Selenium C# – Test Automation Guide

seleniumwithc

     Entry of Automation changed everything in the innovative world; anyone can automate applications from different corners in the world. In today’s business environment, companies are expected to do more and deliver higher quality applications in lesser time with fewer resources. Nowadays, competitions are happening in between the companies to develop secure, faster and useful applications without breaking the guidelines and requirements of the clients. Here I would like to share the idea of Automation using Selenium C# and its implementations.

Selenium Automation using C# (NUnit and MSTest)

Recently, I got an opportunity to write selenium automation using C# language with NUnit and MSTest frameworks. Prior to scripting, I started the configuration from the scratch to achieve my selenium scripting using C# with NUnit and MSTest. Here I would like to share my experience with configuration and scripting part,

Steps for install and configure Visual Studio:

Step 1: Navigate to the URL https://www.visualstudio.com/downloads/ and Click on the ‘Free download’ button displayed on Visual Studio Community 2017 tab.
Step 2: Open the exe downloaded. Click on ‘Yes’ if asked for Admin Rights.
Step 3: A popup will appear. Click on ‘Continue’ button.
Step 4: In the next screen, select the check-boxes for

  • Universal Windows Platform development
  • .Net desktop development

Click on ‘Install.’ Wait for installation of each component to complete. Files are 16GB in size and will take time.
Step 5: A pop up will be displayed. Click on ‘Restart’ button (if required).
Step 6: Once the machine is restarted, search for “Visual Studio 2017” on the start menu and click on the search result. In the next screen, Click on “Not now, maybe later” link if you do not have an existing account.
Step 7: In the next screen,

  • Select color theme of your liking
  • Click the button “Start Visual Studio'”

Step 8: Visual Studio ‘Get Started’ screen will appear.

Set up Visual Studio with Selenium WebDriver:

Step 1: Navigate to Tools -> NuGet Package Manager -> Manage NuGet Packages for Solution
Step 2: In the next window,

  1. Search for “Selenium”.
  2. Select the first search result “Selenium.WebDriver”
  3. Check the project checkbox
  4. Select the desired version.
  5. Click on ‘Install’.
  6. Select second search result “Selenium.Support”
  7. Check the project checkbox.
  8. Select the desired version.
  9. Click on ‘Install’.
Set up Visual Studio with NUnit Framework:

Step 1: Navigate to Tools -> NuGet Package Manager -> Manage NuGet Packages for Solution
Step 2: In the next window,

  1. Search for “NUnit”
  2. Select the search result “NUnit”
  3. Check the project checkbox
  4. Select the desired version.
  5. Click Install.
  6. In the same window, select search result “NUnit3TestAdapter”
  7. Check the project checkbox.
  8. Select the desired version.
  9. Click on ‘Install’.
Set up Visual Studio with MSTest Framework:

Step 1: Navigate to Tools -> NuGet Package Manager -> Manage NuGet Packages for Solution
Step 2: In the next window,

  1. Search for “MSTest”
  2. Select the search result “MSTest.TestFramework”
  3. Check the project checkbox
  4. Select the desired version.
  5. Click Install.
  6. In the same window, select search result “MSTest.TestAdapter”
  7. Check the project checkbox.
  8. Select the desired version.
  9. Click on ‘Install’.
Create a new project in Visual Studio:

Step 1: In the File Menu, Click New > Project
Step 2: In the next screen,

  1. Select the option ‘Visual C#’
  2. Click on Console App (.Net Framework)
  3. Enter project name.
  4. Click OK

Step 3: You will be able to see the created project.

Now the configurations and project is ready, next you can add one C# class file to project and start writing your first scripts for automation as below.

Selenium C# with MSTest:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Threading;

