Web Testing
Imagine you have just built a workflow app containing multiple user dialogs. Do you really want to always click through the full process, even if you only changed a small part of it? However, you should make sure that the functionality (happy path) of this process is still valid.
Web Integration Tests will always follow the same steps and can be automated.
Setup a Test Project
To get started you have to create a test project. The ‘Axon Ivy Test Project’ wizard will help you to create a test project with all required configurations plus a simple sample test.
Add a new Axon Ivy Test Project
Right click on a project you would like to write tests for.
Select: New -> Axon Ivy Test Project in the context menu.
Pick the test flavor
IvyWebTest
to include in the ‘New Axon Ivy Test Project’ wizard.Finish the wizard.
A sample test will be generated into the
src_test
directory of the newly created project.
Run test
Make sure the Axon Ivy Engine is started with your projects
To run this test right-click inside this class -> Run As -> JUnit Test
A new JUnit View should be opened and the test should be green.
Write a Web Test
Let’s start by extending our test class generated before with a
real test implementation.
First, we need to start a process. To do this you can use the
EngineUrl
utility from the Web-Tester.
This process opens a dialog with two input fields (firstname
and
lastname
) and a submit
button. After submitting, a second dialog with your
input values is displayed.
@Test
public void registerNewCustomer() {
// valid links can be copied from the start page of the internal web-browser
open(EngineUrl.createProcessUrl("myWorkflow/154616078A1D629D/start.ivp"));
// fill new customer form
$(By.id("form:firstname")).sendKeys("Unit");
$(By.id("form:lastname")).sendKeys("Test");
// verify that the submit button is enabled, before clicking it.
$(By.id("form:submit")).shouldBe(enabled).click();
// verify that the registration was successful.
$(By.id("form:newCustomer")).shouldBe(visible, text("Unit Test"));
}
Tip
The @IvyWebTest annotation can be configured (e.g to
select a browser
or to start the test headless
).
Select, Do and Check
Now let’s take a look at how this test works. Basically, there are three things you need to know:
Select an element
Do an action on the selected element
Check a condition on the selected element
Select
To work with a single element you need to first select the correct one.
Usually you use the By.id
selector to do this:
$(By.id("form:submit")); //Find element by id selector
Tip
To evaluate the real id of an element you can use your browser’s Developer Tools.
There are many more options to use selectors, e.g you can select multiple elements:
$$(By.cssClass("ui-outputlabel")); //Find all <p:outputLabel> elements
Have a look at the demo project to see more options.
Execute an Action
On the selected element you can perform some actions:
$(By.id("form:submit")).click(); //click on button
$(By.id("form:lastname")).clear(); //clear input field
$(By.id("form:lastname")).sendKeys("Test"); //set input value
Check a Condition
On your selected element you can check certain conditions (e.g is the element visible or contains a specific value):
$(By.id("form:lastname")).shouldHave(value("Test")); //input field should have value "Test"
Tip
You can check multiple conditions on an item or check a condition before performing an action on the item by chaining the method calls:
//button should be enabled before click on it
$(By.id("form:submit")).shouldBe(enabled).click();
//<h:outputText> element should be visible and have text "Unit Test"
$(By.id("form:newCustomer")).shouldBe(visible, text("Unit Test"));
Have a look at the demo project to see more options.
Change Application Runtime
For some test cases, you may need to run your web tests with a different user or you need another value for a variable or app configuration. In this case the WebAppFixture util can help you to achieve this. Unlike the AppFixture of Unit Tests, the changed values are not automatically reset after the test run. Let’s have a look at it:
You can change the current user or log out to an anonymous session:
@Test
void user(WebAppFixture fixture) {
/* The WebAppFixture can login to another user. */
fixture.login("test", "test");
open(EngineUrl.createProcessUrl("a-process-url/start.ivp"));
/* Or it can logout the user to an anonymous session. */
fixture.logout();
open(EngineUrl.createProcessUrl("a-process-url/start.ivp"));
}
If you want to change the value of a variable, you can proceed as follows:
@Test
void variable(WebAppFixture fixture) {
/* The WebAppFixture can change the value of a variable. */
fixture.var("myVar", "hello");
open(EngineUrl.createProcessUrl("a-process-url/start.ivp"));
$(By.id("form:variable")).shouldBe(exactText("hello"));
/* Or reset it to the default value. */
fixture.resetVar("myVar");
Selenide.refresh();
$(By.id("form:variable")).shouldBe(exactText("init"));
}
Or you can change an app configuration, e.g the URL of a RestClient:
@Test
void config(WebAppFixture fixture) {
/* The WebAppFixture can change the value of an app configuration. */
fixture.config("RestClients.myClient.Url", "${ivy.app.baseurl}/api/myCoolMockService");
open(EngineUrl.createProcessUrl("a-process-url/18AF06DD4E1A49B8/start.ivp"));
$(By.id("rest:result")).shouldBe(exactText("hello from mock service"));
/* Or reset it to the default value. */
fixture.resetConfig("RestClients.myClient.Url");
Selenide.refresh();
$(By.id("rest:result")).shouldBe(exactText("hello from real service"));
}
Run Automated
Let’s have a look at how you can run your web tests fully automated (Continuous Integration). This is especially important if you want fast feedback on breaking changes done by a team member.
Module Build
Both projects, production and test project, need to be compiled during the same run. To do this, we need to first setup a Maven module build:
Create Maven module
Delete projects
crm
andcrmIntegrationTests
from your Axon Ivy Designer workspace.Open your workspace folder and move both projects into an new folder, e.g
compile-test
Create a
pom.xml
file in thecompile-test
folder.Add the following code to the pom.xml file (ensure the correct modules
crm
andcrmIntegrationTests
are set):<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>ch.ivyteam.ivy.project.demos.ci</groupId> <artifactId>crm.modules</artifactId> <version>9.1.0-SNAPSHOT</version> <packaging>pom</packaging> <modules> <module>crm</module> <module>crmIntegrationTests</module> </modules> </project>
Your folder structure should now look as follows:
workspace/ compile-test/ crm/ crmIntegrationTests/ pom.xml
Run module build in Axon Ivy Designer
In your Axon Ivy Designer open the Import Wizard, then Existing Maven Projects
Select
compile-test/pom.xml
with sub projects (crm
andcrmIntegrationTests
should be visible here) and click FinishRight-click on
compile-test
-> Run As -> Maven buildSet Goals to
clean verify
and click RunThis triggers a run that starts and ends with something similar to:
[INFO] Scanning for projects... [INFO] ------------------------------------------------------------------------ [INFO] Reactor Build Order: [INFO] [INFO] crm [iar] [INFO] crm.integration.tests [iar-integration-test] [INFO] crm.modules [pom] ... [INFO] Reactor Summary for crm.modules 9.1.0-SNAPSHOT: [INFO] [INFO] crm ................................................ SUCCESS [ 5.872 s] [INFO] crm.integration.tests .............................. SUCCESS [ 29.015 s] [INFO] crm.modules ........................................ SUCCESS [ 0.024 s] [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 36.287 s [INFO] Finished at: 2020-07-16T08:56:53+02:00 [INFO] ------------------------------------------------------------------------
Congratulations, you can now run your tests fully automated with Maven!
Further Resources
If you want to know more about web testing, have a look at the second test in our demo project or at our other demo projects and how they are tested.
If you want to learn more about how to build a CI/CD pipeline, take a look at the CI/CD videos in our Tutorial section.
Selenium
Selenium is an open source web testing framework. It works across different browsers and platforms. To communicate with the browser, Selenium provides the WebDriver specification.
In our tests we use the Selenide (GitHub, API) framework, which is based on the Selenium WebDriver. If you’re more familiar with plain Selenium tests the following comparison can give you a quick overview about the differences and benefits: Selenide vs Selenium. Or you can simply write your tests with the normal Selenium API by accessing the driver object:
WebDriver driver = WebDriverRunner.getWebDriver();
Web-Tester
With the web-tester project we provide the testing
annotation @IvyWebTest
. This annotation sets up the browser connection for
you. It can be configured with some parameters:
//Default (same as simple @IvyWebTest)
@IvyWebTest(browser = "firefox", headless = true, reportFolder = "target/selenide/reports")
browser: The browser which should run the test e.g: chrome, firefox, ie, phantomjs, htmlunit, safari, opera
headless: Controls if the browser should start with a UI or not.
reportFolder: when a test fails the test framework automatically takes screenshots. This folder defines where these screenshots are saved to.