Selenium 系列第四部分:终止闲置的浏览器进程以获得更一致的 Selenium 测试
本文旨在帮助您在自动化 Selenium 测试期间清理浏览器进程。
引言
本文将逐步介绍如何稳定我们的浏览器测试,并确保在需要时,您的计算机在给定时间只有一个 Selenium 浏览器实例进程在运行。
我们希望在这里实现的目标是:当 1 个测试运行时 - 只有 1 个 Selenium 浏览器进程处于活动状态。
背景
如果您正在编写 Selenium 测试并调试测试,我们都会这样做!有时,该测试会抛出我们正在处理的场景。随着时间的推移,如果您只是在调试时关闭浏览器窗口,底层进程仍然会挂起,因为一行重要的代码没有被执行,而这行代码本应执行。
driver.Quit();
这意味着,如果您多次执行此操作(关闭浏览器而不让调试器或测试命中 driver.Quit()
导致失败),那么在您的计算机上可能会有许多 IEDriverServer.exe、FirefoxDriver.exe 和 Chromedriver.exe 进程在后台运行,并且占用多个端口,特别是如果您正在运行不同的浏览器配置。
在您开发测试的机器上检查一下,看看是否有这些额外的进程。
- 在您的 Windows 机器上打开 **任务管理器窗口**。
- 点击 **详细信息** 选项卡,以查看您机器上的所有进程。
- 按 **名称** 对详细信息选项卡进行排序,查找您正在测试的进程。
- IE、Chromedriver.exe、IEDriverServer.exe,本文还提到了可用于此目的的其他驱动程序,但重点介绍了 Chrome 和 Internet Explorer。
- 如果您在本地运行测试进行开发和调试,希望显示的进程不多。请看下面,在我没有运行任何测试的情况下,我也有 3 个过多的进程。
- 如果您确实显示了与 Selenium 浏览器驱动程序相关的进程,**那么让我们删除它们,即终止进程,然后开始工作 :-)**
通过在您的解决方案中添加几行代码,可以帮助您在本地使用 MsTest 或顺序运行程序进行 Selenium 测试,NUnit 也适用,这确实有助于保持您的系统进程干净。
我的做法是在测试开始前终止所有浏览器进程,这意味着如果我有一个测试正在运行,我确保只有一个进程在运行,因为在顺序运行时,这是 1 对 1 的映射。
我主张“如果你不需要它,就删除它!!”
Using the Code
如上所述,这适用于顺序 C# 测试,而大多数使用 C# .NET 绑定的人都是这样做的。
下面的代码是我在测试设置中使用的几行代码。在 MsTest
中,这被称为 [TestInitialize]
。
我之所以在设置而不是拆卸中执行此操作,是因为
- 在开发测试、调试和中断它们的过程中,有时您会提前关闭测试。这意味着您可能不会执行拆卸,因此也就不会执行
Driver.Quit()
方法,这正是我们试图在这里解决的问题。 - 因此,如果您将以下代码片段放在 **测试设置** 中
- 每个测试都必须通过设置,这是 Test Initialize 的规则,因此您知道并可以保证用于清除进程的代码将被执行,并且您闲置的死进程将被清除,这意味着您的测试只有一个进程可以附加。
- **如果您不需要它,请删除它!**(请注意,此代码片段也是如此,如果您不需要它,请放在手中以备将来使用,但不要在需要之前使用它)
可以 Microsoft Library 中找到 system.diagnostics
类和详细信息。
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());
}
}
关注点
- 我将此代码作为我 C# .NET Selenium 测试解决方案的一部分运行,因为 MsTest 是我们的运行器。在 Java 和其他可以多线程的语言中,这可能会有问题,因此本文的范围仅限于顺序运行测试。
- 我在运行 Sauce Labs 时也使用了这段代码,并且效果很好,因为 C# .NET MsTest 是顺序执行 Selenium 测试的。
- 上面的进程可以扩展,我只展示了 IEDriverServer.exe 和 chromedriver.exe 这两个进程的终止。在扩展到其他直接影响系统的系统进程时要小心。
- 在添加任何进程之前,请务必了解它们为什么运行以及它们正在做什么。
- 我所有的测试类都继承了
TestBase
,如上所示,因此免费获得了上述运行。 - 我正在编写一篇关于 Selenium TestBase、Test Setup / Tear Down 的文章,以更深入地探讨这个话题。
- 如果您觉得不需要这个,那么也许就不要使用它,但是如果您有空闲的进程在那里什么也不做,那么它将会有帮助。这不会有什么坏处,因为谁想要一个有数千个空闲进程的机器状态呢?
- 如果您有任何意见,请大声告诉我,我很想听听您的使用情况!
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();
}
}
}
祝您测试愉快!谢谢!