Automation Testing using Specflow and Selenium in .NET Framework

Automation Testing using Specflow and Selenium in .NET Framework

This tutorial explain Automation testing using Specflow and Selenium in .NET framework. We will see an end to end example of using Specflow based BDD specifications and the tests will be executed via Selenium Webdriver. The tests could be as simple as testing the login functionality of an application. It is just that, we will describe those tests using Specflow and the Step implementations will use Selenium driver and commands and NUnit as assertion framework.

Find Source Code

End of article, you can see the automation how automation is work for us. When the script is run then it automatically call to YouTube then search India as Country.

Creating .NET Project and implement Automation Testing

  • Create .NET Core Unit Test Project like below. (We consider Visual Studio 2019)
  • The .NET Framework version is 4.7.2

Add the below required package in the Project

To add the package into folder we can add using 2 ways.

  1. Right click on project then Manage Nuget Packages then add the packages
  2. Add using Nuget package Manager Console, Tools => Nuget Package Manager => Package Manager Console

#1) Install Nuget package for Nunit and Specflow.

Install-Package Specflow.NUnit

#2) Install Selenium’s Webdriver for chrome browser. 

This can be installed via Nuget Package Manager console too through the below command.

Install-Package Selenium.WebDriver.ChromeDriver

#3) Install Selenium Webdriver libraries and Selenium Wait Helpers for adding ExpectedCondition waits.

Install-Package Selenium.WebDriver
Install-Package DotNetSeleniumExtras.WaitHelpers

#4) Create folders for Features and Step Definitions to store feature and Step definition implementation files.

This is not a mandatory step but is useful to organize the features and step implementations in separate folders.

Feature and Step Implementation

Now let’s get started with the feature file and the actual step implementation.

Feature Implementation

The sample feature will be of testing/validating the search functionality of YouTube Website. We will be searching for a keyword and asserting that the user got redirected to the search results page.

Add a new feature file and name it as YoutubeSearch.feature

Feature: YoutubeSearch
	In order to test search functionality on youtube	 
@mytag
Scenario: Youtube should search for the given keyword and should navigate to search results page
	Given I have navigated to youtube website
	And   I have entered India as search keyword
	When I press the search button
	Then I should be navigate to search results page

The above scenario expects the test to:

  • Navigate to YouTube Website: This will require a Web automation framework like Selenium, which will use a Webdriver to navigate to a webpage on a browser.
  • Search for a keyword: This step will involve looking for appropriate input elements and buttons in order to key-in the keyword and execute the search respectively.
  • Assert that the search results are displayed and the user is on the results page: This step will involve assertions around verifying if the user landed on the correct page.

Steps Definition Implementation

Then you can create the steps definition name it as YoutubeSearchSteps.cs, Right click on feature then Generate Step definitions.

using System;
using TechTalk.SpecFlow;
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;
using SeleniumExtras.WaitHelpers;
using System.Collections.Generic;
using System.Linq;
namespace Specflow.UnitTest.StepDefinitions
{
    [Binding]
    public class YoutubeSearchSteps : IDisposable
    {
        private String searchKeyword;
        private ChromeDriver chromeDriver;
        public YoutubeSearchSteps() => chromeDriver = new ChromeDriver();
        
        [Given(@"I have navigated to youtube website")]
        public void GivenIHaveNavigatedToYoutubeWebsite()
        {
            chromeDriver.Navigate().GoToUrl("https://www.youtube.com");
            Assert.IsTrue(chromeDriver.Title.ToLower().Contains("youtube"));
        }
        [Given(@"I have entered (.*) as search keyword")]
        public void GivenIHaveEnteredIndiaAsSearchKeyword(String searchString)
        {
            this.searchKeyword = searchString.ToLower();
            var searchInputBox = chromeDriver.FindElementById("search");
            var wait = new WebDriverWait(chromeDriver, TimeSpan.FromSeconds(2));
            wait.Until(ExpectedConditions.ElementIsVisible(By.Id("search")));
            searchInputBox.SendKeys(searchKeyword);
        }
        [When(@"I press the search button")]
        public void WhenIPressTheSearchButton()
        {
            var searchButton = chromeDriver.FindElementByCssSelector("button#search-icon-legacy");
            searchButton.Click();        
        }
        [Then(@"I should be navigate to search results page")]
        public void ThenIShouldBeNavigateToSearchResultsPage()
        {
            System.Threading.Thread.Sleep(2000);
            // After search is complete the keyword should be present in url as well as page title`
            Assert.IsTrue(chromeDriver.Url.ToLower().Contains(searchKeyword));
            Assert.IsTrue(chromeDriver.Title.ToLower().Contains(searchKeyword));
        }
        public void Dispose()
        {
            if (chromeDriver != null)
            {
                chromeDriver.Dispose();
                chromeDriver = null;
            }
        }
    }
}

Code Explanation

#1) Arrange Steps:

Given I have navigated to youtube website  
And I have entered India as search keyword  

Both of these steps involve interacting with the driver instance. The first step open’s the browser window and navigates to the YouTube website. The second step looks for search input button and enters “India” as the search keyword.

