If you are just getting started with Iridium, please read the article An Introduction to Iridium, an Open Source Selenium and Cucumber Testing Tool.
One issue we ran into writing complex Cucumber test scripts was that quite often functionality needed to be shared between scripts. As end-to-end journeys were captured in scripts, we needed some way to move common scenarios into a single location. For example, the journey for updating a user’s details and buying a new product both start with the user logging into the application. It just didn’t make sense to have those common steps copied and pasted between test scripts.
One thing you will find about Gherkin, the language that is used by Cucumber, is that it is not a programming language in the traditional sense. And nor should it be: the elegance of Gherkin is that you write test scripts in plain English. In our case though the redundancy introduced by copying and pasting the same scenarios between scripts outweighed the benefit of self contained, top to bottom scripts.
To work around this limitation, Iridium supports the notion of importing fragments of a feature script into the main script. This means that common scenarios can be shared between test scripts without the maintenance headaches of copy and paste code.
Let’s see what this looks like in practice. For this example we’ll look at sharing some scenarios that implement security scanning via the Zed Attack Proxy.
To run this example, right click, download and run this Web Start file.
The test script launched by this web start file begins with the following code:
Feature: Open an application Scenario: Generate Page Object Given the alias mappings | Title | /html/body/center/table/tbody/tr/td/h1 | | LoginLink | [href='login.jsp'] | | RegisterLink | [href='register.jsp'] | | AboutLink | [href='about.jsp'] | | BasketLink | [href='basket.jsp'] | | SearchLink | [href='search.jsp'] | | SearchInput | [name='q'] | | SearchButton | [value='Search'] | | DoodahsLink | [href='product.jsp?typeid=6'] | | GizmosLink | [href='product.jsp?prodid=26'] | | GizmosIncrement | [onclick='incQuantity(26);'] | | ContactLink | [href='contact.jsp'] | #IMPORT: startzap.fragment Scenario: Launch App And I set the default wait time between steps to "2" And I open the application
The important line here is the comment #IMPORT: startzap.fragment. This line instructs Iridium to replace the comment with the contents of the file startzap.fragment.
The startzap.fragment file looks like this:
Scenario: Initialise ZAP Given a scanner with all policies enabled
Admittedly, this is a pretty simple scenario, and wouldn’t be that hard to copy into each test script that required ZAP integration. The real value of moving scenarios like this into an imported fragment comes when you need to update the scenario, and have those updates shared across all your test scripts.
Imagine you had 10 test scripts importing this fragment, and one day you are asked to reconfigure the policies used by ZAP. This change is as simple as updating one fragment file, and all your scripts will import the changes with no additional effort.
Just as we initialized ZAP with an imported fragment, we also configure the final scanning and reporting via a fragment.
Scenario: Send Feedback And I click the element with the css selector alias of "ContactLink" And I wait "30" seconds for the element with the xpath alias of "Title" to be displayed And I populate the element with the ID of "comments" with "Some Feedback" And I click the element with the ID of "submit" And I wait "30" seconds for the element with the xpath alias of "Title" to be displayed #IMPORT: finishzap.fragment
The file finishzap.fragment contains the following scenario:
Scenario: Save the results And the application is spidered timing out after "15" seconds And the attack strength is set to "HIGH" And the active scanner is run And the ZAP XML report is written to the file "zapreport.xml" # Ignore X-Frame-Options Header Error And the following false positives are ignored | url | parameter | cweId | wascId | | https://bodgeit.herokuapp.com.* | | 16 | 15 | Then no "Low" or higher risk vulnerabilities should be present for the base url "^https://bodgeit.herokuapp.com"
This scenario is a little more involved, and includes a lot of customization that it is easy to image would be updated frequently. Changing the attack strength, ignoring new violations and changing the reporting levels can now be done in a single file and the changes are automatically applied to all test scripts that import the fragment.
Moving cross cutting concerns like security scanning into fragment files improves the maintainability of the test scripts by removing the need to copy, paste and then maintain common scenarios between test scripts. However, if you find yourself writing a lot of complex shared scenarios, you may want to move them into Java. You can find more information on this process in Extending Iridium With Custom Step Definitions.
You can find the code for this example on GitHub.