namespace seleniumTestProject
{
[TestClass]
public class SeleniumTest
{
public IWebDriver driver; //declare the driver object
[TestInitialize]
public void BeforeTest()
{
driver = new ChromeDriver(“path_to_chromedriver.exe”); //initialize the ChromeDriver instance
driver.Url = “https://www.google.co.in/”; //load application URL
}

[TestMethod]
public void GoogleSearchTest()
{
driver.FindElement(By.Id(“lst-ib”)).SendKeys(“Journey of Quality”);
}

[TestCleanup]
public void AfterTest()
{
driver.Close();
}
}
}

Selenium C# with NUnit:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using NUnit.Framework;
using NUnit.Framework.Interfaces;
using System.Threading;

namespace seleniumTestProject
{
[TestFixture]
public class SeleniumTest
{
public IWebDriver driver; //declare the driver object

[OneTimeSetUp]
public void BeforeClass()
{
driver = new ChromeDriver(“path_to_chromedriver.exe”); //initialize the ChromeDriver instance
driver.Url = “https://www.google.co.in/”; //load application URL
}

[SetUp]
public void BeforeTest()
{
//You can write any precondition to perform prior to each test cases
}

[Test]
public void GoogleSearchTest()
{
driver.FindElement(By.Id(“lst-ib”)).SendKeys(“Journey of Quality”);
}

[TearDown]
public void AfterTest()
{
driver.Close();
}

[OneTimeTearDown]
public void AfterClass()
{
driver.Quit();
}
}
}

     Try the above configuration and scripting using C# for Selenium Automation from your end. I recommend everyone to use NUnit framework than MSTest framework for Selenium C# scripting. NUnit provides straight-froward scripting when use their annotations. In case of MSTest, we must declare the method as static and should possess one parameter when use [AssemblyInitialize] or [ClassInitialize]. In case of NUnit, no need to declare the method as static when uses [OneTimeSetUp] or [SetUp].

Set up Extent Reports with NUnit:

I observed that the difficulty to generate rich HTML report in Automation using NUnit. One day, I thought to build a custom beautiful high rich HTML reports with minimum effort; that time I used AventStack’s Extent Report. Here, I would like to share the details on the integration and implementation of Extent Report utility in Automation test classes that built with NUnit.

Prerequisites to Generate Extent Reports:
  1. Visual Studio 2017 should be installed.
  2. NUnitand NUnit3TestAdapter should be installed via package manager.
  3. WebDriverand Selenium.Support should be installed via package manager.
  4. ExtentReports package should be installed via package manager.
Set up Visual Studio with ExtentReports:

Step 1: Navigate to Tools -> NuGet Package Manager -> Manage NuGet Packages for Solution
Step 2: In the next window,

  1. Search for “ExtentReports”.
  2. Select the first search result “ExtentReports”.
  3. Check the project checkbox.
  4. Select the desired version. Better to select latest version.
  5. Click on ‘Install’.
Steps To Generate Extent Reports:
  1. Firstly, create a Console App (.Net Framework) project.
  2. Create a c# class say ‘SeleniumExtentReport’ and add following code to it,

using System;
using System.Text;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

using AventStack.ExtentReports;
using System.IO;
using AventStack.ExtentReports.Reporter;
using NUnit.Framework;
using NUnit.Framework.Interfaces;
using System.Threading;

