Panther UI Automation Design
The following email was recieved from the lead developer...
From: Sharmila Sudha [Automation Specialist]
Sent: Friday, 12 January 2018 15:43 p.m.
To: Mike Talks [Avionic Manager]; Test Team
Subject: Panther UI Automation Suite
Hi Mike - Happy New Year!
Well, we're getting there. The first working version of the ODM pages were ready before Christmas, and I've been putting together the Selenium framework to allow us to build some tests. I'm going to talk you through some of the design decisions, and maybe you'll want one of the testers to put this into a wiki sometime.
Test properties
Under the base directory you'll find the readme.md which outlines the project and the all important test.properties file.
The test.properties file contains the test parameters used in the test code. The important ones of these are,
- browser, the type of browser to test on
- machine_type, the type of machine you're running this on
- website_under_test, the url for the website you're testing
- max_wait, the maximum amount of time the system will wait before failing a step
- shut_browser_when_done, should normally be true, but if you're exploring a new test, you might want it set to false
Utilities
The utility package can be found under src/main/java/testsheepnz.panther/util. This includes a host of the backbone classes to make the tests work. I will only talk about the classes your testers might have to worry about here.
SeleniumInstance
The most important one is SeleniumInstance, which collects together both the Selenium webdriver and wait, together with the properties defined in test.properties.
It uses the properties to define what kind of browser to launch together with where to find the driver, what size to make the page and how long to definte the default wait.
TestLog
TestLog looks after creating screenshots, and creating documents for each test run. Tests will take screenshots at tactical points as defined by the user. This handles making that happen.
For your testers they probably only need to worry about calling the method addScreenshot within their test.
The output test logs can be found under src/main/resources/screenshots
SetupAssistant
This is a set of methods which will take care of setting up the webpage if they're using later features. It helps make their tests as simple as possible.
Because these are utility methods to set up data for a test, we do not use any assertions here.
Methods available to them include,
- setupStandardAircraftFromEquipmentForm, they just need to provide fuel, and sets up a Panther in a default equipment setting
- setUpAircraftFromEquipmentForm, is a more customisable way to load the aircraft
- selectLoadFromEquipmentForm, waits for the equipment form to be visible, then selects to load
- selectCruiseFromStatusForm, waits for the status form to be visible, then selects cruise
- selectClimbFromStatusForm, waits for the status form to be visible, then selects climb
- selectDiveFromStatusForm, waits for the status form to be visible, then selects dive
- applyCruiseFromCruiseForm, waits for the cruise form to be visible, then enters the details for cruise, then applies
- applyDiveFromDiveForm, waits for the dive form to be visible, then enters the details for dive, then applies
- applyClimbFromClimbForm, waits for the climb form to be visible, then enters the details for climb, then applies
- setHeightFromStatusForm, will set the aircraft to whatever altitude you need it to be
- getErrorMessage, captures any error message and returns it
Page Definitions
The Selenium tests use the Page Factory model (references at the bottom), with pages defined under src/main/java/testsheepnz.panther/page
Pages extend the BasePage class, which contains all the WebDriver, TestProperty and WebDriverWait objects, as well as calls the PageFactory.initElements to initialise the elements for the page.
The pages themselves are technically defined for each active form on the Panther, which we felt made sense - it's a single application acting like several pages!
For each web page such as DivePage, there are the following items,
- definitions - an identifier in the form private static final String for the web element (your testers can check these using the browser developer tools)
- waitForPage method - this is a method which will wait until a certain element for a form is present. We're typically using forms for the ODM page, but it can be anything which once it visible, you know you can proceed. Occasionally we've specified a reverse waitForPageToVanish
- @FindBy declaration - each element needs to have a @FindBy statement. We're currently using @FindBy ID as our definition.
- public activity methods - define all our @FindBy methods as private. For each element we're using we need to decide how the tests will interact and use them, and create public methods to facilitate that. So for the apply button we'll create a method to click the button called clickApplyButton. For a text field we might want to create a method to get the value from the field, as well as another method to be able to set the value of the field - so getDiveAltitude and setDiveAltitude respectively.
Tests
Ah, this is where the magic happens, and where your testers will be most interested in. They're under src/test/testsheepnz.panther.aircraft.test
BaseTest
There is a parent BaseTest class which all tests extend from. BaseTest contains the SeleniumInstance as well as the TestLog
BaseTest runs some @Before / @BeforeClass methods before tests are run which will read the test properties, set up a Selenium Instance (opening a browser) as well as set up the log file.
Correspondingly it will also run some @After / @AfterClass methods to close the file and browser afterwards.
Note that there is a parameter, protected Boolean testPasses which is set to false at the start of a test, and only set to true as the last step in a test. This means if the test aborts because of a problem, the log file will assume it failed. You only get it to pass if the test ran all the way through.
Individiual tests
Each test class extends BaseTest.
They should have a @BeforeClass which will include the name of the class. This helps define the name of the logfile generated for these test.
A typical test looks like this,
- Start by setting the SeleniumInstance to the homepage.
- We use testDecription as a form of comment, which will be sent to takeScreenshot at an appropriate point.
- We then declare an instance of EquipmentPage, and we use methods on there to wait for the page to be displayed (then take a screenshot).
- We assert that when we call the method attemptNumMissile(1) it returns true
Ideally we want to limit ourselves to one or two assertions for each test, and give them a meaningful name.
Reading
I know the Page Factory model is a bit new to some of your testers, you might find some of the following reading helpful,
- Using the page factory
- Page Object Model (POM) & Page Factory
- Building a Selenium framework
- Page object model in Java
- Page Object Model Framework with Java and WebDriver
- Page Object Model- Make It Simple, Use Abstraction
- Creating Page class
Test Automation University
The following free courses on Test Automation University are available and can help you dive more into the concepts used in the automation,
Good luck with this, your testers know where to find me,
Sharmila Sudha
Automation Specialist, Panther Project