User Interface Unit Tests with .NET Core
In a previous post I talked about doing unit tests with .NET Core. What I didn’t cover was unit testing for the user interface (UI). It is actually something quite common, and we will see how we can do it now.
Selenium is a portable software-testing framework for web applications and there is a .NET port of it. We will be using the Selenium.WebDriver package, plus one or more of the following, to target different browsers:
Selenium offers a “minimum” contract that works across all browsers.
I won’t go through all of it, but I will give you some examples on how it works. We start by instantiating a driver:
using (var driver = (IWebDriver) new ChromeDriver(Environment.CurrentDirectory))
Notice the Environment.CurrentDirectory parameter; it specifies the path where the driver can find the chromedriver.exe file, or geckodriver.exe for Firefox or MicrosoftWebDriver.exe, in the case of IE/Edge. These executables are added automatically by the Nuget packages. If you don’t dispose of the driver, the window will remain open after the unit test finishes. You can also call Quit at any time.
Now, we can navigate to some page:
And find some element from its name:
var elm = driver.FindElement(By.Name("q"));
Besides the name, we can also search by:
- Id: By.Id
- CSS class: By.ClassName
- CSS selector: By.CssSelector
- Tag name: By.TagName
- Link text: By.LinkText
- Partial link text: By.PartialLinkText
- XPath: By.XPath
Once we find an element, we can access its properties:
var attr = elm.GetAttribute("class");
var css = elm.GetCssValue("display");
var prop = elm.GetProperty("enabled");
Then we can send it text strokes:
Or click on it:
As we know, page loading can take some time, so, we can configure the default time to wait for it, probably before we do a GoToUrl:
var timeouts = driver.Manage().Timeouts();
timeouts.ImplicitWait = TimeSpan.FromSeconds(1);
timeouts.PageLoad = TimeSpan.FromSeconds(5);
ImplicitWait is just a time that Selenium waits before searching for an element.
If we need to wait for some period of time, like, until some AJAX request finishes, we can do this:
var waitForElement = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
var logo = waitForElement.Until(ExpectedConditions.ElementIsVisible(By.Id("hplogo")));
The condition passed to ExpectedConditions can be one of:
As you can see, you have a wealth of conditions that you can use. If the condition is not met before the timer expires, then the value returned by Until is null.
This can be a nice complement to your unit tests. Hope you find this useful!