Browse Category: Webdriver

Test Automation in Selenium Using Page Object Model and Page Factory

Writing automated tests is more than just a luxury for any agile software development team. It is a need, and is an essential tool to find bugs quickly during early phases of software development cycles. When there is a new feature that is still in development phase, developers can run automated tests and see how other parts of the system are affected by those changes.

Through test automation, it is possible to lower the cost of bug fixing and bring overall improvement to quality assurance (QA) process. With proper tests, developers get a chance at finding and resolving bugs even before it gets to QA. Test automation further helps us to automate test cases and features that are constantly regressing. This way QAs have more time in testing other parts of the application. Moreover, this helps in ensuring quality of the product in production releases. As a result, we get products that are effectively more stable, and a QA process that is more efficient.

clip_image001

Selenium simplifies test automation for web applications

Although writing automated tests may seem like an easy task for developers and engineers, there is still the possibility of ending up with poorly implemented tests, and the high cost of code maintenance in any agile process. Trying to constantly deliver changes or features in any agile development project can prove to be costly when tests are involved. Changing one element on a web page that 20 tests rely on will require one to go through these 20 test routines and update each one to adapt to this newly introduced change. Not only can this be really time consuming, but a serious de-motivating factor when it comes to implementing automated tests early on.

But, what if we could make the change in one place only, and have every relevant test routine use it? In this article, we will take a look at automated tests in Selenium, and how we can use Page Object models to write maintainable and reusable test routines.

Page Object Model in Selenium

Page Object model is an object design pattern in Selenium, where web pages are represented as classes, and the various elements on the page are defined as variables on the class. All possible user interactions can then be implemented as methods on the class:

clickLoginButton();
setCredentials(user_name,user_password);

Since well-named methods in classes are easy to read, this works as an elegant way to implement test routines that are both readable and easier to maintain or update in the future. For example:

In order to support Page Object model, we use Page Factory. Page Factory is an extension to Page Object and can be used in various ways. In this case we will use Page Factory to initialize web elements that are defined in web page classes or Page Objects.

Web page classes or Page Objects containing web elements need to be initialized using Page Factory before the web element variables can be used. This can be done simply through the use of initElements function on PageFactory:

LoginPage page = new LoginPage(driver);
PageFactory.initElements(driver, page);

Or, even simpler:

LoginPage page = PageFactory.intElements(driver,LoginPage.class)

Or, inside the web page class constructor:

public LoginPage(WebDriver driver) {           
         this.driver = driver; 
         PageFactory.initElements(driver, this);
}

Page Factory will initialize every WebElement variable with a reference to a corresponding element on the actual web page based on configured “locators”. This is done through the use of @FindBy annotations. With this annotation, we can define a strategy for looking up the element, along with the necessary information for identifying it:

@FindBy(how=How.NAME, using="username")
private WebElement user_name;

Every time a method is called on this WebElement variable, the driver will first find it on the current page and then simulate the interaction. In case we are working with a simple page, we know that we will find the element on the page every time we look for it, and we also know that we will eventually navigate away from this page and not return to it, we can cache the looked up field by using another simple annotation:

@FindBy(how=How.NAME, using="username")
@CacheLookup
private WebElement user_name;

This entire definition of the WebElement variable can be replaced with its much more concise form:

@FindBy(name="username")
private WebElement user_name;

The @FindBy annotation supports a handful of other strategies that make things a bit easier:

id, name, className, css, tagName, linkText, partialLinkText, xpath

@FindBy(id="username")
private WebElement user_name; 

@FindBy(name="passsword")
private WebElement user_password;

@FindBy(className="h3")
private WebElement label;

@FindBy(css=”#content”)
private WebElement text;

Once initialized, these WebElement variables can then be used to interact with the corresponding elements on the page. The following code will, for example:

user_password.sendKeys(password);

… send the given sequence of keystrokes to the password field on the page, and it is equivalent to:

driver.findElement(By.name(“user_password”)).sendKeys(password);

Moving on, you will often come across situations where you need to find a list of elements on a page, and that is when @FindBys comes in handy:

@FindBys(@FindBy(css=”div[class=’yt-lockup-tile yt-lockup-video’]”)))
private List<WebElement> videoElements;

