Extent Reports in Automation – NUnit

Captujjkre

     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. Reference click here.
  2. NUnit and NUnit3TestAdapter should be installed via package manager. Reference click here.
  3. Selenium.WebDriver and Selenium.Support should be installed via package manager. Reference click here.
  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 ExtentReports and 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 FailTest and 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 BeforeClass which was assigned to [OneTimeSetUp] annotation to generate the HTML report in the required path.
  • Used object of ExtentTest class (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.

Capturee

Capture

Try to practice this report in your Automation scripts which planning to develop using C# and NUnit.

make it perfect !

7 thoughts on “Extent Reports in Automation – NUnit

Add yours

  1. Thanks for the post and its really helpful . Can you please help me with below scenario . If i am having multiple classes (i.e. Test fixtures) and if i want to implement extent report generic to all classes then how can i implement .

    Your help on this really appreciated.

    Liked by 1 person

    1. You can create a AutomationBase class with following:

      [OneTimeSetUp] : there you can create report directory and add extent HTML report into it.

      [SetUp]: To get the name of current running test to extent report

      [TearDown]: Logging the detials into extent HTML report

      [OneTimeTearDown]: To flush extent report

      Once above steps done, make the test class extends AutomationBase class.

      Like

    1. I already mentioned the code snippet in the post, you can refer from there. You just need to implement this logic in a class say “AutomationReport” after that you can extend your test class with AutomationReport class.

      Like

  2. This was a very helpful post and the reports look great.
    However, I did not manage to have 1 report for multiple test classes. I am using [SetUpFixture] for the OneTimeSetUp and OneTimeTearDown, and if I extend the test classes with the SetUpFixture, then the setup and teardown will run before each class, overwriting the previous report html.
    If I do not extend the test classes, then no html report is created at all
    Do you have any thoughts on this?

    Like

Leave a comment

Create a website or blog at WordPress.com

Up ↑