Designing an automation framework – Part 3

All about NUnit. How to use it. We are covering all the important aspects of the automation framework we want to design first and then we would code and utilize it. I would be providing the PDF version of this article at the end of the series and access to some code so you can start your own framework.

NUnit Quick Primer

NUnit is basically composed of attributes, or annotations. These indicate to the framework to execute the tests that are implemented in the class, and also how to interpret them. Annotations tell the framework how to interpret the code. NUnit tests also include assertions that allow checking and comparing values.

Important NUnit Attributes

The annotations are very easy to use: just add the annotation between brackets before the method declaration. With the annotation you can define the test: behavior (specifying Setup or TearDown method), assertions for example performance assertions like MaxTime method, and information like the Category method. To understand the annotations, please go through the sample test cases in this document. NUnit also provides us with several annotations to parametrize our tests. This functionality can be used with the annotations [TestCase ] and [TestCaseSource]

Sample Attribute  Syntax:

[Test, Order(1), **DeleteCosmosDocuments**, Category("CardPayments"), Description("Check whether successful notification is showed after card payment was done"), Retry(1)]
AnnotationUsageCommnets/Description
CategorySpecifies one or more categories for the testCategorizes the test cases or classes. Category separation is a best practice on testing because you could see your test cases by its category on your test runner tool or run them in a Continuous Integration application seperately.
CultureSpecifies cultures for which a test or fixture should be run 
IndicatesIndicates that a test should be skipped unless explicitly run 
IgnoreIndicates that a test shouldn’t be run for some reasonIgnores the test case.
MaxTimeSpecifies the maximum time in milliseconds for a test case to succeed 
OneTimeSetUpIdentifies methods to be called once prior to any child testsThe one time triggered method before test cases start.
OneTimeTearDownIdentifies methods to be called once after all child testsThe one time triggered method after test cases end.
PlatformSpecifies platforms for which a test or fixture should be run 
RandomSpecifies generation of random values as arguments to a parameterized test 
RepeatSpecifies that the decorated method should be executed multiple times 
RetryCauses a test to rerun if it fails, up to a maximum number of times 
TearDownIndicates a method of a TestFixture called immediately after each test methodThis is an annotation that acts the opposite of [SetUp]. It means the code written with this attribute is executed last (after passing other lines of code). Typically in our case we use it with CloseTestExecution() method. Triggered after every test case.
TestMarks a method of a TestFixture that represents a testMarks a test case.
TestCaseMarks a method with parameters as a test and provides inline argumentsThis annotation replaces the annotation Test we saw before, and allows creating a set of tests that execute the same code with different data inputs.  Example:    [TestCase(“user1”, “Welcome user1”)]     [TestCase(“user2”, “Invalid User”)]     [TestCase(“user3”,”Not Registered User”)]       public void testLogin(string user, string pw){}   In this example we defined that the test testLogin runs 3 times, and in each execution the data input is specified in the annotation of our Test Case.    
TimeoutProvides a timeout value in milliseconds for test cases 
SetUpIndicates a method of a TestFixture called immediately before each test methodWe generally use this for code that needs to be executed before executing a test, with the purpose to not repeat the code in each test. Every test inherited in the [SetUp] annotation with the Initialize() method will be used to decide which browser to use, to open the test and to maximize the window.
[TestCaseSource]This annotation is similar to TestCase annotation and it’s used when the list of records is too big.It takes a public static property that it provides in every entry record. This allow us to load our record from a .csv file or from a database.  Example: [TestCaseSource(“TestCases”)]    public void testLogin(string user, string pw){}   In this case the script testLogin takes as data input every record that is stored in the property TestCases.  TestCases method return the data type TestCaseData that can hold any type of data and expected results  
[TestFixture]Indicates that the class has test methods. The [TestFixture] attribute denotes a class that contains unit tests also.Multiple parameters that represent the browser, browser version, & platform are passed to the TestFixture class. The TestFixture class is a part of the NUnit.Framework.Internal namespace.   [TestFixture(“chrome”, “72.0”, “Windows 10”)] [TestFixture(“internet explorer”, “11.0”, “Windows 10”)] [TestFixture(“Safari”, “11.0”, “macOS High Sierra”)] [TestFixture(“MicrosoftEdge”, “18.0”, “Windows 10”)]
[Parallelizable(ParallelScope.All)]Allows runnig tests in parallel. Parallel Testing should be used when testing is performed on a remote Selenium Grid since it reduces the overall execution time thereby shortening the release cycles. The ThreadLocal class that belongs to the System.Threading namespace provides thread-local storage of data. The instance of IWebDriver is the data that is stored per-thread. For usage with syntax like below:   public class ParallelLTTests     {         ThreadLocal<IWebDriver> driver = new ThreadLocal<IWebDriver>();  

Attribute parameters

Many attributes have parameters, which can be positional, unnamed, or named. Any positional parameters must be specified in a certain order and cannot be omitted. Named parameters are optional and can be specified in any order. Positional parameters are specified first. For example, these three attributes are equivalent:

Example:

[DllImport(“user32.dll”, SetLastError=false, ExactSpelling=false)]

[DllImport(“user32.dll”, ExactSpelling=false, SetLastError=false)]

Dhakate Rahul

Dhakate Rahul

One thought on “Designing an automation framework – Part 3

Leave a Reply

Your email address will not be published. Required fields are marked *