My Maintainable Automated UI Tests

Original post By Mehdi Khalili on 9 Oct 2013 here
I just modified it to best suit my needs.

Mehdi Khalili uses Selenium webdriver to do an automated UI test. The key of the post is to see the test code as “code” and use object oriented patterns. Here is how I’m using it with xunit and Trackyon CUIT Helpers.

Basic MVC example

Complete solution for download here.

  1. Create a new MVC 4 Intranet Application (Razor engine)
    Project properties:

    • Anonymous Authentication (Disabled),
    • Windows Authentication (Enabled),
    • URL (notice port)

    basic mvc

  2. Create a new Class Library to hold the tests
    Nuget packages:

    • xunit,
    • Trackyon.CUIT.Helpers,
    • Selenium.WebDriver,
    • Selenium.Support
  3. Download and add IEDriverServer
    File properties:

    • Build Action (None),
    • Copy to Output Directory (Copy if newer)
  4. Create base classes Host, Page, SeleniumApplication. For simplicity only the changes from the original post are shown below.
    public class SeleniumApplication {
        public void Run(string websiteName, int portNumber) {
            IISExpress.Start(websiteName);  // Trackyon.CUIT.Helpers
            var options = new InternetExplorerOptions() {
            IntroduceInstabilityByIgnoringProtectedModeSettings = true
            };
            WebDriver = new InternetExplorerDriver(options);
            WebDriver.Navigate().GoToUrl(
                   string.Format("http://localhost:{0}", portNumber));
            AppDomain.CurrentDomain.DomainUnload 
                    += CurrentDomainDomainUnload;
        }
        private void CurrentDomainDomainUnload(object sender, 
                                               EventArgs e) {
            WebDriver.Quit();
        }
    }
    
  5. Create a class to mimic the HomeController Index page
    public class HomeIndex : Page {
        public static HomeIndex Initiate() {
            var driver = Host.Instance.WebDriver;
            driver.Navigate().GoToUrl(driver.Url);
            return new HomeIndex();
        }
    
        // bullets on the index page of the home controller
        public string[] Bullets {
            get {
                return WebDriver.FindElement(By.ClassName("round"))
                                .FindElements(By.TagName("li"))
                                .Select(x => x.Text).ToArray();
            }
        }
    }
    
  6. Create a class to hold the testdata.
  7. Create a class to hold the coded UI tests. The IUseFixture takes care of initializing and disposing the testdata. This is a xunit feature.
    public class HomeTest {
        [Fact]
        public void HomeIndexPage_Shows_gettingStarted() {
            var page = HomeIndex.Initiate();
            Assert.True(page.Bullets.Any(bullet => 
                    bullet.ToLower().Contains("getting started")));
        }
        [Fact]
        public void HomeIndexPage_Shows_nuget() {
            var page = HomeIndex.Initiate();
            Assert.True(page.Bullets.Any(bullet => 
                    bullet.ToLower().Contains("nuget")));
        }
        [Fact]
        public void HomeIndexPage_Shows_hosting() {
            var page = HomeIndex.Initiate();
            Assert.True(page.Bullets.Any(bullet => 
                    bullet.ToLower().Contains("hosting")));
        }
    }
    

The testcode checks the Index page for the text in the three bullets. Getting started, nuget and hosting.
basic mvc highlighted
Complete solution for download here.

More details

Because of the security I’m using (Windows Authentication) I’m using the Trackyon.CUIT.Helpers IISExpress class. The original solution started the process from the commandline with a custom port, but that needed IISExpress to be configured the same for all websites. I could’t figure out a way to use the visual studio solution from the commandline. The Trackyon solution just starts the website that is in the applicationhost.config and is adjusted by visual studio.

Xunit provides the IUseFixture for handling testdata. I’m using it to load a certain page, do all the tests on it and then close the page after all tests are done.

When the tests are run, the webdriver is still active as a process. I’m still looking into the AppDomain.CurrentDomain.DomainUnload event and why it is not firing when the xunit tests are done. I might add the WebDriver.close() to the testdata / IUseFixture.

[update]
I’m using WebDriver.Quit() to stop the process. After upgrading to xUnit.net runner 0.99.3 the event was triggered and everything is just “fine and dandy” now.
[update]
No need for IUseFixture (removed) and updated demo project.

About erictummers

Working in a DevOps team is the best thing that happened to me. I like challenges and sharing the solutions with others. On my blog I’ll mostly post about my work, but expect an occasional home project, productivity tip and tooling review.
This entry was posted in Test and tagged , , , , , , , . Bookmark the permalink.

3 Responses to My Maintainable Automated UI Tests

  1. Pingback: Run Selenium from visualstudio.com | .NET Development by Eric

  2. Pingback: Best Off .NET development by Eric | .NET Development by Eric

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.