Introduction
This is an article which is going to take us step by step through how to stabilize our browser tests and ensure that our computer only ever has one process running of the Selenium Browser Instance at a given time if that is so desired.
What we're hoping to achieve here, when 1 test is running - only 1 Selenium Browser process is alive.
Background
If you're writing Selenium tests and debugging tests, we all do! Sometimes, that test throws the scenario we're tackling here. Over time, if you just close the browser window whilst debugging, the underlying process still hangs around as one important line of code doesn't get executed which should:
driver.Quit();
Meaning if you do this multiple times closing the browser and not letting your debugger or test fail hitting driver.Quit()
, then you can have many IEDriverServer.exe, FirefoxDriver.exe and Chromedriver.exe running in the background on multiple ports on your computer if you're running different browser configurations.
Check it out on your machine you develop tests and see if you have these extra processes:
- Open the Task Manager Window on your Windows machine.
- Click on the Details tab to see all your processes on your machine.
- Order the details tab by Name, look for the process you're testing with:
- IE, Chromedriver.exe, IEDriverServer.exe, also there are drivers which can be used as part of this article but highlighted Chrome and Internet Explorer.
- If you run tests locally when developing tests and debugging, hopefully there aren't many processes shown. See below, I have 3 too many when no tests are running.
- If you do have processes shown which are the selenium browser drivers, then let's delete, aka, kill the processes and get to work :-)
In a few lines of code added to your solution, it could help you when locally running Selenium Tests with MsTest or a Sequential runner, NUnit also applies that this really does help keep your system processes clean.
What I do is kill all browser processes before my test begins, meaning if I have 1 Test running, I ensure I have 1 process running only as its a 1-1 mapping when running sequentially.
I am an advocate of if you don't need it, then Delete it!!
Using the Code
As mentioned above, this is for sequential C# tests which is the majority of people using the C# dotnet bindings.
The below piece of code are the few lines I use as part of my test setup. This is called [TestInitialize]
in MsTest
.
The reason I do this in the setup vs tear-down is:
- When developing tests, debugging and breaking on them, on occasion, you'll close the test early. Meaning that you might not hit the tear down and therefore the
Driver.Quit()
method, that's the item we're trying to take care of here. - Therefore, if you put the below code snippets in the Test Setup
- Every single test must run through the setup, it's the law of Test Initialize and therefore you know and are guaranteed that the code to clear your processes will be executed, and you have your laying around dead processes of the driver killed meaning your test has only 1 process to attach too.
- If you do not need it, Delete it! (note this is true of the snippet, if you do not need it, have it in your pocket to use but do not use it until you need it)
The process system.diagnostics
class and details can be found in the Microsoft Library.
using System.Diagnostics;
public class TestBase
{
[TestInitialize]
public void SetUp()
{
Process.GetProcessesByName("IEDriverServer").ToList().ForEach(p => p.Kill());
Process.GetProcessesByName("chromedriver").ToList().ForEach(p => p.Kill());
}
}
Points of Interest
- I run this code as part of my C# .NET Selenium Testing Solution as MsTest is our runner. In Java and other languages which can multi thread, this could be an issue so scope for this article is defined for sequential running of tests.
- I use this snippet of code also when running sauce labs and it works great due to C# .NET MsTest being a sequential execution of Selenium tests.
- The above processes can be extended, I've only shown IEDriverServer.exe and chromedriver.exe for the processes I kill. Be careful on extending into other system processes such as windows processes directly affecting the system.
- Always make sure you know why they're running and what they are running before adding.
- All my Test classes inherit
TestBase
as shown above, therefore get the above run for free. - I am in the process of writing a Selenium TestBase, Test Setup / Tear Down article to dive deeper into that side of the post.
- If you do not feel you need this, then maybe do not consume it, however if you have processes hanging around doing nothing, then it's going to be a help. It cannot hurt as who wants a machine state with 1000s of processes doing nothing?
- Any comments, please do shout and let me know as I would love to hear how you're getting on!
using System.Diagnostics;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using WebsiteUiTests.Driver;
using WebsiteUiTests.Factory;
using WebsiteUiTests.Helpers;
namespace WebsiteUiTests.Tests
{
public class TestBase
{
public TestContext TestContext { get; set; }
[TestInitialize]
public void SetUp()
{
Process.GetProcessesByName("IEDriverServer").ToList().ForEach(p => p.Kill());
Process.GetProcessesByName("chromedriver").ToList().ForEach(p => p.Kill());
SeleniumDriver.TestName = TestContext.TestName;
SeleniumDriver.BaseUrl = Configuration.GetBaseUrl;
SeleniumDriver.CreateDriver();
Page.LoginPage.Goto();
}
[TestCleanup]
public void TearDown()
{
if (Configuration.GetSauceLabsEnabled.ToLower().Equals("yes"))
{
bool pass = TestContext.CurrentTestOutcome == UnitTestOutcome.Passed;
((IJavaScriptExecutor) SeleniumDriver.Instance).ExecuteScript(
"sauce:job-result=" + (pass ? "passed" : "failed"));
}
SeleniumDriver.Close();
}
}
}
Happy testing! Cheers!