The above code will find all the div elements having two class names “yt-lockup-tile” and “yt-lockup-video”. We can simplify this even more by replacing it with the following:

@FindBy(how=How.CSS,using="div[class=’yt-lockup-tile yt-lockup-video’]")
private List<WebElement> videoElements;

Additionally, you can use @FindAll with multiple @FindBy annotations to look for elements that match any of the given locators:

@FindAll({@FindBy(how=How.ID, using=”username”),

@FindBy(className=”username-field”)})
private WebElement user_name;

Now that we can represent web pages as Java classes and use Page Factory to initialize WebElement variables easily, it is time we see how we can write simple Selenium tests using PO and PF patterns.

Simple Test Automation Project in Java

For our simple project let’s automate developer sign up for Toptal. To do that, we need to automate the following steps:

· Visit www.toptal.com

· Click on the “Apply As A Developer” button

· On Portal Page first check if it’s opened

· Click on the “Join Toptal” button

· Fill out the form

· Submit the form by clicking on “Join Toptal” button

Setting Up a Project

· Download and install Java JDK

· Download and install InteliJ Idea

· Create a new Maven project

· Link “Project SDK” to your JDK, e.g.: on Windows “C:\Program Files\Java\jdkxxx”

· Setup groupId and artifactId:

<groupId>SeleniumTEST</groupId>
<artifactId>Test</artifactId>

· Add dependencies Selenium and JUnit Maven in your project POM file

   <dependencies>
        <!-- JUnit -->         
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
 
        <!-- Selenium -->
 
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-firefox-driver</artifactId>
            <version>${selenium.version}</version>
        </dependency>
 
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-support</artifactId>
            <version>${selenium.version}</version>
        </dependency>
 
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>${selenium.version}</version>
        </dependency>
 
    </dependencies>

Replace Selenium version and JUnit Version with latest version numbers that can be found by searching for JUnit Maven on Google and on Selenium site.

At this point, if auto build is enabled, dependencies should start downloading automatically. If not, just activate Plugins > install > install:install under the Maven Projects panel on the right side of your IntelliJ Idea IDE.

clip_image002

Once the project has been bootstrapped, we can start creating our test package under “src/test/java”. Name the package “com.toptal”, and create two more packages under it: “com.toptal.webpages” and “com.toptal.tests”.

clip_image003

We will keep our Page Object/Page Factory classes under “com.toptal.webpages” and the test routines under “com.toptal.tests”.

Now, we can start creating our Page Object classes.

HomePage Page Object

The very first one we need to implement is for Toptal’s homepage (www.toptal.com). Create a class under “com.toptal.webpages” and name it “HomePage”.

package com.toptal.webpages;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.How;
import org.openqa.selenium.support.PageFactory;
 
 public class HomePage {
   private WebDriver driver;
 
   //Page URL
   private static String PAGE_URL="https://www.toptal.com";
 
   //Locators
 
   //Apply as Developer Button
   @FindBy(how = How.LINK_TEXT, using = "APPLY AS A DEVELOPER")
   private WebElement developerApplyButton;
 
   //Constructor
   public HomePage(WebDriver driver){
       this.driver=driver;
       driver.get(PAGE_URL);
       //Initialise Elements
       PageFactory.initElements(driver, this);
   }
 
   public void clickOnDeveloperApplyButton(){
 
       developerApplyButton.click();
 
   }
}
Determining Element Locators

On Toptal’s homepage we are interested about one element in particular, and that is the “Apply as a Developer” button. We can find this element by matching the text, which is what we are doing above. While modeling web pages as Page Object classes, finding and identifying elements can often become a chore. With Google Chrome or Firefox’s debugging tools, this can be made easier. By right clicking on any element on a page, you can activate the “Inspect Element” option from the context menu to find out detailed information about the element.

One common (and my preferred) way is to find elements using Firefox’s FireBug extension, in combination with Firefox web driver in Selenium. After installing and enabling FireBug extension, you can right click on the page and select “Inspect element with FireBug” to open FireBug. From the HTML tab of FireBug, you can copy the XPath, CSS Path, Tag name or “Id” (if available) of any element on the page.

clip_image004

By copying the XPath of the element in the screenshot above, we can create a WebElement field for it in our Page Object as follows:
@FindBy(xpath = “/html/body/div[1]/div/div/header/div/h1”)
WebElement heading;
Or to keep things simple, we can use the tag name “h1” here, as long as it uniquely identifies the element we are interested in:

