In this tutorial i will be using Specflow with Selenium WebDriver. In the Previous post, we have gained introductory knowledge of writing feature files. We also generated step definitions for the scenarios. Furthermore, we now understand that BDD is a process which can be aided using Specflow. This point I think is very essential to the success of an Automation project using Specflow. You should realize, that the main automation work, including framework development activities still remain. Specflow is just another layer that can be added, optionally, for business readability.
- Application Under Test and sample Requirement
- Install Selenium and relevant tools
- Implementing the relevant steps
- Hooks Introduction
Application Under Test and Sample Requirement
Please Refer to my previous post here, to help you set up the application I will be using for this demo. It is essentially an easy to get up and running WordPress installation. You can always use another WordPress installation hosted somewhere else.
Here is a sample requirement to simply test Logging into the application. Our Application Under Test is a Web Application.
- It should work on browsers including Chrome, Internet Explorer, Firefox.
- Users should be able to login with registered username or email
Feature: Login In order to create new post As a WordPress user I want to be able to login to the dashboard
There are two Scenarios we can consider with this feature. 'Successful Login' and 'Unsuccessful Login'.
Under Each Scenario we can have multiple test cases. Successful Login could include,
- An Admin attempts login with the correct username and password
- An Editor attempts login with the correct username and password
- An Admin attempts login with the correct email and password
- An Editor attempts login with the correct email and password
Lets look at just one for now.
Scenario: Successful Login by Admin User Given I Navigate to the Login page When I Login with Username 'admin' and Password 'password' on the Login Page Then the User Name 'admin' Should be seen on the Dashboard Page
- Add a new feature file named Login.feature and include the requirement and scenarios.
- The steps in the Feature file should show color indicating that the steps are not bound.
- Generate a new step definition file to match the Scenario steps. (refer to previous tutorial)
- Your generated class should look as shown.
- Do a build and run the test from Test Explorer
- It should fail as expected.
Install Selenium and Relevant Tools
Now we have our requirement and Scenarios. Next, we will install the required tools into our project. All the browsers required have their own driver that can used. We are in luck because selenium can interact with all their drivers to manipulate the page elements. Hence, Selenium WebDriver is the perfect tool for the job.
Here is the shopping list. For now, we will work with just the chrome driver.
- Selenium webDriver
- Chrome driver (depending on your required browser)
We already have MSTest as our unit testing framework for assertion. It was installed when we chose the unit test project template during the initial project creation.
- Add Selenium into the '.Binding project' via nuget packager manager
- Also Install chrome driver into the '.Test project'
- Do a build and make sure you haven't broken anything.
Implementing the relevant Steps
Let us implement the steps with the simplest code that will make it work.
For the Given Step:
- We create an instance of chrome driver
- Then we simply navigate to the url of our Web Application. Mine is http://127.0.0.1:4001/wordpress/wp-login.php
For the When Step:
- We will use the driver instance to find the relevant elements and perform the required operation.
- The username and password data from the scenario steps are passed into the located username field and password field.
- Finally, the located Submit Button is clicked.
Note: sleeps were added to slow things down for demo purposes. We do not do this in real life. More on this later.
Finally, for the Then Step:
- This is where our assertion is done.
- We will use 'AreEqual' method from the MSTest unit testing framework Assert class to compare the expected value to the actual value retrieved by selenium.
- After the test Completion, we will close the browser and then quit the webDriver instance.
You should end up with the code below.
- Spin up the Application that we are testing by starting up 'instant WordPress'
- Ensure you have google chrome browser installed.
- Right Click and Run the Test
- You should get a pass.
From the above solution, you can see that the driver creation and clean-up have been carried out in the Given and Then Steps respectively. This means this piece of code will have to be repeated in every Scenario we are executing.
Specflow comes with a concept called hooks that can help us with this repetition. For now, I will only discuss two of them.
BeforeScenario - The Before Scenario attribute runs any method it is decorated with, before every Scenario.
AfterScenario - The After Scenario attribute runs any method it is decorated with, After every Scenario.
One rule for using hooks that we will consider for now is that the Class containing the Hooks, should be decorated with the [Binding] attribute. So let us add some Hooks.
- Lets create a new folder in the .Binding project called Hooks
- Add a new class and name it GeneralHooks.cs with two methods with the attribute above.
- We will add the code to create a driver instance and then start and setup the chrome browser. This will be done in the before method so copy over the code from the given step.
- After Driver setup, we will store instance of the driver to be used in our Steps binding classes in the Scenario context. More on this later.
- After the Scenario completes, we will add the statements from the Then Step to Quit the driver.
- Note, because we haven't done anything fancy with the hooks, it will apply to every scenario added in the Assembly.
- Finally, in the Login Steps, we will initialize the driver in the constructor.
- Your Binding step show now look as shown.
Do a build.
Ensure your AUT is running and execute the Tests. Your test should pass as before.
As the test suite grows and more tests are added, maintainability, readability and code duplication become a huge issue. In the current solution, We have mixed the knowledge of the application with our scripts. In short the 'Test Code' is mixed up with the 'Test Script'. Imagine we need another step definition class that requires locating the 'username' and 'password' elements for completely different test. We will be in a situation where we will have to repeat these lines.
var usernameBox = _driver.FindElement(By.Id("user_login")); var passwordBox = _driver.FindElement(By.Id("user_pass"));
Now imagine a hundred step definition files. Finally, assume an instance where the locator "user_login" changes to something else? . We will have to go through the trouble of fixing this in multiple areas. #BigNightmare.
There are numerous ways this can be solved. A tried and tested way is using Page Object Model (POM). I have discussed this in detail in my previous tutorial. on POM. I will use the exact same concept to separate the interaction with the UI using selenium from the step definitions (test script) for our specflow scenarios.
We have done the first automated web browser test using specflow with selenium without a framework. Remember, as i have always maintained, Specflow is only another layer. We still need to develop an automation testing framework. A framework is a software used to write test scripts or step definitions quicker in our case.
In next lectures we will look into using Page objects and other techniques to separate our steps scripts from the actual code driving the browser.
Click Here to Download the Complete Working Solution.
Any thoughts, questions, comments, addition, or anything you don’t like, do not hesitate to leave a comment or contact me. Thank you!