Mostrando entradas con la etiqueta acceptance test. Mostrar todas las entradas
Mostrando entradas con la etiqueta acceptance test. Mostrar todas las entradas

sábado, diciembre 14, 2013

Asciidoctor Meets JBehave.


User story is one or more sentences in natural language or business language which captures the requirements of what end user wants to be implemented in the product we are developing.

User Stories typically have the form:

"In order to <receive benefit> as a <role>, I want <goal/desire>"

User stories are also documentation for our project, first of all because they express what the product should do, and second one because they will be used by our clients/stakeholders, to validate that we are building the right thing.

JBehave is a framework for Behaviour-Driven Development (BDD). BDD is an evolution of test-driven development (TDD) and acceptance-test driven design, and is intended to make these practices more accessible and intuitive to newcomers and experts alike. The core of JBehave from the point of view of end users are user story files, where we define stories that our product should meet to validate that we are aligned with what our client wants. A user story example in JBehave is:


Note that first sentence is a description, then a narrative section which contains sentences of the form in order to, as a, I want. And finally the definition of scenarios that must meet this story to be considered completed.

So as you can see, story files are project documentation, and as project documentation would be awesome if we could add them inside our documents as documentation and not as simple plain text. And here is where Asciidoctor comes to action. Asciidoctor is a Ruby, Java and Javascript processor for converting AsciiDoc source files and strings into HTML 5, DocBook 4.5 and other formats. Your project may contain different kind of documents written in AsciiDoc like Software Design Specifications (SDS), manuals, or for example a test plan. And it is in test plan where including user stories, could be a really good improvement. And for this reason jbehave-asciidoctorj-extension has been developed.

Let's see an example. Suppose that we are writing a document where we want to test some user stories manually (apart of automatically of course) due to the criticality of the process:


As you can see we have created a simple AsciiDoc document with some information. But the interesting part is include::jbehave::userStories:src/**/*.story[initialLevel=1, manual=true]. Note that we are including all jbehave userstories that are placed on src folder. This extension supports any valid glob expression. And at the end we can set two attributes, the first one is the initial level of the section where user stories will be rendered (remember that the first one is 0), and finally if the steps will be executed manually or not, which has a deep impact on final rendered document as we will see soon.

Our project has two story files:


As you can see the second story has a dependency to the first story, which means that this second story is only valid if first story has passed successfully. Apart from this fact, we can set examples as tables as well.

So let's see an screenshot of previous document rendered:


I think it is important to note two blocks. The first one is the NOTE block. See that GivenStories are rendered as Admonition, and with a link pointing to another story; this is pretty important because clicking there it will move the page where that (precondition) story was defined, so you can also inspect what was that story about. The other interesting part is the Result part. Because we have set user stories as manual, the extension will render three checkboxes so tester can mark if the scenario passes, fails or also if he wants to add some comment.

So now there is no excuse to not adding user stories in your documents in a really fashion way.


We keep learning,
Alex.
Maman dit Annotate"travailler c'est bien", Bien mieux qu'être mal accompagné, Pas vrai ? (Papaoutai - Stromae)




miércoles, marzo 06, 2013

NoSQLUnit 0.7.5 Released



NoSQLUnit is a JUnit extension to make writing unit and integration tests of systems that use NoSQL backend easier. Visit official page for more information.

In 0.7.5 release, next changes has been added:
We keep learning,
Alex.
Cuando la pena cae sobre mi, el mundo deja de existir, miro hacia atrás, y busco entre mis recuerdos (Entre Mis Recuerdos - Luz Casal)

Music: http://www.youtube.com/watch?v=zUnOWCURe2M

martes, diciembre 04, 2012

Writing Acceptance Tests for Openshift + MongoDb Applications



Acceptance testing are used to determine if the requirements of a specification are met. It should be run in an environment as similar as possible of the production one. So if your application is deployed into Openshift you will require a parallel account to the one used in production for running the tests. In this post we are going to write an acceptance test for an application deployed into Openshift which uses MongoDb as database backend.

The application deployed is a very very simple library which returns all the books available for lending. This application uses MongoDb for storing all information related to books.

So let's start describing the goal, feature, user story and acceptance criteria for previous application.

Goal: Expanding lecture to most people.
Feature: Display available books.
User Story: Browse Catalog -> In order to find books I would like to borrow, As a User, I want to be able to browse through all books.
Acceptance Criteria: Should see all available books.