@FindBy(tagName = "h1")
WebElement heading;
DeveloperPortalPage Page Object

Next, we need a Page Object that represents the developer portal page, one that we can reach by clicking on the “Apply As A Developer” button.

On this page, we have two elements of interest. To determine if the page has loaded, we want to verify the existence of the heading. And we also want a WebElement field for the “Join Toptal” button.

package com.toptal.webpages;
 
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
 
public class DeveloperPortalPage {
   private WebDriver driver;
 
   @FindBy(xpath = "/html/body/div[1]/div/div/header/div/h1")
   private WebElement heading;
 
   @FindBy(linkText = "JOIN TOPTAL")
   private WebElement joinToptalButton;
 
   //Constructor
   public DeveloperPortalPage (WebDriver driver){
       this.driver=driver;
 
       //Initialise Elements
       PageFactory.initElements(driver, this);
   }
 
   //We will use this boolean for assertion. To check if page is opened
   public boolean isPageOpened(){
       return heading.getText().toString().contains("Developer portal");
   }
 
   public void clikOnJoin(){
       joinToptalButton.click();
   }
}
DeveloperApplyPage Page Object

And finally, for our third and last page object for this project, we define one that represents the page containing developer application form. Since we have to deal with a number of form fields here, we define one WebElement variable for every form field. We find each field by their “id” and we define special setter methods for every field that simulate keystrokes for the corresponding fields.
package com.toptal.webpages;
 

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
 
public class DeveloperApplyPage {
   private WebDriver driver;
 
   @FindBy(tagName = "h1")
   WebElement heading;
 
   @FindBy(id="developer_email")
   WebElement developer_email;
 
   @FindBy(id = "developer_password")
   WebElement developer_password;
 
   @FindBy(id = "developer_password_confirmation")
   WebElement developer_password_confirmation;
 
   @FindBy(id = "developer_full_name")
   WebElement developer_full_name;
 
   @FindBy(id = "developer_skype")
   WebElement developer_skype;
 
   @FindBy(id ="save_new_developer")
   WebElement join_toptal_button;
 
 
   //Constructor
   public DeveloperApplyPage(WebDriver driver){
       this.driver=driver;
 
       //Initialise Elements
       PageFactory.initElements(driver, this);
   }
 
   public void setDeveloper_email(String email){
       developer_email.clear();
       developer_email.sendKeys(email);
   }
 
   public void setDeveloper_password(String password){
       developer_password.clear();
       developer_password.sendKeys(password);
   }
 
public void  setDeveloper_password_confirmation(String password_confirmation){
       developer_password_confirmation.clear();
       developer_password_confirmation.sendKeys(password_confirmation);
   }
 
   public void setDeveloper_full_name (String fullname){
       developer_full_name.clear();
       developer_full_name.sendKeys(fullname);
   }
 
   public void setDeveloper_skype (String skype){
       developer_skype.clear();
       developer_skype.sendKeys(skype);
   }
 
   public void clickOnJoin(){
       join_toptal_button.click();
   }
   public boolean isPageOpened(){
       //Assertion
       return heading.getText().toString().contains("Apply to join our network as a developer");
   }
}
Writing a Simple Test

With Page Object classes representing our pages, and user interactions as their methods, we can now write our simple test routine as a series of simple method calls and assertions.

package com.toptal.tests;
 
import com.toptal.webpages.DeveloperApplyPage;
import com.toptal.webpages.DeveloperPortalPage;
import com.toptal.webpages.HomePage;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
 
import java.net.URL;
import java.util.concurrent.TimeUnit;
 
public class ApplyAsDeveloperTest {
   WebDriver driver;
 
   @Before
   public void setup(){
       //use FF Driver
       driver = new FirefoxDriver();
       driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
   }
 