namespace SeleniumExtentReportTest
{
[TestFixture]
public class SeleniumExtentReport
{
public IWebDriver driver;
protected ExtentReports _extent;
protected ExtentTest _test;

///For report directory creation and HTML report template creation
///For driver instantiation
/// Author: Sanoj
/// Since: 23-Sep-2018
[OneTimeSetUp]
public void BeforeClass()
{
try
{
//To create report directory and add HTML report into it

_extent = new ExtentReports();
var dir = AppDomain.CurrentDomain.BaseDirectory.Replace(“\\bin\\Debug”, “”);
DirectoryInfo di = Directory.CreateDirectory(dir + “\\Test_Execution_Reports”);
var htmlReporter = new ExtentHtmlReporter(dir + “\\Test_Execution_Reports” + “\\Automation_Report” + “.html”);
_extent.AddSystemInfo(“Environment”, “Journey of Quality”);
_extent.AddSystemInfo(“User Name”, “Sanoj”);
_extent.AttachReporter(htmlReporter);
}
catch (Exception e)
{
throw (e);
}

try
{
driver = new ChromeDriver();
}
catch (Exception e)

{
throw (e);
}
}

///Getting the name of current running test to extent report
/// Author: Sanoj
/// Since: 23-Sep-2018
[SetUp]
public void BeforeTest()
{
try
{
_test = _extent.CreateTest(TestContext.CurrentContext.Test.Name);
}
catch (Exception e)
{
throw (e);
}
}

[Test]
public void PassTest()
{
Assert.IsTrue(true);
}
[Test]
public void FailTest()
{
driver.Url=”
http://google.com”;
Assert.AreEqual(driver.Title, “Journey”);
}

/// Finish the execution and logging the detials into HTML report
/// Author: Sanoj
/// Since: 23-Sep-2018
[TearDown]
public void AfterTest()
{
try
{
var status = TestContext.CurrentContext.Result.Outcome.Status;
var stacktrace = “” + TestContext.CurrentContext.Result.StackTrace + “”;
var errorMessage = TestContext.CurrentContext.Result.Message;
Status logstatus;
switch (status)
{
case TestStatus.Failed:
logstatus = Status.Fail;
string screenShotPath = Capture(driver, TestContext.CurrentContext.Test.Name);
_test.Log(logstatus, “Test ended with ” + logstatus + ” – ” + errorMessage);
_test.Log(logstatus, “Snapshot below: ” + _test.AddScreenCaptureFromPath(screenShotPath));
break;
case TestStatus.Skipped:
logstatus = Status.Skip;
_test.Log(logstatus, “Test ended with ” + logstatus);
break;
default:
logstatus = Status.Pass;
_test.Log(logstatus, “Test ended with ” + logstatus);
break;
}
}
catch (Exception e)
{
throw (e);
}
}

///To flush extent report
///To quit driver instance
/// /// Author: Sanoj
/// Since: 23-Sep-2018
[OneTimeTearDown]
public void AfterClass()
{
try
{
_extent.Flush();
}
catch (Exception e)
{
throw (e);
}
driver.Quit();
}

/// To capture the screenshot for extent report and return actual file path
/// Author: Sanoj
/// Since: 23-Sep-2018
private string Capture(IWebDriver driver, string screenShotName){
string localpath = “”;
try
{
Thread.Sleep(4000);
ITakesScreenshot ts = (ITakesScreenshot)driver;
Screenshot screenshot = ts.GetScreenshot();
string pth = System.Reflection.Assembly.GetCallingAssembly().CodeBase;
var dir = AppDomain.CurrentDomain.BaseDirectory.Replace(“\\bin\\Debug”, “”);
DirectoryInfo di = Directory.CreateDirectory(dir + “\\Defect_Screenshots\\”);
string finalpth = pth.Substring(0, pth.LastIndexOf(“bin”)) + “\\Defect_Screenshots\\” + screenShotName + “.png”;
localpath = new Uri(finalpth).LocalPath;
screenshot.SaveAsFile(localpath);
}
catch (Exception e)
{
throw (e);
}
return localpath;
}
}
}

Code Explanation:
  • Imported two classes ExtentReportsand ExtentTest.
    • ExtentReportsBy using this class we set the path where our reports need to generate.
    • ExtentTestBy using this class we could generate the logs in the report.
  • Took two methods with [Test] annotation such as PassTest and FailTestand method BeforeClass with [OneTimeSetUp] annotation, BeforeTest with [SetUp] annotation, another method AfterTest with [TearDown] annotation and finally, AfterClass with [OneTimeTearDown] annotation.
  • Here my intention is to generate a report with all the two types of results such as Pass and Fail.
  • Used object of ExtentReports class (i.e., _extent) in the BeforeClasswhich was assigned to [OneTimeSetUp] annotation to generate the HTML report in the required path.
  • Used object of ExtentTestclass (i.e., _test) in BeforeTest to get the name of currently executing test case. Also, _test object used in AfterTest method which was assigned to [TearDown] annotation to write logs in the report.
  • Used TestStatus class in the [TearDown] to describe the result of a test.

     Refresh the project after execution. You could find an HTML file named “Automation_Report.html” in “Test_Execution_Reports” folder. Copy the location of the “Automation_Report.html” file and open it by using any browser. You could see beautiful high rich HTML reports as shown below.