Scenario:
Given I want to borrow a book
When I am at catalog page
Then I should see available books information: The Lord Of The Jars - 1299 - LOTRCoverUrl , The Hobbit - 293 - HobbitCoverUrl

Notice that this is a very simple application, so the acceptance criteria is simple too.

For this example, we need two test frameworks, the first one for writing and running acceptance tests, and the other one for managing the NoSQL backend. In this post we are going to use Thucydides for ATDD and NoSQLUnit for dealing with MongoDb.

The application is already deployed in Openshift, and you can take a look at https://books-lordofthejars.rhcloud.com/GetAllBooks



Thucydides is a tool designed to make writing automated acceptance and regression tests easier. 

Thucydides uses WebDriver API to access HTML page elements. But also helps you to organise your tests and user stories by using a concrete programming model, create reports of executed tests, and finally it also measures functional cover. 

To write acceptance tests with Thucydides next steps should be followed. 
  • First of all choose a user story of one of your features. 
  • Then implement the PageObject class. PageObject is a pattern which models web application's user interface elements as objects, so tests can interact with them programmatically.  Note that in this case we are coding "how" we are accessing to html page.
  • Next step is implementing steps library. This class will contain all steps that are required to execute an action. For example creating a new book requires to open addnewbook page, insert new data, and click to submit button. In this case we are coding "what" we need to implement the acceptance criteria.
  • And finally coding the chosen user story following defined Acceptance Criteria and using previous step classes.








NoSQLUnit is a JUnit extension that aims us to manage lifecycle of required NoSQL engine, help us to maintain database into known state and standarize the way we write tests for NoSQL applications. NoSQLUnit is composed by two groups of JUnit rules,  and two annotations. In current case, we don't need to manage lifecycle of NoSQL engine, because it is managed by external entity (Openshift).

So let's getting down on work:

First thing we are going to do is create a feature class which contains no test code; it is used as a way of representing the structure of requirements.

Note that each implemented feature should be contained within a class annotated with @Feature annotation. Every method of featured class represents a user story.

Next step is creating the PageObject class. Remember that PageObject pattern models web application's user interface as object. So let's see the html file to inspect what elements must be mapped.

The most important thing here is that table tag has an id named listBooks which will be used in PageObject class to get a reference to its parameters and data. Let's write the page object:

Using @DefaultUrl we are setting which URL is being mapped, with @FindBy we map the web element with id listBooks, and finally getBooksTable() method which returns the content of generated html table.

The next thing to do is implementing the steps class; in this simple case we only need two steps, the first one that opens the GetAllBooks page, and the other one which asserts that table contains the expected elements.

And finally class for validating the acceptance criteria:

There are some things that should be considered in previous class:
  • @Story should receive a class defined with @Feature annotation, so Thucydides can create correctly the report.
  • We use MongoDbRule to establish a connection to remote MongoDb instance. Note that we can use localhost address because of port forwarding Openshift capability so although localhost is used, we are really managing remote MongoDb instance.
  • Using @Steps Thucydides will create an instance of previous step library.
  • And finally @UsingDataSet annotation to populate data into MongoDb database before running the test.


Note that NoSQLUnit maintains the database into known state by cleaning database before each test execution and populating it with known data defined into a json file.

Also keep in mind that this example is very simple so only and small subset of capabilities of Thucydides and NoSQLUnit has been shown. Keep watching both sites: http://thucydides.info and https://github.com/lordofthejars/nosql-unit

We keep learning,
Alex.
Love Is A Burning Thing, And It Makes A Fiery Ring, Bound By Wild Desire, I Fell Into A Ring Of Fire (Ring of Fire - Johnny Cash)

martes, septiembre 06, 2011

Soy El Capitán De La Nave Tengo El Control, Llamando A La Tierra Esperando Contestación, Soy Un Cowboy Del Espacio Azul Eléctrico (Llamando A La Tierra - M.Clan)



Groovy is an object-oriented programming language for the Java platform and can be used as a scripting language. Most of us but instead of using Groovy alone, we use Grails (web framework based on Groovy) for developing web applications.

But Groovy can be used standalone for developing your internal tools. Let me explain why Groovy scripts have simplified our development of tools for generating data for integration tests.

In my company we create clinical instruments. These instruments are so expensive, and big enough to say that they are not portable. For these reasons each instrument has an emulator, so integration tests are run without having physically any instrument.

Our emulator has an XML file where all required resources for running tests are configured. In summary each file contains a list of blood barcodes, and reagent barcodes. In our case barcodes have a meaning (kind of resource, expiry date, checksum, ...).