   @Test
   public void applyAsDeveloper() {
       //Create object of HomePage Class
       HomePage home = new HomePage(driver);
       home.clickOnDeveloperApplyButton();
 
       //Create object of DeveloperPortalPage
       DeveloperPortalPage devportal= new DeveloperPortalPage(driver);
 
       //Check if page is opened
       Assert.assertTrue(devportal.isPageOpened());
 
       //Click on Join Toptal
       devportal.clikOnJoin();
 
       //Create object of DeveloperApplyPage
       DeveloperApplyPage applyPage =new DeveloperApplyPage(driver);
 
       //Check if page is opened
       Assert.assertTrue(applyPage.isPageOpened());
 
       //Fill up data
       applyPage.setDeveloper_email("dejan@toptal.com");
       applyPage.setDeveloper_full_name("Dejan Zivanovic Automated Test");
       applyPage.setDeveloper_password("password123");
       applyPage.setDeveloper_password_confirmation("password123");
       applyPage.setDeveloper_skype("automated_test_skype");
 
       //Click on join
       //applyPage.clickOnJoin(); 
   }
 
    @After
    public void close(){
          driver.close();
       }
   }
Running the Test

At this point, your project structure should look like this:

clip_image005

If you want to run the test, select “ApplyAsDeveloperTest” from the tree, right click on it and then select Run ‘ApplyAsDeveloperTest’.

clip_image006

Once the test has been run, you can see the results in the lower-left corner of your IDE:

clip_image007

Conclusion

Page Object and Page Factory make it easy to model web pages in Selenium and test them automatically and make the life of both developers and QAs much more simpler. When done right, these Page Object classes can be reused across your entire test suite and to give yourself the opportunity to implement automated Selenium tests for your projects early on, without compromising agile development. By abstracting away user interactions in your page object models and keeping your test routines light and simple, you can adapt your test suite to changing requirements with little effort.

I hope I have managed to show you how to write nice and clean test code that is easy to maintain. I will end the article with my favorite QA quote:

Think twice, code once!

This article originally appeared on Toptal.

Recording Selenium Test Execution

After long time, got few min to think about new blog. There are many blog available for each and every solution but I was thinking to have few which is either not available or very limited information available over internet. I have free version of sauce lab and I am always fascinated by this kind of tool and I would love to build such tool sometime in future. There is one feature that is recording the session is always attracted me. I tried to find some resources which can help me to achieve so in my framework.

I found Microsoft expression encoder to do recording your screen. You can use their dlls to add into your C# based framework to execute and record the session. In you framework you can write a method which starts recording since beginning and later during cleanup task, you can have some login to determine if you want to save recording or not. For example, I my framework, I start recording based on my configuration file and in teardown methods, I check if there is an error or not. if yes then I encode into wmv format else I discard recording.




Follow following steps to have code and settings into framework:

Step 1:

