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
These are written in a BDD format.
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:
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:
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:
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)
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:
Highly descriptive actions/queries (as directed by demands of steps definition files)
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 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.
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: