Ve Test Pattern

A set of lightweight rules and patterns that can be implemented in most programming languages.
By Dwayne Dowding Posted 16 March 2016

Ve Test Pattern

Ve Test Pattern

I have created the Ve Test Pattern which is a set of lightweight rules and patterns that can be implemented in most programming languages.

An example of it in use in C#: github.com/.../AcceptanceTests

An example of it in use in Java: github.com/.../java-and-webdriver-example/.../AcceptanceTests/src

Acceptance Test Project Structure

Acceptance Test Folder Structure Screenshot

  • Features - All feature files
  • PageObjects - All page object classes
  • Steps - All step definition files
  • TestData - Test data classes
  • Support  - Test framework files:
    • Browser.cs - Where the browser driver is created and has a method to take screenshots of test errors
    • Site.cs - Class which creates the page object factory and instantiates page objects
    • StepBase.cs - This contains the before and after hooks for all tests. (Each step definition file should inherit from this to work when using C#)

Usage Guidelines and Examples

Feature Files

These are written in a BDD format.

  • Given: Preconditions for the test scenarios
  • When: Actions for test scenarios
  • Then: Assertions for the test scenarios (Only Thens should have assertions)

You can have multiples of each, however Givens are always before all Whens and Whens are always before all Thens. A good rule of thumb is that all scenarios should never be more than five lines. If you find you have one longer than five lines, you might what to break it up into smaller scenarios.

In your scenarios you should describe behavior and not user actions for example. Imagine you have a scenario for a charity donation website:

  • Scenario: New user completes a donation up to the Review and Donate page

In this scenario to get to the Review and Donate page you have to fill in several forms on several pages.

Given this you may be tempted to write the scenario in the following way:

  • Scenario: New user completes a donation up to the Review and Donate page
    • Given I open the browser
    • When I go to a charity's Message and Amount page 
    • And I select the "EUR" currency
    • And I select the amount "20"
    • And I click the continue button
    • And I enter my email address
    • And I enter my password
    • And I click the continue button
    • And I enter my credit card details
    • And I click the continue button
    • Then I am brought to the Review and Donate page
    • And the Review and Donate page displays an accurate summary for my pending donation

As you can see this way describes the users actions and has twelve lines. User actions are more likely to change in the future than the users behaviour. That is to say users will always make donations on this site, but their actions and the user interface flow they take to do it will mostly likely change. If this does happen the feature files will have to be rewritten. 

The same scenario can be written as follows:

  • Scenario: New user completes a donation up to the Review and Donate page
    • Given I am on a charity's Message and Amount page 
    • When I submit my donation details with new user credentials
    • Then I am brought to the Review and Donate page
    • And the Review and Donate page displays an accurate summary for my pending donation

In this case the users behavior is described and the user actions are abstracted down into the step definition files.

Please see: github.com/.../DonationSteps.cs

Meaning if the actions change then only the step definition files need be updated.

Step Definitions Files

In these files there should be minimal logic. Here we should only, save values between steps via "ScenarioContext.Current", call methods on page objects, get values from page object methods and assert on them. This is not the place for loops, if statements or finding elements on a page.

Test Steps (Simple logic)

  • Go to page X
  • Remember Y
  • Click here
  • Assert Z is Y- etc..

Some examples:

github.com/.../just-giving-code-test/.../DonationSteps.cs

github.com/.../propertyfinder-code-test/.../PropertySearchSteps.cs

github.com.../propertyfinder-android-app-test/.../PropertySearchSteps.cs

github.com/.../java-and-webdriver-example/.../HomePageSteps.java

Page Objects

Page Object is a Design Pattern which is used for enhancing test maintenance and reducing code duplication. A page object is an object-oriented class that serves as an interface/representation of a page on your site under test. The test steps then use the methods of this page object class whenever they need to interact with the UI of that page. The benefit is that if the UI changes for the page, the tests themselves don’t need to change, only the code within the page object needs to change. Subsequently all changes to support that new UI are located in one place.

In native mobile application testing these are sometimes referred to as a Screen Objects where they represent a screen in the app under test.

These page objects should only do two kinds of things:

  • Actions (no output)
  • Queries (with answers)

Highly descriptive actions/queries (as directed by demands of steps definition files)

Some examples:

github.com/.../just-giving-code-test/.../PageObjects

github.com/.../propertyfinder-code-test/.../PageObjects

github.com/.../propertyfinder-android-app-code-test/.../ScreenObjects

Page Elements

These are essentially mini page objects that represent elements shared between multiple page objects of your site. For example a shared navigation bar could be represented by a page element and multiple page objects could reference it. These are simply used to keep the code and steps definitions clean.

Test Data

Test data is often littered between the feature and step definitions files. It is good practice to abstract it out to its own layer. This will allow you to better maintain any test data changes and allow you to swap out different data sets depending on what test environment you are using. In the charity site example, you can see we have abstracted out a ValidUkAddress.cs and a ValidVisaCard.cs and used it in PaymentAddress.cs and also Payment.cs respectively. 

Avoid Thread.Sleep!

A Thread.Sleep here and there can add up in your code and cause your tests to run unnecessarily slow. Using explicit wait/implicit wait is the best practice.

This is what they do:

  • Explicit wait: An explicit waits is a kind of wait for a certain condition to occur before proceeding further in the code.
  • Implicit wait: An implicit wait is to tell WebDriver to poll the DOM for a certain amount of time when trying to find an element or elements if they are not immediately available. The default setting is 0.
  • Thread.sleep(n): Will always wait for the mentioned seconds "n" even in case the working page is ready after (n-x) sec where (x > 0). So this can slow the tests.
Dwayne Dowding
Dwayne Dowding
Lead Developer in Test