Install Microsoft Encoder Expression: Refer CerebrumLabs.com for that (http://www.cerebrumlabs.com/free-screen-recording-software/). Once you install, you may get following folder in installation location. C:\Program Files (x86)Microsoft Expression. If you try to explore few folders inside this folder you will find SDK folder @: C:\Program Files (x86)\Microsoft Expression\Encoder 4\SDK, where you can see Microsoft.Expression.Encoder.dlls which you can use in your framework code.

Step 2:

Include dlls given in SDK folders into your framework. You can write a method and call that. I have a key value pair in my framework config file and I can decide if I want to do recording or not.  In your test’s [setup] method, you can call this method which will start recording at the beginning of the test.

using System;

.

.

using OpenQA.Selenium;

.

.

using Microsoft.Expression.Encoder.ScreenCapture;

using System.Drawing;

using Microsoft.Expression.Encoder.Profiles;

using Microsoft.Expression.Encoder;

namespace FRAMEWORK

{

    //Call this method in setup method.   
    public static void StartRecordingVideo()

    {

        //Provide setting in config file if you want to do recording or not.
        if (testEInfo.isRecording)

        {

            job = new ScreenCaptureJob();

            job.CaptureRectangle = Screen.PrimaryScreen.Bounds;

            job.ShowFlashingBoundary = true;

            //provide the location where you want to save the recording.
            job.OutputPath = AutomationLogging.newLocationInResultFolder;

            job.Start();

        }

    }

}

Step 3:

Now your test started and in the background your screen recording going on. once you reach to the [teardown] method. you can decide if you want to keep the recording or not. In my case I want to keep recording only if there is test failure so my developers can review else there is no point of having recording if tests are passing. To do so I have following method in above code which I call in code at the very end.

public static void StopRecordingVideo()
        {
            if (testEInfo.isRecording)
            {
                string filename = job.ScreenCaptureFileName;
                job.Stop();
                if (AutomationLogging.countOfError > 0)
                {
                    MediaItem src = new MediaItem(filename);
                    Job jb = new Job();
                    jb.MediaItems.Add(src);
                    jb.ApplyPreset(Presets.VC1HD720pVBR);
                    jb.OutputDirectory = AutomationLogging.newLocationInResultFolder;
                    string output = ((Microsoft.Expression.Encoder.JobBase)(jb)).ActualOutputDirectory;
                    jb.Encode();
                }

                File.Delete(filename);
            }
        }

Conclusion:

during encoding, you may notice that encoder is eating little more memory and you system may little slow. Try at your end and let me know if you have any question.

Learning NUnit In Easy Way For Beginners

NUnit is a test framework for all Microsoft .Net language. NUnit is derived from JUnit, a unit test framework for Java. It is written in C# and helps you to execute unit tests for code written in .net. At the time of writing this article, the most recent version of NUnit was 2.6.2. NUnit supports many features but in this article I explain only those features which are actually required by black box testers. I intend to write another article on advanced NUnit where I will cover the features in depth.

GETTING STARTED:

Let’s write a simple banking program.

namespace Banking
{
 public class Banking
 {
 private double balance;
 public Banking()
 {
 balance = 0;
 }
 public void DepositMoney(double depositAmount)
 {
 balance += depositAmount;
 }
 public double WithdrawMoney(double withdrowAmount)
 {
 balance -= withdrowAmount;
 return balance;
 }
 }
}

If I ask you to write unit test for this program, you may write like this:

namespace Banking
{
 public class BankingTest
 {
 public void TestBankingTransfers()
 {
 Banking banking = new Banking();
 banking.DepositMoney(300);
 banking.DepositMoney(100);
 double remainingBal = banking.WithdrawMoney(200);
 if (remainingBal == 200)
 {
 Console.WriteLine("Test working");
 }
 }
}

But the biggest problem with this approach lies in identifying and running the tests in a simple way. We can write a unit test case like the one mentioned above but what if we want to execute this test for another set of input? We cannot write the same test in a loop or make our test more complex. In this case, we need to use a test framework which was designed to test the code at the unit level with less hassle.



This is where NUnit comes into picture. The same code will now look like this:

using NUnit.Framework;
namespace Banking
{
 [TestFixture]
 public class BankingTest
 {
 [Test]
 public void TestBankingTransfers()
 {
 Banking banking = new Banking();
 banking.DepositMoney(300);
 banking.DepositMoney(100);
 double remainingBal = banking.WithdrawMoney(200);
 //if (remainingBal == 200)
 //{
 //Console.WriteLine("Test working");
 Assert.AreEqual(200, remainingBal, "Method is returning correct value");
 //}
 }

}
}

Comparing both solutions you will find that we used the reference unit.framework namespace. We used various attributes to write test classes and tests.

Use [TestFixture] attribute before the class where you write test method. And [Test] attribute before The test method. If you look at the code, ‘BankingTest’ is the test class and TestBankingTransfers() is a test method. To verify, you can use Assert.AreEqual method. NUnit.Framwork provides various flavors of Assert. Till now, we have learned how to write the basic test in Nunit. In the next section, I will go into details of the test. I will also show you how to execute tests.

HOW TO EXECUTE TESTS:

There are two different ways to run your tests. You can run on the command line using ‘nunit-console.exe’, which is quite fast to launch, or use GUI application ‘nunit.exe’, which is windows standalone application and allows you to execute test selectively.

INSTALLATION:

Go to http://nunit.org/index.php?p=download and choose compatible version preferred win: Nunit-2.x.x.msi version and install. By default NUnit will install in C:\ProgrameFiles \NUunit2.x.x directory. You will see folders like bin, doc. In the doc folder, you can get the whole documentation of unit by opening index.html in offline webpage format.

Go to the bin folder and you will see nunit.exe. This is a GUI application. The folder named “framework” contains nunit.framework.dll which we will add in our test as a reference library (explained in a later sections).

WRITING TESTS:

Before starting writing tests using NUnit, we need to understand about few terminologies of NUunit.

1. ATTRIBUTES: indicate test classes and methods and to modify their behavior in different ways.

2. ASSERTIONS: test an actual value against expected values and report as pass or fail.

3. CONSTRAINTS: used for assertion i.e. Assert.That( myString, new EqualConstraint(“Hello”) );

4. TEST CONTEXT: helps code to get information about the test environment.

ATTRIBUTES:

Attributes are a vital part of Unit framework which we use to identify test classes and test methods. They can be found in NUnit.Framework namespace. Each source file that contains tests must call this namespace using nunit.Framework; statement. And for this, you need to add unit.Framework.dll first in your reference.

In Nunit 2.x.x versions, the NUnit is designed in such a way that you are free to use it anywhere ie. your inherit class can also use these attributes.

Although there are many attributes, we will cover the important ones here.

1. TestAttribute => [Test]

The [Test] attribute is a way to mark  method inside a [TextFixture] class as test method. NUnit will recognize inline method as test method and execute that. Refer to the following code.


using System;

using NUnit.Framework;

namespace Banking

{

class KeyBankTests

{

[Test]

public void TestBankingTransfers()

{

Console.WriteLine("Test: Start Testing Transfer");

}

}

}

Sample NUnit.exe Application
Sample NUnit.exe Application

You can parameterize the test method using various attributes.

I will walk you through other attributes like [TextFixture] one by one in more detail.

2. SetupAttribute => [SetUp]

This attribute is to mark a method inside [TestFixture] class which we want to execute before executing each Test method. If there are more than one test, then setup method will execute just before executing test.

If a SetUp method fails or throws an exception, the test will stop and report a failure or an error.


using System;

using NUnit.Framework;

namespace Banking

{

class KeyBankTests

{

[Test]

public void TestBankingTransfers()

{

Console.WriteLine("Start Testing Transfer");

}

[SetUp]

public void OpenBank()

{

Console.WriteLine("Open Bank in Before Test");

}

}

}

[Setup] Attribute
Code inside [Setup] attribute executed before [Test].
 If you look at the output printed on NUnit Test Output screen, you will see [SetUp] method executed before [Test] method.

3. TearDownAttribute => [TearDown]

This attribute is to mark a method inside [TestFixture] class which we want to execute after executing each Test method. Once SetUp and Test are executed, TearDown test is executed. If you have more than one test, they will be executed in the following order;

SetUp > Test1 > TearDown SetUp Test2 > TearDown

As long as SetUp method runs without any error, it is guaranteed that TearDown test will execute. It will not run if Setup throws an Exception.


using System;

using NUnit.Framework;

namespace Banking

{

class KeyBankTests

{

[Test]

public void TestBankingTransfers()

{

Console.WriteLine("Test: Start Testing Transfer");

}

[SetUp]

public void OpenBank()

{

Console.WriteLine("Setup: Open Bank in Before Test Execution");

}

[TearDown]

public void CloseBank()

{

Console.WriteLine("TearDown: Close Bank after Test Execution");

}

}

}

 

setupTestTearDown

4. TestFixtureAttribute => [TestFixture]

This attribute assigns a class that contains tests and optionally, setup or teardown methods which we learned in the previous section.

You need to take care of certain rules before assigning a class as [TestFixture].

  • Class may be with any access modifier(public, private, protected or internal).
  • Class may be static in .NET 2.0+.
  • A class cannot be abstract.
  • TextFixture with no argument is provided if that class has a default constructor.
  • If arguments are provided then they must match one of the constructors.

1. Non-Parameterized Text Fixture:

TextFixture attribute is optional for non-parameterized fixture. As long as the class contains at least one method marked with the [Test], [TestCase] or [TestCaseSource] attribute, this class will be treated as a [TestFixture].

e.g.:

<b></b>

using System;

using NUnit.Framework;

namespace Banking

{

[TestFixture]

class KeyBankTests

{

[Test]

public void TestBankingTransfers()

{

Console.WriteLine("Test");

}

}

}

[TestFixture] Attribute
[TestFixture] Attribute

2. Parameterized Text Fixture:

Beginning with version 2.5, test fixtures may take constructor argument. Argument values of TestFixture should match with the constructor of test class. NUnit will construct a separate constructor based on the parameter provided in TestFixture.

e.g.:


using System;

using NUnit.Framework;

namespace Banking

{

[TestFixture(2,4)]

class KeyBankTests

{

private int x;

private int y;

public KeyBankTests(int a, int b)

{

x = a;

y = b;

}

[Test]

public void TestBankingTransfers()

{

Console.WriteLine(x + "  "+ y);

}

}

}

Parameterized TestFixture Attribute
Parameterized TestFixture Attribute

5. TestFixtureSetUpAttribute => [TestFixtureSetUp]

This attribute is used inside TestFixture to assign a method which needs to run before any tests or methods get executed.
If a TestFixtureSetup method fails or throw an exception, none of the tests in TestFixture will execute and reports a failure or an error.

using NUnit.Framework;
using Assert = NUnit.Framework.Assert;
namespace Banking
{
    [TestFixture(200,100)]
    public class ChaseBankingTest
    {
        private double a;
        private double b;
        public ChaseBankingTest(double x, double y)
        {
            a = x;
            b = y;
        }
        [TestFixtureSetUp]
        public void TestFixtureSetUp()
        {
            System.Console.WriteLine("TestFixtureSetUp");
        }
        [Test]
        public void TestBankingTransfers()
        {
           Banking banking = new Banking();
           banking.DepositMoney(a);
           banking.DepositMoney(a);
           double remainingBal = banking.WithdrawMoney(b);
           Assert.AreEqual(300, remainingBal, "Method is returning incorrect value");
        }
        [Test]
        public void TestBankingTransfers2()
        {
            System.Console.WriteLine("Test2");
        }
        [Test]
        public void TestBankingTransfers3()
        {

            System.Console.WriteLine("Test3");
        }
        [SetUp]
        public void setup()
        {
            System.Console.WriteLine("Setup");
        }

    }
}

TestFixtureSetup

6. TestFixtureTearDownAttribute => [TestFixtureTearDown]

This attribute is used inside TextFixture to provide a single set of functions that are performedafter all tests are executed.

using NUnit.Framework;
namespace Banking
{
    [TestFixture(200,100)]
    public class PncBankingTest
    {
        private double a=0;
        private double b=0;
        public PncBankingTest(double x, double y){a = x;b = y;}
        [Test]
        public void TestBankingTransfers2()
        {
            System.Console.WriteLine("Actual Test method: TestBankingTransferTest1\n");
        }
        [Test]
        public void TestBankingTransfers1()
        {
            System.Console.WriteLine("Actual Test method: TestBankingTransferTest1\n");
        }
        [SetUp]
        public void InitStep()
        {
            System.Console.WriteLine("Setup Test method: InitStep\n");
        }
        [TestFixtureSetUp   ]
        public void DeletePreCondItems()
        {
            System.Console.WriteLine("TestFixtureSetUp Method: DeletePreCondItems\n");
        }
        [TestFixtureTearDown]
        public void CleanUpAll()
        {
            System.Console.WriteLine("TestFixtureTearDown Method: CleanUpAll\n");
        }
    }
}

 


If you look at the code there are two Test methods and steps of execution look like this.

[TestFixtureTearDown] executes in the last
[TestFixtureTearDown] executes in the last

7. CategoryAttribute => [Category(“Some Name“)]

Category attribute provides an alternative way to group the tests in suites. You can categorize test methods or TextFixtures in various groups and while running test suite you can selectively choose tests based on the category. Use category attribute as follows.

using NUnit.Framework;
namespace Banking
{
    [TestFixture(200,100)]
    public class ChaseBankingTest
    {
        private double a;
        private double b;
        public ChaseBankingTest(double x, double y)
        {
            a = x;
            b = y;
        }
        [Test]
        [Category("US Market")]
        public void TestBankingTransfers1()
        {
            System.Console.WriteLine("Test for US market");
        }
        [Test]
        [Category("UK Market")]
        public void TestBankingTransfers2()
        {
            System.Console.WriteLine("Test for UK market");
        }
    }
}

Categories1

Categories2

There are many more test attributes which I will cover later in WhiteBox testing section. For now, this information should be sufficient for beginners.

ASSERTION:

Assertion is the core of any unit test framework and NUnit is no exception. NUnit provides static methods in asserting class.

If an assertion fails, the method call does not return butreports a failure. Additionally, failure of one assertion terminates the execution of any subsequent assertions. For this reason, it is not recommended to use more than one assert per test method.

Equality Asserts:

These methods test whether two items are equal. Overloaded methods are provided to test various input values like string, int, double, decimal etc. so other languages can use as required.
Eg.

Assert.AreEqual( int expected, int actual );
Assert.AreEqual( int expected, int actual, string message );
Assert.AreNotEqual(int expected, int actual, string message, params object[] parms )

You can explore others in visual studio using intellisense.

Condition Asserts:

These methods test condition provided in first arguments. And optionally other arguments for message.
Few important condition asserts are as follows.
Eg.

Assert.IsTrue( bool condition );
Assert.True(bool condition)
Assert.IsEmpty( string aString );

You can explore others in visual studio using intellisense.

Comparison Asserts:

These methods compare if one object is greater than other one. There are four types of comparison assertion.
Eg.

Assert.Greater( int arg1, int arg2 );
Assert.GreaterOrEqual( int arg1, int arg2 );
Assert.Less( int arg1, int arg2 );
Assert.LessOrEqual( int arg1, int arg2 );
It compares the first argument with the other. Assert.LessOrEqual( 3, 4 ); is true.

You can explore other arguments in visual studio using intellisense.

This is good for reference. We will go into more details in White Box Testing section.

RUNNING TESTS:

There are two ways to execute tests .
Console Runner: nunit-console.exe to execute tests in batch.
And GUI Runner: nunit.exe, provides an interactive way to select test or category before running. You can see the result and command and code from UI. GUI Runner is a bit slower than console runner but has a better way to handle tests.

There are other ways to execute tests using third party sortware or directly from Visual Studio but here we will talk about only above two methods.

Console Runner:

Console Runner is the fastest way to execute unit tests. It is a text based test execution tool and is used when you want to execute all the tests and do not want the interactive icons to get status for passed/failed tests.

Console Runner
Console Runner

I enabled all tests and executed using above command nunit-console ‘Test dll file’ in screenshot.

Note: It’s recommended that you add the path of Nunit-console executable into your PATH variable so you do not need to navigate there every time. You can directly execute tests without any hassle.

Use the following command to get all the options to use console runner:

Nunit-console.exe /help

I will just talk about the important option which we need to execute our tests.

Specify an Assembly:

Assemblies contains test codes ie. to run the tests contained in the Banking.dll, use the following command:

Nunit-console <Assembly Name > 

specifyAssembly

Specify an Assembly and a Test to Run:

If you want to execute a specific test from a set of tests given in assembly, you need to use

/run:<Testname> command with above command

           Nunit-console /run:TestBankingTransfersUs Banking.dll

GUI RUNNER:

Nunit.exe is gui runner for tests where you can perform selective testing. You will get result in very fancy way by seeing grean red or yellow icons. A progress bar tells the status of your tests execution.

To select the tests, you need to locate the test assembly and click on Run button on the right column.


GUIRunner

I would like to mention a few things here

 Progress Bar:

The progress bar tells you the overall status of tests. If all tests are passed, it’s green but even if a single test fails, it will be red and if you get a single warning, the bar will turn into yellow.

ProgressBar

Result Summary:

At the end of the test run, summary of the test result will display below the progress bar.

ResultSummary

Error And Failures Tab:

In case if some tests fail, you will get the summary of tests failure and details in this tab. First columnshows which method failed and right side shows the exact code which caused the failure.

Error And Failures Tab

 Text Output tab:

If you are sending output on to the console you will see the output on this tab.. You can see what tests are running etc.

Text Output tab 

Footer Summary:

You can see the summary at the bottom about the number of testcases, error failures etc.

FooterSummary

Category Tab:

Click on the Category tab on left side below Tests. If your tests have category attribute, those will appear here. You can select and click on Add to select the category or double click. Selected category will move to ‘Selected Categories’ section and if you move back to Tests tab, you will see all tests become inactive but the selected categories.

CategoryTab

If you hit the Run button only selected will execute.

You can do all above via the command line like launching GUI runner, selected tests and selecting categories etc.

Go to command line and type nunit /? You will get various options and description to that you execute the test.

NUnitGuide

I hope you liked this article. Don’t forget to leave you comment below. If you have any question please let me know. Or email me learn@learnseleniumtesting.com. I will be more than happy to respond.