NUnit Tutorial: Parameterized Tests With Examples
Himanshu Sheth
Posted On: December 2, 2020
161210 Views
14 Min Read
This article is a part of our Content Hub. For more in-depth resources, check out our content hub on Selenium NUnit Tutorial.
Cross browser testing has become an integral part of the test process to ensure the product experience and behavior remains consistent across different combinations of web browsers, devices, and operating systems. As testing has to be performed on varied combinations, it can lead to code duplication as a lot of test methods will be doing the same thing but on different input combinations. I have come across many such situations during the code optimization process when I felt that a part of the code is either duplicated or redundant.
One important lesson I learned from these situations is that you should never leave such activities for the future as it becomes more challenging to optimize with the increase in LOC (Lines of Code). This is where a parameterized test can be beneficial as it enables testing the code/methods against different input values. Test parameterization should be explored in cross browser testing as the same tests need to be executed on different web browsers and different versions of the same web browser. In this blog, we learn how to execute NUnit parameterized tests with examples. If you’re looking to improve your NUnit interview skills, check out our curated list of NUnit interview questions and answers.
TABLE OF CONTENT
What Is Parameterization In NUnit?
NUnit is a popular C# testing framework extensively employed for cross-browser testing, owing to its seamless integration with the Selenium test suite. Starting from NUnit 2.5, it has offered support for parameterized tests, allowing test methods to accept parameters. Various NUnit attributes facilitate the indication of which arguments the framework should provide. While some attributes permit specifying arguments directly within the method, others utilize a separate method or field for this purpose.
We will use Visual Studio 2019 (Community Edition) for development, which can be downloaded from here.
Note: This blog will only focus on creating NUnit parameterized test examples that will aid you in the process of cross browser testing or automated browser testing.
NUnit Parameterized Tests (Or Data-Driven Tests)
Parameterization of NUnit tests was introduced with version 2.5 (as mentioned above) and is considered extremely useful when used with the Selenium WebDriver. Using special attributes in NUnit, you can develop foolproof tests by verifying them on different browsers, browser versions, and platforms, which can be passed as parameters to the test.
To demonstrate an NUnit parameterized test example, we perform the test mentioned below:
- Open DuckDuckGo in the intended web browser.
- Locate the search box.
- Enter search query i.e., LambdaTest.
- Execute the search operation.
- Free up the resources.
You can refer to our detailed article on NUnit, which walks you through the implementation of executing the above mentioned test without parameterization.
Cross browser testing on the local Selenium grid can hit a roadblock as it is not feasible to have an in-house setup with different combinations of browsers, platforms, and devices.
Using a local Selenium grid for cross browser testing can lead to a reduction of test coverage. Instead, cross browser testing should be performed on cloud-based cross browser testing platforms like LambdaTest, where testing can be performed on 3000+ browsers, thereby providing wider test coverage.
To get started, you should create an account on LambdaTest and note the user-name & access-key from the Profile Page. Desired capabilities can be generated using LambdaTest Capabilities Generator, and these capabilities enable to execute tests using different browser + OS combinations on remote Selenium grid. Along with parameterization, the prerequisite is that the tests have to be executed in parallel to complete test execution within a shorter time. With my current plan, I can execute five tests in parallel on the remote Selenium Grid on LambdaTest.
Let’s explore the different attributes in NUnit using which we can come up with an NUnit parameterized test:
Take this certification to master the fundamentals of Selenium automation testing with C# and prove your credibility as a tester.
Here’s a short glimpse of the Selenium C# 101 certification from LambdaTest:
TestCase Attribute
The TestCase attribute in NUnit marks a method with parameters as a test method. It also provides the inline data that needs to be used when that particular method is invoked. It can appear one or more times on the test method, with each appearance carrying values for the test case. Make more copies of the attribute if you want multiple cases. The data type of the values provided to the TestCase attribute should match with that of the arguments used in the actual test case.
This attribute that helps in coming up with an NUnit parameterized test also supports several additional named parameters like Author, Category, Description, ExpectedResult, TestName, etc. The execution order of the TestCase attribute can vary when used in combination with other data-providing attributes.
Demonstration – [TestCase] Attribute
The search for ‘LambdaTest’ on DuckDuckGo is carried out on the following browser + OS combinations.
The complete implementation is below:
Code WalkThrough
Step 1 – The data of IWebDriver is stored per-thread basis, and that is the reason for using the ThreadLocal class.
1 2 3 |
public class ParallelLTTests { ThreadLocal driver = new ThreadLocal(); |
Step 2 – The input combinations of browser, version, and platform constitute the parameters for the test case. These are supplied via the TestCase attribute. As the test has to be performed on four combinations, there are four occurrences of the attribute. The TestCase attribute is under the Test attribute, which defines the start of a test case.
As we want the test and its descendants to execute in parallel with other tests at the same level, ParallelScope is set to All using the Parallelizable attribute.
1 2 3 4 5 6 |
[Test] [TestCase("chrome", "72.0", "Windows 10")] [TestCase("internet explorer", "11.0", "Windows 10")] [TestCase("Safari", "11.0", "macOS High Sierra")] [TestCase("MicrosoftEdge", "18.0", "Windows 10")] [Parallelizable(ParallelScope.All)] |
Step 3 – We have not used the SetUp attribute as the steps being performed as a part of that attribute, i.e., creating instances of a remote Selenium WebDriver, setting browser capabilities, etc., are shifted to the TestCase attribute.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public void DuckDuckGo_TestCase_Demo(String browser, String version, String os) { String username = "user-name"; String accesskey = "access-key"; String gridURL = "@hub.lambdatest.com/wd/hub"; DesiredCapabilities capabilities = new DesiredCapabilities(); capabilities.SetCapability("user", username); capabilities.SetCapability("accessKey", accesskey); capabilities.SetCapability("browserName", browser); capabilities.SetCapability("version", version); capabilities.SetCapability("platform", os); |
Step 4 – The search box on DuckDuckGo is located using the XPath locator, for which we made use of the browser’s Inspect Tool. A search term is entered in the search box to perform the search operation.
1 2 3 4 5 6 7 8 |
driver.Value.Url = "https://www.duckduckgo.com"; IWebElement element = driver.Value.FindElement(By.XPath("//*[@id='search_form_input_homepage']")); element.SendKeys("LambdaTest"); /* Submit the Search */ element.Submit(); |
Step 5 – The resources used by the Selenium WebDriver instance is released as part of the TearDown attribute.
1 2 3 4 5 6 7 8 |
[TearDown] public void Cleanup() { ................... ................... // Terminates the remote webdriver session driver.Value.Quit(); } |
As seen in the execution snapshot, the data passed in the TestCase attribute is used as parameters for executing tests in DuckDuckGo_TestCase_Demo(String browser, String version, String os).
As parallelism is enabled, the DuckDuckGo_TestCase_Demo test is executed on four different input combinations (supplied via the TestCase attribute) in one shot.
This NUnit Tutorial for beginners and professionals will help you learn how to use NUnit framework with Selenium C# for performing Selenium automation testing.
TestCaseSource Attribute
The TestCaseSource attribute can be applied to any test method, just like the TestCase attribute. The property, methods, or fields specified by the TestCaseSource attribute provide the arguments to the parameterized method. Unlike the TestCase attribute that is used to provide simple compile-time constants as parameters to the parameterized function, the TestCaseSource attribute can be used to provide more complicated parameter types.
The other major advantage of this attribute is that the source method is reusable across different tests. The object/data that is a part of the method using the TestCaseSource attribute can also be reused for multiple tests.
The source specified by the attribute can either return IEnumerable or a type that implements IEnumerable. For simple tests, object[] can be returned from the source. For more complicated tests, IEnumerable is used as the TestCaseData class provides additional test case information for a parameterized test, e.g., TestName, Result, ExpectedException, Properties, Result, etc.
For demonstrating the usage of TestCaseSource to create an NUnit parameterized test, the source method uses IEnumerable to provide values to the parameterized function.
Demonstration – [TestCaseSource] Attribute
We use the same test case that was used to showcase the usage of the TestCase attribute, i.e., a search for ‘LambdaTest’ is performed on the following browser and OS combinations.
The complete implementation is below:
Code WalkThrough
The core implementation that involves the following remains the same as the [TestCase] attribute:
- Invocation of Selenium WebDriver in the target web browser.
- Generation of browser capabilities.
- Performing a search on DuckDuckGo, and
- Releasing the resources used by the WebDriver instance as a part of the TearDown attribute.
You can refer to steps 1, 3, 4, and 5 from the ‘Code WalkThrough’ section of [TestCase] attribute for more detailed information on how the above requirements are implemented in the code.
As shown in the snippet below, AddBrowserConfs() is the source method that returns IEnumerable. The browser capabilities are passed to the parameterized function, i.e., DuckDuckGo_TestCaseSource_Demo(String browser, String version, String os) through the TestCaseData attribute.
The test case information provided via TestCaseData matches the argument type being used in DuckDuckGo_TestCaseSource_Demo, i.e., the arguments should be of type String.
The TestCaseSource attribute uses the AddBrowserConfs method to supply parameters to the test case DuckDuckGo_TestCaseSource_Demo.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
private static IEnumerable AddBrowserConfs() { yield return new TestCaseData("chrome", "72.0", "Windows 10"); yield return new TestCaseData("internet explorer", "11.0", "Windows 10"); yield return new TestCaseData("Safari", "11.0", "macOS High Sierra"); yield return new TestCaseData("MicrosoftEdge", "18.0", "Windows 10"); } ................... ................... [Test, TestCaseSource("AddBrowserConfs")] public void DuckDuckGo_TestCaseSource_Demo(String browser, String version, String os) { ................... ................... } |
As shown in the execution snapshot, the four tests are executed in parallel on LambdaTest’s remote Selenium grid. The browser capabilities are passed to DuckDuckGo_TestCaseSource_Demo using the TestCaseSource attribute that is used on AddBrowserConfs, a parameterized test method.
Interesting Read: Top 28 Selenium WebDriver Commands in NUnit
ValueSource Attribute
The ValueSource attribute functions similarly like TestCaseSource, except that it is used as a Method parameter.
Using the ValueSource attribute for creating parameterized tests in NUnit for cross browser testing does not sound convincing as a list of tests is prepared based on the values supplied via the ValueSource attribute. For example, the input values shown below generate four test cases, i.e., chrome 70.0, chrome 71.0, Firefox 70.0, and Firefox 71.0
1 2 3 4 5 6 7 8 9 |
private static string[] AddBrowserConfs = new string[] { "chrome", "Firefox" }; private static string[] AddVerConfs = new string[] { "70.0", "71.0" }; |
Demonstration – [ValueSource] Attribute
For demonstrating the usage of ValueSource attribute, a DuckDuckGo search for LambdaTest is performed on the following browser + OS combinations.
The complete implementation is shown below:
Code WalkThrough
There are no changes in the core implementation for invoking the WebDriver instance, generating the browser capabilities, performing DuckDuckGo search, and performing de-initialization. You can refer to steps 1, 3, 4, and 5 from the ‘Code WalkThrough’ section of the TestCase attribute for more information.
Three string arrays consisting of browser type, browser versions, and platforms are created. These arrays are then passed as individual parameters to the test method (DuckDuckGo_ValueSource_Demo) using the ValueSource attribute.
A total of eight test combinations are generated from the input values passed to the test method i.e. (chrome + 70.0 + Windows 10), (chrome + 71.0 + macOS Mojave), (Firefox + 70.0 + Windows 10), (Firefox + 71.0 + macOS Mojave), etc.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
private static string[] AddBrowserConfs = new string[] { "chrome", "Firefox" }; private static string[] AddVerConfs = new string[] { "70.0", "71.0" }; private static string[] AddOsConfs = new string[] { "Windows 10", "macOS Mojave" }; [Test] public void DuckDuckGo_ValueSource_Demo( [ValueSource("AddBrowserConfs")]String browser, [ValueSource("AddVerConfs")] String version, [ValueSource("AddOsConfs")] String os ) { ................... ................... }; |
The execution snapshot below shows that eight test combinations are created from the test parameters supplied through the ValueSource attribute.
TestFixture Attribute
The TestFixture NUnit attribute marks a class that contains tests. Parameterized and generic test fixtures were introduced in NUnit 2.5. For an NUnit parameterized test, argument values are passed to the TestFixture NUnit attribute. The NUnit framework constructs a separate instance of TestFixture for each set of arguments.
From NUnit 2.5, test fixtures can take constructor arguments. In the example shown below, the test fixture would be instantiated by the NUnit framework three times, passing each set of arguments to the appropriate constructor.
1 2 3 |
[TestFixture("chrome", "72.0", "Windows 10")] [TestFixture("internet explorer", "11.0")] [TestFixture("Safari", 11)] |
Demonstration – [TestFixture] Attribute
A search for ‘LambdaTest’ is performed on the following browser and OS combinations.
The complete implementation is below:
Code WalkThrough
Step 1 – The browser and platform combinations are specified as arguments to the TestFixture attribute.
1 2 3 4 5 |
[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)] |
Step 2 – The arguments supplied via the TestFixture NUnit attribute are passed to the constructor that has three parameters of type String.
1 2 3 4 5 6 |
public ParallelLTTests(String browser, String version, String os) { this.browser = browser; this.version = version; this.os = os; } |
Step 3 – The implementation related to the instantiation of WebDriver and setting up the capabilities for testing on the remote Selenium grid is added to the SetUp attribute.
1 2 3 4 5 6 7 8 9 10 11 |
[SetUp] public void Init() { String username = "user-name"; String accesskey = "access-key"; String gridURL = "@hub.lambdatest.com/wd/hub"; DesiredCapabilities capabilities = new DesiredCapabilities(); ................... ................... } |
Step 4 – The implementation of de-initialization remains unchanged and is included as a part of the TearDown attribute.
Shown below is the execution snapshot where it is observed that ParallelLTTests constructor is called four times, i.e., the number of times the TestFixture was instantiated by the NUnit framework.
Summary
In this blog, we had a look at some of the widely used attributes in the NUnit framework that are used for test parameterization, including TestFixture NUnit. Apart from the attributes that we covered in the blog, there are other attributes that aid in creating parameterized tests in NUnit framework. However, many of those NUnit attributes are not useful for test scenarios related to cross browser testing or automated browser testing.
Cross browser testing on the local Selenium grid is not scalable; hence, it is recommended to perform automated browser testing on a remote Selenium grid. When choosing an attribute for an NUnit parameterized test, you should also look at the complexities involved in adding/removing test cases. To summarize, NUnit parameterized tests are extremely useful in cutting down duplication in tests that can unnecessarily bloat the test code’s size.
I hope the NUnit parameterized test example I have showcased above will help make a difference in your test strategies!
Happy testing!
Frequently Asked Questions
Does NUnit run tests in parallel?
By default, no parallel execution can take place. The 3.0 version of the NUnit framework is capable of running tests in parallel within an assembly. To do so, you can use a separate facility from Engine Parallel Test Execution.
How NUnit is used in unit testing?
To use NUnit for unit testing with Selenium, we can use the Visual Studio IDE for development and execution. Using Visual Studio, developers can come up with test cases/test suites for different platforms like Windows, Android, iOS, Web, Cloud, etc.
- Set up Visual Studio for development.
- Install the NUnit framework & NUnit test adapter.
- Setup Selenium WebDriver with Visual Studio
- Start automated browser testing with NUnit for Selenium scripts
Why is the TestFixture attribute used in NUnit?
The TestFixture attribute marks a class that contains tests. Parameterized and generic test fixtures were introduced in NUnit 2.5. For an NUnit parameterized test, argument values are passed to the TestFixture NUnit attribute. The NUnit framework constructs a separate instance of TestFixture for each set of arguments.
What is the difference between NUnit and MSTest?
NUnit and MSTest are both open source frameworks, but they are different in many ways. NUnit is ported from JUnit automated testing framework, is well-matured, while MSTest is relatively new. MSTest comes pre-bundled with Visual Studio, due to which many developers prefer MSTest over other frameworks, including NUnit.
Got Questions? Drop them on LambdaTest Community. Visit now