How To Write Frontend Unit Tests with C# and Selenium

I think a lot of developers have heard of Selenium, however, from my experience very few teams get around to using Selenium on their projects.  Like Unit Testing in general, I think most people have 'frontend' testing on their 'we SHOULD do this list'.  At the beginning of a project, it gets added as a task that someone promises to get around to implementing and ultimately it never happens. In today's guide, I'm going to walk you through setting up Selenium with C# and NUnit, I'm going to tell you one simple technique that will make your deployments a lot more secure and I'll end by showing you the code to implement it, so read on.

Whats The Point Of Using Selenium With C#

As someone who runs their own website, one issue I have whenever I do a deployment, is that even though the current changeset might look pretty simple I don't have the time to physically check that every template/page works for each release.  I run this website and I also deal with multiple clients so my time is limited.  A LOT of code has been written to render this page you're reading, this isn't simply some theme but a handcrafted website that probably does a lot more than you might first think.  At the time of writing, I think there are over 1000 pages now.

This leaves me with a problem; when I make code changes how do I know that I haven't broken a template, or, a page without spending an hour or two each release checking every page? This is one area Selenium can come in handy and save you hundreds of hours of boring testing. When I make a release I like to know that it will work. One simple set of Selenium tests that you can write, is create a test to make sure that key pages on your site don't return a 404 when your build server is compiling your site.  

This one simple trick has helped me a number of times find errors that would have otherwise gone live.  In my opinion, setting up Selenium is a really good time investment as over your website's lifespan, you can save hours and hours worth of manual testing.  If you're working on an e-commerce site for example, simply spotting and saving an error on the checkout page for example can save you a fortune in lost revenue.  I've seen companies lose anywhere between £10,000 and £45,000 over a weekend through bad deployments (it wasn't me, incase you're wondering!!!!) 

How Do I Write Code Using Selenium With C#

Writing Selenium tests is very similiar to writing normal unit tests and the majority of your test code will look exactly the same . You can still use NUnit for the setup and tear down code, you still define tests by using the [Test] attribute above it. The main difference when using Selenium is that you'll need to set-up a web driver to either load a browser locally (on your build server), or you can use a virtual browser in the cloud to emulate different browsers. Virtual browsers are pretty cool and make your life a lot easier and if you're thinking Selenium is for you, then I recommend doing a bit of research into it.   If you opt to use local browsers isntalled on your server via a local web driver, then you'll need to install all the browsers you want to test against on your server and keep them up-to-date. This is a pain...

What Is BrowserStack?

I talked briefly about virtual web drivers, there might be loads of options availble, but my experience has mainly been with browser stack automate.  Browser stack automate is not free, however, it's not going to cost you millions of pounds to use and if you can afford it I would recommend getting a BrowserStack license. Browserstack has a cool feature called Automate.  Once up and you have a browser stack atomate account, you can create a web driver class, passing in your browserstack username/password and then you can use virtual browsers!  Simply specify what type of browser you want to use from Browserstacks list and off you go.  No one software maintenance required!

What Does My Build Process Look Like?

One thing that can confuse people is what a build process with Selenium looks like.  Selenium does add in an extra few steps.  First, you will need to deploy your website with a hostname/url that the build server can talk to, in order for the Selenium tests to be run. Unlike normal unit tests,  you will need a fully deployed site within IIS website (that works) before you can run your tests.  You cannot simply just run Selenium tests against your compiled assemblies/Dll's.  

This means that in your build process before your website can be classed as 'built' or 'working', you will need to deploy the current build to a seperate website, run your selenium tests against that new instance and then if everything passes, continue on with your build however you normally would.  

Your website can only be considered as built after your Selenium tests have run.. In effect you're adding an additional build step, that needs to talk to a new working instance of your website before you can deploy to the target enviroment you can to finish with.


In most situations, I usually create a hostname similiar to 'autotestsite.website.com' that the build server deploys to first.  The Selenium tests are run against 'autotestsite.website.com' and if they pass, the build server then deploys the working website to 'website.com'.  All QA/demos etc.. then occurs on 'website.com'

Show Me Some Selenium Code!

Ok, so let's get to the good stuff.  If you're new to unit testing, I suggest you read my NUnut section first, otherwise you might get muddled up with which parts are NUnit and which parts are Selenium.  In these test I'm using a web driver thats talking to browser stack.  Below this class I'll also go over how you would create a normal local web driver.

    using System;
    using FluentAssertions;
    using NUnit.Framework;
    using NUnit.Framework.Internal;
    using OpenQA.Selenium;

    [TestFixture]
    public class HomepageTests
    {
        private IWebDriver _driver;
        private string _baseUrl;

        [SetUp]
        public void SetupTest()
        {
            var capability = DesiredCapabilities.Firefox();
            capability.SetCapability("browserstack.user", "MYUSERNAME");
            capability.SetCapability("browserstack.key", "MYPASSWORD");

            _driver = new RemoteWebDriver(
                new Uri("http://hub-cloud.browserstack.com/wd/hub/"), capability);

            _baseUrl = "https://world.episerver.com/";
        }

        [Test]
        public void Should_Pass()
        {
            driver.Navigate().GoToUrl(baseUrl);

            var query = driver.FindElement(By.Name("searchQuery"));
            query.SendKeys("jon");
            query.Submit();

            driver.PageSource.Should().Contain("Looks cool Jon");
        }

        [Test]
        public void Should_Pass()
        {
            driver.Navigate().GoToUrl(baseUrl);

            var query = driver.FindElement(By.Name("searchQuery"));
            query.SendKeys("browserstack");
            query.Submit();

            driver.PageSource.Should().NotContain("Looks cool Jon");
        }

        [Test]
        public void Should_Fail()
        {
            driver.Navigate().GoToUrl(baseUrl);

            var query = driver.FindElement(By.Name("searchQuery"));
            query.SendKeys("browserstack");
            query.Submit();

            driver.PageSource.Should().Contain("Looks cool Jon");
        }

        [TearDown]
        public void Cleanup()
        {
            if (this.driver == null)
            {
                return;
            }

            this.driver.Close();
            this.driver.Quit();
        }
    }
}

As you can see, the tests look pretty similiar to normal unit tests. You create a web driver and then you can use methods like 'FindElement()' and 'SendKeys()' to perform the commands you need. The driver has properties like PageSource, PageTitle etc.. in order for you to test that the page is then working as expected.

Selenium Takeaway

On big projects, I think having automated tests that make sure you haven't broken key pages is a vital part of a good  build process, you can achieve this using Selenium.  Granted it does take little up-front learning and effort, but, over the course of a year, the amount of manual testing you need to do will be drastically reduced.  Enjoy!

,

Jon D Jones

Software Architect, Programmer and Technologist Jon Jones is founder and CEO of London-based tech firm Digital Prompt. He has been working in the field for nearly a decade, specializing in new technologies and technical solution research in the web business. A passionate blogger by heart , speaker & consultant from England.. always on the hunt for the next challenge

Back to top