65.9K
CodeProject 正在变化。 阅读更多。
Home

Selenium 系列第四部分:终止闲置的浏览器进程以获得更一致的 Selenium 测试

starIconstarIconstarIconstarIconstarIcon

5.00/5 (4投票s)

2018 年 4 月 19 日

CPOL

4分钟阅读

viewsIcon

13132

本文旨在帮助您在自动化 Selenium 测试期间清理浏览器进程。

引言

本文将逐步介绍如何稳定我们的浏览器测试,并确保在需要时,您的计算机在给定时间只有一个 Selenium 浏览器实例进程在运行。

我们希望在这里实现的目标是:当 1 个测试运行时 - 只有 1 个 Selenium 浏览器进程处于活动状态。

背景

如果您正在编写 Selenium 测试并调试测试,我们都会这样做!有时,该测试会抛出我们正在处理的场景。随着时间的推移,如果您只是在调试时关闭浏览器窗口,底层进程仍然会挂起,因为一行重要的代码没有被执行,而这行代码本应执行。

driver.Quit();

这意味着,如果您多次执行此操作(关闭浏览器而不让调试器或测试命中 driver.Quit() 导致失败),那么在您的计算机上可能会有许多 IEDriverServer.exeFirefoxDriver.exeChromedriver.exe 进程在后台运行,并且占用多个端口,特别是如果您正在运行不同的浏览器配置。

在您开发测试的机器上检查一下,看看是否有这些额外的进程。

  • 在您的 Windows 机器上打开 **任务管理器窗口**。
  • 点击 **详细信息** 选项卡,以查看您机器上的所有进程。
  • 按 **名称** 对详细信息选项卡进行排序,查找您正在测试的进程。
    • IE、Chromedriver.exeIEDriverServer.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.exechromedriver.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();
        }
    }
}

祝您测试愉快!谢谢!

© . All rights reserved.