So one can think about creating a standard configuration file that is used in integration tests. It is a good idea if you don't know that expiry date is expressed in months. So one day without knowing exactly why your tests begin to fail. The answer is obvious, resources have become expired. We need a (script ?) that updates this XML file so when a resource is becoming expired, its month field is changed.

Moreover not all resources should be updated. Some tests imply working with expired resources. For this reason some barcodes have special format that suggests that update should not be applied.

Because project is developed in Java, one can think about creating a small Java class that do all these work. But wait and think if this class would be small or not, we need a parser (DocumentBuilder), a method that walks all nodes and see if resource is expired or not (NodeList, Element.getAttribute(), ...), and finally writing modifications to file. Furthermore, some barcodes contains special charachtrs that should be detected using a regular expression (Pattern, Matcher) for avoiding its update. Although this class is not difficult, it is far away from a small class with few lines.

But how about polyglot programming? Groovy can be a choice. Let's see how Groovy deals with XML and Regular Expressions.

Imagine next XML file:


Groovy and XML

Meanwhile in Java you create a DocumentBuilderFactory that returns a DocumentBuilder, and then call parse method, in Groovy is as simple as:

and root variable points to root element of XML file.

And now imagine that you want to update all blood barcodes of given holder. With Java you will use an iterator over NodeList or using an XPath expression. See the simplicity with Groovy.


See that with Groovy, nodes are explored as object attributes, and finally we call findAll() method that returns a list of sample nodes belonging to SampleHolder11 tag. For returning an attribute value is as easy as adding @ character before attribute name, in our case barcode.

And for writing an XML is as easy as:


In previous example, output is written to console.

Groovy and Regular Expressions

Remember that some barcodes have special format. In our case if any barcode starts with A, B, C or D, should not be modified. A clean, reusable and maintainable solution is using regular expressions to check if one barcode matches or not special format. In Java the process is not banal, you have to create a Pattern object with a regular expression, a Matcher and use find() method to see if pattern is found on entry or not.

But how we can determine if one string matches a regular expression in Groovy ? ==~ operator does the work for us. Tell me what you think about this expression:


Elementary. You will agree with me that Groovy approach is simpler than Java one.  For specifying a pattern you only have to use ~ character plus a slash (/) then a regular expression and finally a slash to delimit. But Groovy also supports =~ (create a Matcher) and ==~ (return boolean, whether String matches the pattern).

I think that creating a script that reads/parses/writes XML file is so fast and easy, not much classes are involved compared to Java. And not worth making the comparison with regular expression approach, in Groovy is the simplest way one may think.



After the success of previous Groovy script, we decided to create another tool (Groovy script) for manipulating database.

System registers into database every incidence that has occurred to an execution. Some incidences are easy to reproduce with emulator, but others not. In integration tests there is no problem, because a defined-filled database is used, but acceptance tests contains no data and is generated with the execution of tests. But because there are some incidences that are hard to reproduce in emulator, a Groovy script to insert incidences are created.

Groovy and SQL

As Java, Groovy can also access to databases and as you can suppose in a simple way. No Connection object, no PreparedStatement, no ResultSet, ....

Let's see an example of searching data and using them for creating a new registry. Imagine that we have a table called Execution and another one called Incidence, and one-to-many relationship.


Simple, yes? With one line a connection to database is established.

Executing SELECT query and iterate over results are also easy. Using eachRow method, all results are iterated. No ResultSet object is required anymore. Parameters values are passed between brackets ([]), and as XML each row is accessed using Closure. In previous example each row is mapped to execution variable. Moreover see how easy is read a value of each tuple. As in XML you access the value as a class attribute, no more getters of ResultSet methods, in example execution.dboid is used to refer to dboid field.

Finally execute method is used to update database.



Now that I have shown you some of nice features that Groovy offers us, I will explain you how we execute these tools.

GMaven

We use Jenkins with Maven as Continuos Integration System. Before Jenkins starts to execute Integration Tests, Groovy scripts are executed so emulator is configured propertly. The iteresting part of this step is how pom is configured for executing Groovy scripts.

Exists a plugin called gmaven-plugin. This plugin runs Groovy scripts depending on phase and goal.


No problem configuring gmaven plugin, the most important part is where you specify which script should be executed.

As final notes I want to say that I am a huge fan of Java and my intention is not criticize it, but I think that there are some problems that are best suited using other languages rather than Java. My advice is  learning as many kind of languages as you can (Scala, Groovy, ...) so as programmer you can choose the best solution to a given problem.