1

2

Parallel Execution in Selenium C# Automation:

      In case of Selenium C#, there is no direct capability like TestNG to achieve the parallel execution of test cases in different instances of browsers. I used NUnit attributes just above in all test classes and that test class extends AutomationBase class. Used following NUnit attributes:

  • [TestFixture(“chrome”)]
  • [TestFixture(“firefox”)]
  • [Parallelizable]

        Added a parameterized constructor (the parameter should be browserName) and call StartBrowser(browserName) method inside the constructor. StartBrowser (browserName) method is implemented in AutomationBase class. Following is the sample implementation that I have done in the test class:

using NUnit.Framework;
namespace com.test.testcases
{
[TestFixture(“chrome”)]
[TestFixture(“firefox”)]
[Parallelizable]
public class TestModuleClass: AutomationBase
{
public TestModuleClass(string browserName)
{
StartBrowser(browserName);
}

[Test, Order(1)]
public void TC_001_SampleTest()
{
//Your test steps
}
}
}

    In AutomationBase class, I have added new method StartBrowser(String browserName) to identify the requested browser for execution and implemented the logic to drive chrome and firefox drivers. Following is the implementation of StartBrowser,

public IWebDriver StartBrowser(String browserName)
{
try
{
if (browserName.ToLower().Equals(“”))
{
throw (new Exception(“BROWSER_NAME is not specified”));
}
if (browserName.ToLower().Equals(“chrome”))
{
// implement code to start chrome driver session
}
if (browserName.ToLower().Equals(“firefox”))
{
// implement code to start firefox driver session
}
}
catch (Exception e)
{
throw (e);
}
return driver;
}

Send Automation Reports as Mail Report

     Automation test reports are one of the important deliverable of Automation executions. Getting those automation reports in the mail automatically is another important concept. The System.Net.Mail namespace contains classes used to send electronic mail to a Simple Mail Transfer Protocol (SMTP) server for delivery. Following Send_Report_In_Mail() method helps to send test automation reports with attachment,

public void Send_Report_In_Mail()
{
MailMessage mail = new MailMessage();
SmtpClient SmtpServer = new SmtpClient(“smtp.gmail.com”);
mail.From = new MailAddress(“sender_mail_address”);
mail.To.Add(“mail_lists_of_recipients”);

StringBuilder TimeAndDate = new StringBuilder(DateTime.Now.ToString());
TimeAndDate.Replace(“/”, “_”);
TimeAndDate.Replace(“:”, “_”);

mail.Subject = “Automation Test Report_”+ TimeAndDate;

mail.Body = “Please find the attached report to get details.”;

string actualPath = AppDomain.CurrentDomain.BaseDirectory.Replace(“\\bin\\Debug”, “\\Test_Execution_Reports”); //Reports should store in Test_Execution_Reports folder

var mostRecentlyModified = Directory.GetFiles(actualPath, “*.html”)
.Select(f => new FileInfo(f))
.OrderByDescending(fi => fi.LastWriteTime)
.First()
.FullName;

Attachment attachment;
attachment = new Attachment(mostRecentlyModified);
mail.Attachments.Add(attachment);

SmtpServer.Port = 587;
SmtpServer.Credentials = new System.Net.NetworkCredential(“sender_mail_address”, “sender_mail_account_password”);
SmtpServer.EnableSsl = true;

SmtpServer.Send(mail);

}

In case of NUnit(C#), you can use above method in [OneTimeTearDown]

Try to use above mentioned capabilities in your Selenium C# automation.

make it perfect !

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s