Definition of datadriven tests
A simple testsuite for Molybdenum holds the details about navigation through the web application as well as the input data and the expected results.
For datadriven tests, we will separate the input data and the expected results from the navigation description.
 |
Molybdenum does not support navigation flow changes dependent on externalized data.
This could be realized with conditional statements like if/then/else or switch which are not supported by Molybdenum. |
Benefits
- Separating data from navigation makes it easy to change the data, if a test setup has changed.
- Putting the test navigation into a brick makes it easy to run the same test with different datasets.
- Since datasets are simple XML files, test data can be generated with other tools based on mock data used with the application under test or out of arbitrary sources.
- Using converters in datasets, Molybdenum is able to generate random test data.
Examples
General information
General information how to use datasets can be found in the user reference.
Simple separation of data
Assuming, we have a test which is testing a simple calculator application. In two text fields we have to put the summands. These text fields have the ids summandA and summandB. After clicking calculate we will get the result in an element with id result.
A Molybdenum test to calculate 30 + 12 = 42 would look like this:
Now, we want to separate out the data from the testsuite. This is done by writing a dataset in XML format and replacing the data in the test with variable references. Of course, we have to load our dataset before we can reference variables from it.
<dataset>
<data>
<senseOfLife>
<summandA>30</summandA>
<summandB>12</summandB>
<result>42</result>
</senseOfLife>
</data>
</dataset>
Assuming the data.xml file stays right beside the test suite file, the test suite referencing this data will look like this:
Now we can change the test data without any knowledge about the navigation flow of the web application simply by changing the data.xml file.
Test scenarios using scopes
We will do this by adding additional scopes to the dataset.
<dataset>
<data>
<senseOfLife>
<summandA>30</summandA>
<summandB>12</summandB>
<result>42</result>
</senseOfLife>
<luck>
<summandA>3</summandA>
<summandB>4</summandB>
<result>7</result>
</luck>
<kindergarden>
<summandA>1</summandA>
<summandB>1</summandB>
<result>2</result>
</kindergarden>
</data>
</dataset>
We can activate the new scenarios luck and kindergarden by applying the scope name to the loadData command like this:
or this:
All scenarios in one testsuite
If we want to execute all three scenarios one after the other in a test suite, we could copy our commands above into two additional tests, each with the right scope applied.
But copying commands is bad practice. If your web application will change, you have to adapt all three tests. To avoid this, we will use bricks.
Simply select the 6 commands above in the testsuite view and press Ctrl+Shift+M. A dialog will popup an ask you for a name of the brick to be constructed. Lets name our brick calculation. More about bricks....
After doing so, our test looks like this:
Our brickrepository will hold a brick named calculation with our commands:
Lets parameterize the brick so we can pass in the scenario as parameter:
Now we can pass the scenario as parameter to the brick call. Lets adapt our testsuite and let us add two more tests for the additional scenarios:
Controlling the scenario via commandline
Using the autostart argument (Parameterization), it is possible to control the scenario used in the test via commandline.
Simply replace the scope argument with the variable ${autostartArgument}:
Now you can pass the scenario while starting the test on commandline:
Datasets and loops
It is possible to run a testsuite in a loop by picking up a new dataset per loop.
 |
There is a limitation in the loop handling currently - the result of each loop is not written to the report. The report will show the result of the last loop run only. |
How to handle loops in general is described in another tutorial.
To map data to a certain loop we have to name our data sections with a name distinguished by the loop number they should apply to:
As loop count is starting with 0, this could look like this by choosing data as the base name:
<dataset>
<data>
<data0>
<summandA>30</summandA>
<summandB>12</summandB>
<result>42</result>
</data0>
<data1>
<summandA>3</summandA>
<summandB>4</summandB>
<result>7</result>
</data1>
<data2>
<summandA>1</summandA>
<summandB>1</summandB>
<result>2</result>
</data2>
</data>
</dataset>
Now we change our testsuite from above to utilize the molybdenum_loop variable:
Last we have to set the number of loops to 3 in the Script Properties dialog and run the test.
Using converters
Converters in general described in Datasets.
We want to make a concrete example by using converters to generate names with a random number appended. Such random names can be used to test a registration flow for instance.
Our dataset will hold one scope named registration only. One converter will be used named randomize.js.
<dataset>
<converters>
<converter>randomize.js</converter>
</converters>
<data>
<registration>
<firstname>John</firstname>
<lastname>Do</lastname>
</registration>
</data>
</dataset>
The interseting part,of course, is the converter code:
/*
* Generate a token consisting of 5 lowercase characters
*/
function randomChars() {
var token = "";
for(var c = 0; c < 5; c++) {
token += String.fromCharCode(97 + Math.random() * 26);
}
return token;
}
firstname = firstname + randomChars();
lastname = lastname + randomChars();
password = randomChars() + randomChars();
The function randomChars() will generate random lowercase characters, 5 in a loop. This characters are appended to the variable token which is returned at the end.
The scope of a converter holds all variables of the current datascope. In our example, these are firstname and lastname. These variables can be changed and we can add new variables of type String. Newly added variables can be used in the testsuite as other variables by ${...}. In our case, the variable password is created by the converter.
Converters are running each time the dataset is loaded via the command loadData.
If Molybdenum is installed for your browser, you can
load the tutorial.