View source | Discuss this page | Page history | Printable version   

ERP 2.50:Automated Testing/Implementation

Please refer to the design section for the rationale of this implementation.


Screen definitions

We based the screen definitions on the Screen Object pattern, where every page, frame or window on the application has its own object that encapsulates the elements present in the screen and the actions and verifications that can be done with those elements.

Furthermore, we have defined those screen objects as compositions of simpler objects, that are also compositions of some objects even simpler, until we reach the foundation of the framework that's composed of the base objects that form a user interface: buttons, labels, input fields, etc...

The main page in OpenbravoERP 3.0 is always the same for almost any possible flow. It shows a navigation bar and a set of tabbed views that the user can open and close. Every view offers different possibilities for the user, and it also displays a set of internal tabs for related data and actions. As this main page and all the views and tabs are built using the SmartClient graphical user interface library, the screen definions are closely related to SmartClient.

So, for every SmartClient UI element we have defined a corresponding test class that allows us to simulate a user interaction with that element, and to verify that the result of the interaction was the expected.

There is a SmartClient base class called Canvas. We also have a Canvas test class where we defined the actions that are common to all UI elements, like click, check if is visible, get the text of the element, among others. And just as SmartClient does, the rest of UI elements are built using inheritance. Thus, for example we have defined the TextItem test class that extends the Canvas adding a function to its API allowing us to enter a text on the field, or the Checkbox class that exposes a function to check if the element is checked or not, and even complex elements like the Grid, that has a filter and a number of rows, each composed by arbitrary amounts and types of other simpler elements like TextItems, SelectItems, DateItems, etc.

That's the foundation of UI elements. The composition of them, mocking the way it's done on the ERP, gives us test classes for a Generated Tab with functions to switch between grid and form view, to fill a form, to verify the message displayed, and others; and for a Standard View that has a group of Generated Tabs and can navigate between them and perform actions with their data.

Note:For every Window and Tab defined in the model of the application, we will have corresponding StandardView and GeneratedTab test classes.

The actions on all these UI elements are done by Selenium, so, the basic problem to solve is how to identify and locate them in the web page. For this purpose, SmartClient has added to every UI element a locator that can be used with Selenium, and that's like a path from the root of the web page, following the hierarchy of UI elements. Most of the SmartClient elements will expose a function through JavaScript called getLocator(), that can be used precisely to pass the locator to Selenium. So, what we need is only the JavaScript expression that gives us a reference to the SmartClient object, and then we can call the getLocator() function of that element. We have called this expression the object string, and is the parameter expected by the constructors of all test classes for the UI elements.

Some of the UI elements are not easily reachable with a JavaScript expression. And on the contrary, they are easily reachable extending the SmartClient locator of their parent elements. So, we have also added a way to manually specify the locator of the element we are trying to exercise. However, we don't encourage this because due to the highly dynamic nature of the application, the locator paths might easily change and we will be left with a stale path. Always prefer to instantiate the object with the object string.

And, in order to ease the writing of tests, the developers of the ERP have added a Test Registry, that's an array of SmartClient UI objects using an automation-friendly string as the key in the array. This allows us to easily find the object reference and instantiate the corresponding test class. In order to use the Test Registry, the application should have been built with the test environment property set to true in the file.

Test controllers

Test controllers or scripts are just a semantic layer to ease the writing of test cases. There will be a script class for every Window defined in the application model. This script represents both the Window and its top level tab, and has a hierarchy of internal classes for the children tabs.

On this scripts we defined functions to open the window and navigate on its tabs. And they expose to the test case functions that correspond to the actions possible on each tab, like create a new record, filter the grid, check the number of rows, and may others; and also functions that are specific to one or some tabs, like to complete a sales order header, or copy lines from another record.


The parameters are the information that will be fed into the application in every test case. They are data classes that will be passed to the functions defined in the test controllers in order to execute the desired action.

For example, when we create a new sales order we have to specify the business partner that's buying from us. This sales order is a parameter, and we set the business partner field to a desired value that makes sense with the test we are writing. Then, this parameter is passed to the create new function of the sales order test controller, and it will execute all the required UI actions that will result in the creation of a new sales order.

The parameter classes follow the Builder pattern, as a form of semantic sugar to improve the readability and extensibility of tests, and to ease their writing with the help of an IDE.

The parameters are passed to the JUnit test cases using the @Parameter annotation.

Test cases

The test cases are the sequence of actions or steps that compose a test. Following our implementation, they are just calls to test controller functions passing to them data parameters.

Test cases are implemented using JUnit, so every test case class should have a function with the @Test annotation, and on their constructor they have to define all the parameters it expects from the @Parameter annotation.

All test cases should inherit from the OpenbravoERPTest class (com.openbravo.test.integration), that's in charge of reading the execution properties, starting the Selenium server, opening the application on the browser and logging in; and after the test has finished it takes a screenshot in case of failure, logs out and closes the Selenium server.

Retrieved from ""

This page has been accessed 5,491 times. This page was last modified on 3 April 2012, at 11:00. Content is available under Creative Commons Attribution-ShareAlike 2.5 Spain License.