I wish you find this post useful.

Music: http://www.youtube.com/watch?v=9u54Xs22_SI

miércoles, abril 20, 2011

Are You Locked Up In A World That's Been Planned Out For You? Are You Feeling Like A Social Tool Without A Use? (She - Green Day)



From JBehave site: JBehave is a framework for Behaviour-Driven Development (BDD). JBehave allows developers, QA and non-technical or business participants, to write stories in a plain text file with minimal restrictions about grammar. Then a POJO is created for executing created story. This POJO should have the typical BDD structure Given, When and Then.

From Springsource site: Spring Framework is a Java platform that provides comprehensive infrastructure support for developing Java applications. Spring handles the infrastructure so you can focus on your application.

From Selenium site: Selenium is a suite of tools to automate web app testing across many platforms.


We have three technologies JBehave for acceptance tests, Selenium for web application testing and Spring dealing with infrastructure. In this post I will talk about integrating JBehave with Selenium 2 and Spring.

For this example I have created a very simple web application using Spring MVC. I know that business logic is not accurate to the reality, but it is simple enough to illustrate how to integrate all these technologies together.


I have divided this post in three main subsections:

  • Integrating JBehave with Spring. There is no web application here, only business logic.
  • Integrating Spring MVC with Selenium 2. Only to show how easy is implementing automated tests with Selenium 2.
  • Integrating JBehave with Selenium 2. Web application used in previous example but instead of using only Selenium for automating testing, JBehave instructs to Selenium which steps should execute.
