2

I'm looking for a little bit of help in understanding NUnit when used with C# and Selenium in visual studio.

I've built a suite of tests where a lot of it has been cobbled together via self-learning and youtube videos.

The project used to just need to be a series of regression tests that run against a single site in multiple browsers.

I've achieved this and am quite happy with the results.

What I want to do now is expand this a little further

The product I have been testing against is a website that is reskinned for different clients where 99% of the content is the same.

Instead of just creating multiple projects/solutions in visual studio, I'd like to do something a bit more dynamic to cover regression against the different skins.

What i would like to do, is parametrize the testcase/browser/url combinations e.g.

  • TestCase1/Chrome/Site1
  • TestCase1/Chrome/Site2
  • TestCase1/Edge/Site1
  • TestCase1/Edge/Site2 etc.

I've been able to get the Visual Studio Test Explorer to recognize the parameter, but for some reason, it seems to produce un unexpected result e.g.

  • TestCase1/Site1
  • testcase1/Chrome
  • TestCase1/Site2
  • TestCase1/Edge/etc.

I've seen forums where they discuss doing something similar to what I'm talking about here by using NUnit parameters but have not been able to produce the desired result.

I thought it would have simply been a case of just adding another NUnit pram and passing it as I did before. Here is a slimmed down version of the code I'm currently using:

namespace AutomationStuffs.SmokeTests
{
    [TestFixture]
    public class LoginTests : TestBase
    {
        [Test]
        [TestCaseSource(typeof(TestBase), "BrowserToRunWith")]
        public void FirstTimeLogin(String BrowserName, String Url)
        {
            //Browser Driver Setup For test
            Setup(BrowserName);

            //...DO SOME TESTING THINGS
        }
    }
}

namespace AutomationStuffs.Utilities
{
    public class TestBase
    {
        public static IWebDriver driver;

        public void Setup(String BrowserName)
        {
            Driver.Intialize(BrowserName);
            //... DO SOME SETUP STUFF
            LoginPage.GoTo();
            //..I DO SOME LOGIN SETUP HERE
        }


        public static IEnumerable<String> BrowserToRunWith()
        {
            String[] browsers = BrowsersList.theBrowserList.Split(',');
            foreach (String b in browsers)
            {
                yield return b;
            }
        }
    }
}


namespace AutomationStuffs.Pages
{
    public class LoginPage
    {
        public static void GoTo()
        {
            Driver.Instance.Navigate().GoToUrl(Driver.baseURL);
        }
    }
}


namespace AutomationStuffs.Selenium
{
    public class Driver
    {
        public static IWebDriver Instance { get; set; }
        public static string baseURL
        {
            get
            {
                string url = System.Configuration.ConfigurationManager.AppSettings["BaseUrl"];
                return url;
            }
        }

        public static string chromeDriver
        {
            get
            {
                string driver = System.Configuration.ConfigurationManager.AppSettings["ChromeDriver"];
                driver = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, driver);
                return driver;
            }
        }

        public static string ieDriver
        {
            get
            {
                string driver = System.Configuration.ConfigurationManager.AppSettings["IEDriver"];
                driver = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, driver);
                return driver;
            }
        }


        public static string edgeDriver
        {
            get
            {
                string driver = System.Configuration.ConfigurationManager.AppSettings["EdgeDriver"];
                driver = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, driver);
                return driver;
            }
        }

        public static void Intialize(String BrowserName)
        {
            String DRIVER_PATH = chromeDriver;
            String DRIVER_PATH_IEFF = ieDriver;
            String DRIVER_PATH_EDGE = edgeDriver;

            var optionsChrome = new ChromeOptions();
            optionsChrome.AddArgument("start-maximized");
            optionsChrome.AddArgument("no-sandbox");

            var optionsIe = new InternetExplorerOptions();

            if (BrowserName.Equals("ie"))
            {
                Instance = new InternetExplorerDriver(DRIVER_PATH_IEFF);
                Instance.Manage().Window.Maximize();
            }
            else if (BrowserName.Equals("firefox"))
            {
                Instance = new FirefoxDriver();
                Instance.Manage().Window.Maximize();
            }
            else if (BrowserName.Equals("edge"))
            {
                Instance = new EdgeDriver(DRIVER_PATH_EDGE);
                Instance.Manage().Window.Maximize();
            }
            else
            {
                Instance = new ChromeDriver(DRIVER_PATH, optionsChrome);
            }
        }
    }
}

Here is what I thought I would have to do (And obviously just duplicate and adapt the underlying methods where appropriate):

namespace AutomationStuffs.SmokeTests
{
    [TestFixture]
    //[Parallelizable]
    public class LoginTests : TestBase
    {
        [Test]
        [TestCaseSource(typeof(TestBase), "BrowserToRunWith")]
        [TestCaseSource(typeof(TestBase), "URLToRunWith")]
        public void FirstTimeLogin(String BrowserName, String Url)
        {
            //Browser Driver Setup For test
            Setup(BrowserName);

            Assert.IsTrue(FiveComponentsAndDocStorePage.AssertOnThePage());
        }
    }
}

2 Answers 2

2

NUnit treats every TestCaseSource separately, it will creates test cases for BrowserToRunWith and only after that it will do it for URLToRunWith. If you try to run it you will get

Result Message: Wrong number of arguments provided

To create test cases for both parameters you need to send them together to the TestCaseSource. You can do something like

public static IEnumerable TestData
{
    get
    {
        string[] browsers = BrowsersList.theBrowserList.Split(',')
        string[] urls = UrlsList.theUrlList.Split(',')

        foreach (string browser in browsers)
        {
            foreach (string url in urls)
            {
                yield return new TestCaseData(browser, url);
            }
        }
    }
}

Or with linq

public static IEnumerable TestData
{
    get
    {
        string[] browsers = BrowsersList.theBrowserList.Split(',')
        string[] urls = UrlsList.theUrlList.Split(',')

        return from browser in browsers
               from url in urls
               select new TestCaseData(browser, url);
    }
}

And the TestCaseSource will look like

[TestCaseSource(typeof(AAA), "TestData")]
Sign up to request clarification or add additional context in comments.

1 Comment

That is a spot on answer! Thank you so much. I was running under the very incorrect impression that I could just pass the TestCaseSource value again and NUnit did some magic - obviously, I was very wrong ha, ha.
1

@Guy 's answer is exactly correct - I up-voted it.

For completeness, here is an alternative way to write the test, which may be what you had in mind when you thought NUnit would "do some magic."

    [Test]
    public void FirstTimeLogin(
        [ValueSource("BrowserToRunWith")] String BrowserName, 
        [ValueSource("UrlToRunWith")] String Url)
    {
        //Browser Driver Setup For test
        Setup(BrowserName);

        Assert.IsTrue(FiveComponentsAndDocStorePage.AssertOnThePage());
    }

The ValueSource members would be similar to what you already have but would each return a string rather than a TestCaseData instance.

Note that the [Test] attribute is required in this case. It was optional (and ugly, IMO!) in the original example. :-)

1 Comment

That's very useful to know. Thank you for this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.