Below is the implementation for both of these steps:

[[Given(@"I have navigated to youtube website")]  
public void GivenIHaveNavigatedToYoutubeWebsite()  
{  
    chromeDriver.Navigate().GoToUrl("https://www.youtube.com");  
    Assert.IsTrue(chromeDriver.Title.ToLower().Contains("youtube"));  
}  
[Given(@"I have entered (.*) as search keyword")]  
public void GivenIHaveEnteredIndiaAsSearchKeyword(String searchString)  
{  
this.searchKeyword = searchString.ToLower();  
var searchInputBox = chromeDriver.FindElementById("search");  
var wait = new WebDriverWait(chromeDriver, TimeSpan.FromSeconds(2));  
wait.Until(ExpectedConditions.ElementIsVisible(By.Id("search")));  
searchInputBox.SendKeys(searchKeyword);  
}

For the first Step, notice the Assertion that it ensures that the navigation to youtube was successful by checking the window title.

Note: There can be various ways of placing Assertions on different web elements or driver properties, but the end goal of this tutorial is just to illustrate with the most simplistic way.

In the second step, we have added a Dynamic wait using ExpectedConditions which will ensure that the search box is visible before the code tries to key-in the search keyword.

Also, we are storing the searchString in a private field searchKeyword. This is done so that the searchKeyword can be used in other Step implementations too.

Passing data across the Steps

Passing/Storing data by this approach (i.e. through class variables) is one of the means through which data can be shared across Step bindings.

There are other ways to do this as well like Specflow itself provides a Dynamic Dictionary Object called ScenarioContext. We will see more details about this in the upcoming articles.

#2) Act Step

When I press the search button

Now let’s look at the actual action, which is clicking on the Search button. The step implementation file will search for the search button and click it in order to execute the scenario step.

The code for this step looks as shown below:

[When(@"I press the search button")]  
public void WhenIPressTheSearchButton()  
{      
var searchButton = chromeDriver.FindElementByCssSelector("button#search-icon-legacy");  
    searchButton.Click();  
}  

#3) Finally the Assert Step:

Then I should navigate to search results page

In this step, we are just verifying from the Driver properties as to whether the URL and the page title contains the search keyword or not.

The code for this step is shown below:

[Then(@"I should be navigate to search results page")]  
public void ThenIShouldBeNavigateToSearchResultsPage()  
{  
    // After search is complete the keyword should be present in url as well as page title`  
    Assert.IsTrue(chromeDriver.Url.ToLower().Contains(searchKeyword));  
    Assert.IsTrue(chromeDriver.Title.ToLower().Contains(searchKeyword));  
} 

Execution

Now, let’s try to execute the Scenario and see the results. Once the Scenario is executed, all the Scenario Steps will be executed Sequentially. The test will be opening a browser, navigating to a website and then performing some action.

The output of the test can be seen by clicking the “Output” button from the test summary which shows the success/failure of each individual step.

Source Code

Please find attached the source code share in GitHub link.

Find Source Code

Summary

 Hope you liked this article on Automation Testing using Specflow and Selenium in .NET Framework. We would like to have feedback from my blog readers. Your valuable feedback, question, or comments about this article are always welcome.

Have you enjoyed this post and found it useful? If so, please consider supporting me:

Buy me a coffeeBuy me a coffee

Unit Testing in ASP.NET C#
Unit Testing in ASP.NET C#

This article explain about how to use Unit testing in ASP.NET C#. Testing is an essential aspect of any programming Read more

Unit Testing in ASP.NET C#

Unit Testing in ASP.NET C#

In this article we will discuss how to make unit testing in ASP.NET C#. Testing is an essential aspect of any programming language. Testing for ASP.Net applications is possible with the help of Visual Studio. Every successful software development follows a lifecycle known as SDLC (Software Development Life Cycle).As per Wikipedia: “SDLC is a process followed for a software project, within a software organization. It consists of a detailed plan describing how to develop, maintain, replace and alter or enhance specific software. The life cycle defines a methodology for improving the quality of software and the overall development process.”

Find Source Code

As a developer we normally understand the requirements and write the code. Apart from those we also spend some time software testing. Software testing is a process of executing a program or application with the intent of finding the software bugs. It can also be described as the process of validating and verifying a software program or application or product.

Visual Studio is used to create test code. It is also used to run the test code for an ASP.Net application. In this way, it becomes simple to check for any errors in an ASP.Net application. In Visual Studio, the testing module comes with an out of box functionality. One can straightaway perform a test for an ASP.Net project.

Introduction to Unit testing for ASP.NET

The first level of testing an ASP.Net project is unit level testing. This test is the functionality of an application. The testing is conducted to ensure that the application behaves as expected. In ASP.Net, the first task is to create a test project in Visual Studio. The test project will contain the necessary code to test the application.

Let’s consider the below web page. In the page, we have the sample Calculator that can calculate the passing data (+,,*,/). Now how can we confirm that the correct message is displayed when an ASP.Net project runs. This is done by adding a test project to the ASP.Net solution (used to develop web-based applications). This test project would ensure that the right message is displayed to the user.

Create Sample ASP.NET C# Web Application

Let’s Create a sample ASP.NET web application to following below steps.

  • Choose ASP.NET Web application(.NET Framework)
  • Choose Web Forms template as we want to do it in ASP.NET Web forms.
  • We name the ASP.NET Web forms project name as “Demo.App”.

Create a Models Folder under Demo.App ASP.NET C# application

  • Right Click on the Demo.App project and add a new folder named as “Models”.
  • Under “Models” folder add a class name as “Calculator.cs” with required methods to perform addition, subtraction, multiplication and Division.
  • And the sample code look like below,
 public class Calculator
    {
        public int add(int x, int y)
        {
            return x + y;
        }
        public int sub(int x, int y)
        {
            return x - y;
        }
        public int mul(int x, int y)
        {
            return x * y;
        }
        public int div(int x, int y)
        {
            return x - y;
        }
    }

Impose Calculator method in Default page

<div class="jumbotron">
        <div class="row">
            <asp:Label ID="lbl_add" runat="server"></asp:Label>
        </div>
        <div class="row">
            <asp:Label ID="labl_sub" runat="server"></asp:Label>
        </div>
        <div class="row">
            <asp:Label ID="lbl_mul" runat="server"></asp:Label>
        </div>
        <div class="row">
            <asp:Label ID="lbl_div" runat="server"></asp:Label>
        </div>
    </div>
 public partial class _Default : Page
    {
        Calculator _calc = new Calculator();
        protected void Page_Load(object sender, EventArgs e)
        {
            lbl_add.Text ="Addition Value of (100,5) is : " + _calc.add(100, 5).ToString();
            labl_sub.Text = "Substraction Value of (100,5) is : " + _calc.sub(100, 5).ToString();
            lbl_mul.Text = "Multiplication Value of (100,5) is : " + _calc.mul(100, 5).ToString();
            lbl_div.Text = "Division Value of (100,5) is : " + _calc.div(100, 5).ToString();
        }
    }

Creating a .NET Unit Testing Project

Before we create a test project, let’s remind the below high-level steps.

  • Ensure the Demo.App is open in Visual Studio

To following below steps create the Unit Test project.

  • Choose Unit Test template (We set the project name as Demo.Test)
  • Add reference the Demo.APP in Unit test project
  • UnitTest1.cs file look like below
 [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestMethod1()
        {
            Calculator _cal = new Calculator();
          
            // addition
            Assert.AreEqual(_cal.add(10, 20),30);
            // substraction
            Assert.AreEqual(_cal.sub(20, 20), 0);
            // multiplication
            Assert.AreEqual(_cal.mul(10, 20), 200);
            // division
            Assert.AreEqual(_cal.div(20, 20), 0);
        }
    }

Code Explanation

  • You can see we access the Calculator class and create the object.
  • Call all the calculate method with the expected value and actual value.
  • Expected value is that we pass to the method and actual value is depends upon expected result means let’s take an example Assert.AreEqual(_cal.add(10, 20),30); If we pass value as (10,20) then output should be 30. If the actual value is not 30 then the unit test is not pass. Like this others are work accordingly to their type.
  • Let’s run the Unit test project to follow below steps.

Run Unit Test Project

To run the Unit test project follow below steps.

  • Choose on the Menu Test and then select Run All Tests and if all the result is pass then below image is show as pass.

How to test the Unit testing Project is failed

Let’s make the change the expected value with wrong one and see how the test result is failed.

  • You can see we make change on Assert.AreEqual(_cal.add(10, 20),35) the expected value is 10+20=30 but we make as 35.
  • Like this Assert.AreEqual(_cal.sub(20, 20), 10) we make as 20-20=0 but we make as 10.
  • And when we run you can see the below image the test result is clearly failed.
[TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestMethod1()
        {
            Calculator _cal = new Calculator();

            // addition
            Assert.AreEqual(_cal.add(10, 20),35);
            // substraction
            Assert.AreEqual(_cal.sub(20, 20), 10);
            // multiplication
            Assert.AreEqual(_cal.mul(10, 20), 200);
            // division
            Assert.AreEqual(_cal.div(20, 20), 0);
        }
    }

Source Code

Find Source Code

Summary

  • ASP.Net can add Unit Testing for applications.
  • To test an application, we need to add a Unit Test project to the ASP.Net solution.
  • All tests can be made to run in Visual Studio. A test explorer will show the results of all of the tests.

Have you enjoyed this post and found it useful? If so, please consider supporting me:

Buy me a coffeeBuy me a coffee

How to use angular material in angular
How to use angular material in angular

UI component infrastructure and Material Design components for mobile and desktop Angular web applications.

How to create custom pipes in Angular
How to create custom pipes in Angular

A pipe takes in data as input and transforms it to a desired output. Simply you can say Pipes are Read more

How to read external JSON file in Jquery AJAX
Javascript-Jquery-Ajax

This article explain how to read external json file. There are many ways to store JSON data in our application. Read more

Export data into Excel in ASP.NET MVC
Export-data-into-Excel

In this example we learn how to export the data into MS Excel in ASP.NET MVC without using any 3rd Read more

Pin It on Pinterest