Application that I will use is a simple TraderService, (explained in JBehave page (http://jbehave.org/reference/stable/)). This TraderService generates Stocks, and if a Stock is traded below threshold, its alert status is OFF and if it is traded above, alert status is ON.

In this tutorial I assume that you have a basic idea of JBehave and Spring.


  • Integrating JBehave with Spring:

In this case no web GUI is used, we are going to use JBehave for writing acceptance tests of business logic.

Basic classes are:
  • TradingService, that defines a method for creating stocks. TradingServiceImpl is the implementation.
  • Stock, that contains stock information and logic about its status.
  • StockAlertStatus is Stock status Enum.

Acceptance test part:

First of all we should create a story. A story is where stakeholders, developers... should say what they want the application do, and which are the expected results for given parameters. In our case a story has been created for validating that alarm is OFF if trade value is under threshold, and ON otherwise.


The important parts of that file are: Scenario for describing what we are testing, all symbols between <> that are used as variables, and Examples that are values injected to previous "<>" variables. In this story file two examples are provided, so two executions will be produced, one for each row. As final note, Given, When, Then words should be placed at start and are reserved words, also more than one Given, When or Then could be used in each story.

Next step, create a class that transforms a story written in "natural language" to code. We could say that this class is equivalent of creating a junit class; In JBehave these classes are called Steps. Because we are integrating with Spring an annotation called Steps is created. This annotation extends from Component annotation so Spring component-scan can wire up step classes too.


And Steps annotation is used in TradingServiceSteps class.


In TradingServiceSteps is where all magic occurs. This class is responsible of transforming story file to an execution. Let's see:

@Steps because we want Spring creates automatically this bean. TradingService is the business logic we want to test, and is injected using Autowire annotation. And finally one method for each Given, When, Then. Explained quickly, when JBehave finds an @Given, it searches into loaded stories for a phrase starting with Given. After that checks if @Given string value matches the Given definition expressed in story file. If matches then inject the story parameters as method parameters, for example STK1 as string parameter, or 5 as double threshold parameter. Moreover, in this case because we are using Examples in our story file, @Named annotation for each parameter is required. The named parameters allow the parameters to be injected using the table row values with the corresponding header name. Each parameter is converted from String to required parameter type.

We have written stories, and how to execute them (TradingServiceSteps class). JBehave requires another class, that will be responsible of configurating it. Basically you should configure Step classes and story files location, and what kind of reports are generated.

In our case, because we are integrating JBehave with Spring, some information is provided using Spring Injection.


This class is where JBehave is configured and is responsible for running all stories. Let's examine the most important lines:

In line 1 we specify a JUnit runner for running JBehave stories with Spring.
In line 2 we are configuring JBehave with Enum parameter converter, see that StockAlertStatus is an enum, because it is not a primitive parameter, a converter should be provided. JBehave comes with some convertes, but we can implement ours too.
In line 3 the embedder that we will use. This is the standard embedder for JBehave. Embedder represents an entry point to all of JBehave's functionality that is embeddable into other launchers.
And finally with @UsingSpring we are providing two Spring files, one where step classes are defined, and the other one where JBehave is configured.

Configuration file is a standard Spring file injecting required JBehave parameters:


This is a generic configuration file, that I use in all projects. You configure the output, the classloader for Embedder and prefix for parameters

And finally a Spring context file where all step classes are defined. And you know what, thanks of Spring this is as simple as:



No magic, remember that each Step class has an @Steps annotation? Thanks of component-scan, you don't have to define each Step class in @UsingSteps annotation or using tags.

Now run previous class as JUnit, and reports with results are generated.


  • Integrating Spring MVC with Selenium 2

Selenium 2 is a suite of tools to automate web app testing across many platforms. In this case WebDriver approach has been used. WebDriver is an interface for automating tests in a programmatic way. Selenium provides several implementations depending on browser where tests are run.

For this example I have created an Spring MVC application, that are composed of two pages, one form where all stock information is provided and a page where status of inserted stock is showed. Of course Spring MVC controller for managing all information is also implemented.

Controller of this small application is:


showForm method is used for showing the form where user will write stock information. submitForm method is called when submit button is pushed, and creates an stock and send to showstatus page the status of stock.

StockForm is simply a class with three attributes (stock, threshold and tradeAt price). No secret here.

Form page is also so simply but I will show it because form information will be used for configuring Selenium:



Page for showing status:


WebDriver is used in JUnit test for automatizing a sequence of events. In this case, the sequence will create an stock below threshold and assert that response page shows that alert status is OFF.



Most important sections of previous JSP are:

JSP taglibs <form:input path=""/> like <form:input path="name"/> in form, and <div id="result">. These fields are important because they are used by Selenium for filling form and asserting showed status.

For example, in Selenium class:

WebElement name = driver.findElement(id("name")) returns a "reference" to <input id="name" type="text"> element and using sendKeys method, you are sending keyboard chars to that component.

WebElement element = driver.findElement(id("result")), returns a "reference" to div element and using
assertThat(element.getText(), is(StockAlertStatus.OFF.name())); getText method, none tag characters of element are returned.

Now running this test is as simple as running TraderIsAlertedSelenium class as a simple JUnit test class. When running this class a browser (Firefox in this case) will be opened, and all programmed interactions will be executed on your screen.

At this point we just have to join both previous parts, and integration between JBehave with Spring and Selenium will be reality.


  • Integrating JBehave with Selenium 2 and Spring

JBehave has a module called JBehave-Web, that is used for integrating JBehave with web pages. Base classes are WebDriverProvider and WebDriverPage. Both classes are used by JBehave for abstracting from browser, and also for providing common methods to test webpages. In this example I won't use jbehave-web for two reasons, first because Selenium 2 with WebDriver offers a level of abstraction that is enough for this example, and secondly because WebDriverPage is a class that implements some common funcionalities for testing, but it is abstract, I don't like using extension only for sharing common operations between classes, it is a bad practice (not discussed here), I prefer aggregation. So in this case I have preferred  implementing my class for implementing common functionalities.


In this case abstraction from browser is acquired using WebDriver (Selenium) interface. Moreover all common operations are implemented into this class. The idea of this class is to be used in several projects and for that reason a better design should be desired, but for current example is enough.

Next group of classes are those that use PageUtils object. I have created one class for each page that Selenium should interact with. Acts as a facade to web.

For example class for dealing with page containing form to insert new stock is:


Three operations can be executed in this page, the first one is open the page. Because "insert a new stock" is accessed manually (in this case is the front page), an open method is provided with URL. Also a method for filling stock form and and another for submitting it are provided.

And finally a class that transforms an story written in "natural language" to code (also known as Steps class), this class would be the same used in first example (TradingServiceSteps) but adapted for dealing with web pages (using previous classes).


See that there is no differences between this class and the one created in first example, but using web page interfaces instead of business objects. 

Next modified files are:

Story file:


that has been modified to use web terminology.

Spring file:


that injects into TradingServiceWebSteps required beans.

Configuration file used in first example is the same, and Spring file for configuring JBehave is the same too.

In summary I can definitely say that integrating JBehave with Selenium 2 and Spring is not a difficult task, compared with the benefits that lead us having an automated acceptance test platform. I wish you have found this post useful.

Download Full Code