ERP 2.50:Automated Testing/Implementation
Please refer to the design section for the rationale of this implementation.
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.
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 Openbravo.properties file.
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.
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.