Testing ASP.NET + AngularJS Web Application using SpecFlow, Page Objects, Selenium and PhantomJS

We have been using SpecFlow, Page Objects, Selenium and PhantomJS in some of our projects to ensure the good quality of the web application we are building. We have created a public example solution of similar test setup and we want to share it. You can find the example solution from GitHub. The architecture of the example solution is following:

In the example solution we have built a calculator having four features: add, reduce, division and multiplication. We have used SpecFlow to write the business requirements / specs of the features in executable format. To have the specs in executable format means that we can run those automatically in our builds to ensure that all features are working like they should. You can see below an example of SpecFlow business requirement definition for the add feature.

SpecFlow feature contains a background and one or many scenarios. Background is common for all scenarios of a feature and is executed in the beginning of a each scenario. One SpecFlow scenario is in practice one test. Background and scenarios can contain one or many steps. In SpecFlow exists three different type of steps: Given, When and Then. Given steps can be used to arrange the web application under test to a certain state. When steps can be used to define an action in the web application. Then steps can be used to assert that the state of the web application has changed correctly based on the action done in the When step. In order test to execute, all background and scenario steps needs to have a matching code implementation. You can see below step implementations for the add feature.

In order to make SpecFlow step implementations easy to maintain, we are using Page Objects instead of directly using Selenium. Idea behind the page objects is to abstract the web application to a logical objects and hide the implementation details of the web application. Below you can see how the Page Object for the calculator web application is implemented.

We are using Selenium as a library between the tests and the web browser. In our example solution usage of Selenium is visible in the calculator Page Object. Selenium has IWebDriver interface which you can use to communicate with the web application. The actual implementation of the IWebDriver is defined in the beginning of the test run (in the example solution in file SeleniumSupport.cs). The actual implementation of the IWebDriver is web browser specific. Selenium supports usage of different web browsers. You can for example define that Selenium will use Chrome or Firefox as a web driver.

In our example we are using PhantomJS as a web browser. We are using PhantomJS because it is a headless web browser. By using a headless web browser we can improve the feedback time compared to using non-headless web browser like Internet Explorer. With the feedback time we mean in this case the time that the test will take to execute and provide the result (pass/fail).

In our example IIS Express is hosting the ASP.NET + AngularJS web application. IIS Express is automatically started in the beginning of a test run and will be closed when all tests has been executed. You can see below how it is possible to start and stop the IIS Express automatically.

We hope that this blog post and the example solution will help you to improve quality of your web application.