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

Selenium 系列:第一章——入门

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.82/5 (9投票s)

2017年2月8日

CPOL

7分钟阅读

viewsIcon

21986

downloadIcon

440

让我们在 Selenium 中开始行动,并在本 Selenium 系列中开始自动化测试。

引言

本文是介绍性文章,介绍如何将 MsTest 用作简单的 Selenium 入门测试运行器。这是一个 Selenium 系列,将以有趣的文章形式,希望带领读者从 0 到 100,并附带源代码示例。

背景

本文将介绍 MsTest 和 Selenium 的基础知识。此外,我们还将简要介绍 Shouldly,但会有更深入的文章。如果您对测试、Web 测试以及如何使用 MsTest、Selenium 和 Shouldly 断言感兴趣,那么这里就是您的目的地。为了执行测试,您需要以下条件:

  • 最好是 Visual Studio 2015 及以上版本
  • C# 知识
  • 已安装 Firefox,我们将在其他文章中介绍针对 Internet Explorer、Chrome 和 Safari 运行测试
  • 已从 GitHub 克隆/下载源代码
  • 渴望去测试和搞破坏!

让我们开始吧!

所以您想知道如何将 MsTest 与 Selenium 以及一些 Shouldly 断言用于我们的测试,那就开始吧!这将是一篇基础文章,让我们开始,然后从第 2 章开始,我计划每周发布,内容将越来越深入。

因此,希望您已从背景部分提供的仓库下载了源代码,或者可以从文章的 Selenium 系列附件下载,并在 Visual Studio 中成功构建。如果一切顺利,您将在测试资源管理器窗口中看到以下内容,该窗口可在 Visual Studio 中通过“测试”->“窗口”->“测试资源管理器”找到:

Test Explorer

请注意,测试是如何按排序的,这是因为我们的解决方案中有 4 个测试类。它们如下,让我们开始测试!

OurFirstMsTest

这些测试以单元测试的方式提供 MsTest 设置。由于 MsTest 将是我们整个系列中驱动 Selenium 测试的工具,直到我们偶尔使用 Specflow,因此我认为演示一些简单的 MsTest 设置项目是明智的,我正在单独进行一个系列。下面显示了一个简单的 Person 类,该类具有一些属性和要测试的 get 方法。这可以在解决方案的“代码”->“Person.cs”下找到。

internal class Person
    {
        public int Age { get; set; }
        public string Name { get; set; }
        public int HeightInCm { get; set; }
        public string HairColour { get; set; }
        public int GetAge() => Age;
        public string GetName() => Name;
        public string GetHairColour() => HairColour;
        public int GetHeightInCm() => HeightInCm;
    }

现在,这 4 个 MsTest 可以在“测试”->“001_Our_First_MsTest”->“OurFirstMsTest.cs”中找到,其中包含 4 个测试,如下面的测试资源管理器所示,以及其中一个名为 AgeIs31 的测试的代码片段。

下面的 Age31 测试代码显示 MsTest 有一个名为 AgeIs31() 的测试方法。该方法需要用 [TestMethod] 属性进行装饰,这样 MsTest 才知道这是一个测试,否则 Visual Studio 会将该方法视为一个普通的有效方法,所以这非常重要。

由于测试总是涉及安排(Arrange)、执行(Act)和断言(Assert),我已经将其分解为代码中的这些部分,以便理解测试的各个阶段。现在我明白,关于 BDD/TDD 等的许多出版物都这样写,以及 Arrange-Act-Assert 的流程,但总的来说,无论您测试哪个层面,这个原则都是稳固的。因此,下面的测试会创建一个新的 Person 对象,调用 GetAge 方法,并确保 Sean 的年龄是 31,这很简单,但这些基础知识是理解 Selenium 之前所必需的,因为 MsTest 是其中的一部分。

  [TestMethod]
  public void AgeIs31()
  {
      //Arrange
      var person = new Person
      {
           HairColour = "Blonde",
           Age = 31,
           HeightInCm = 183,
           Name = "Sean"
       };

       //Act
       var actualAge = person.GetAge();

       //Assert
       Assert.AreEqual(31, actualAge);
   }

OurFirstShouldlyTest

我提到了 Shouldly,您可能会问它是什么,简而言之,它是一种用富有表现力的英语进行断言的方式,有些人称之为 Fluent assertions(流畅断言)。

下面显示了 MsTest 和 Shouldly 在我们的测试中外观的差异。如果您查看解决方案中名为 OurFirstShouldlyTest 的测试并执行它们,然后您可以比较您更喜欢哪种。两者都很棒,但我认为 Shouldly 在我们这里做的事情上有时更具表现力。

// MsTest Assertion
   Assert.AreEqual(31, actualAge);

// Shouldly Assertion
   actualAge.ShouldBe(31);

一个 Shouldy 测试示例,注意断言,MsTest 框架正在被使用,这很棒,但我们的断言是 Shouldbe。

        [TestMethod]
        public void Shouldy_IsCalledSean()
        {
            //Arrange
            var person = new Person
            {
                HairColour = "Blonde",
                Age = 31,
                HeightInCm = 183,
                Name = "Sean"
            };

            //Act
            var actualName = person.GetName();

            //Assert
            actualName.ShouldBe("Sean");

使用测试属性

这是一个包含 3 个测试的测试文件,每个测试方法都有 MsTest 属性,这是什么意思?这意味着我们可以将测试分组为对我们测试有意义的逻辑分组。您可能想到的某些测试类别是快速、中等和慢速运行的测试。可以通过将下面的内容添加到测试方法来对它们进行分组,请参见下面我们有的 HIGH、MEDIUM 和 LOW。另外请注意,我们可以为测试方法添加许多 TestCategories 或不添加。

        [TestCategory("HIGH")]
        [TestCategory("PERSON-TESTS")]
        [TestMethod]
        public void Shouldy_IsCalledSean()
        {
            //Arrange
            var person = new Person
            {
                HairColour = "Blonde",
                Age = 31,
                HeightInCm = 183,
                Name = "Sean"
            };

            //Act
            var actualName = person.GetName();

            //Assert
            actualName.ShouldBe("Sean");
        }

        [TestCategory("MEDIUM")]
        [TestCategory("PERSON-TESTS")]
        [TestMethod]
        public void Shouldy_IsCalledSean_CaseInsensitive()
        {
            //Arrange
            var person = new Person
            {
                HairColour = "Blonde",
                Age = 31,
                HeightInCm = 183,
                Name = "Sean"
            };

            //Act
            var actualName = person.GetName();

            //Assert
            actualName.ShouldBe("sean", StringCompareShould.IgnoreCase);
        }

        [TestCategory("LOW")]
        [TestCategory("PERSON-TESTS")]
        [TestMethod]
        public void Shouldly_AgeIsGreaterThan30()
        {
            //Arrange
            var person = new Person
            {
                HairColour = "Blonde",
                Age = 31,
                HeightInCm = 183,
                Name = "Sean"
            };

            //Act
            var actualAge = person.GetAge();

            //Assert
            actualAge.ShouldBeGreaterThan(30);
        }

您可能会问为什么要有它们,以及如何使用它们。让我们看一下测试资源管理器,如果您右键单击它并选择“按…分组”->“特征(Traits)”,您应该会看到您的测试都按类别分组,然后您可以整齐地定位它们并通过类别执行它们,这在 VS 和 MsTest 中是很酷的基础知识。既然我们了解了 MsTest 中的基本运行器、框架、特征/类别和结构,让我们开始进行 Selenium 测试。 Web 驱动的测试开始吧。

我们的第一个 Selenium 测试 - 开始吧

这才是我们现在在这里的目的,运行我们最初的几个测试并理解它们。现在我们已经运行了上面解决方案中的所有测试,并且了解了 MsTest、类别以及如何运行测试。让我们专注于 WEB 特征中的测试,它们位于名为 OurFirstSeleniumTests 的测试类中。

有两个测试,如下所示,非常简单的测试,也是我们成为 Web 测试大师的起点。

        [TestCategory("WEB")]
        [TestCategory("FAST")]
        [TestMethod]
        public void VisitTheSeleniumWebsite_CheckTheTitleIsPresent_AndMentionsSelenium()
        {
            // Arrange
            var driver = new FirefoxDriver();
            driver.Manage().Window.Maximize();
            driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));

            //Act
            driver.Navigate().GoToUrl("http://www.seleniumhq.org/");

            //Assert
            driver.Title.ShouldNotBeEmpty();
            driver.Title.ShouldBe("Selenium - Web Browser Automation");

            // clean up
            driver.Quit();
        }

        [TestCategory("WEB")]
        [TestCategory("FAST")]
        [TestMethod]
        public void VisitTheSeleniumWebsite_NavigateTheMenu_ToTheDocumentationPage()
        {
            // Arrange
            var driver = new FirefoxDriver();
            driver.Manage().Window.Maximize();
            driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));
            driver.Manage().Timeouts().SetPageLoadTimeout(TimeSpan.FromSeconds(10));

            //Act
            driver.Navigate().GoToUrl("http://www.seleniumhq.org/");

            var docMenu = driver.FindElement(By.Id("menu_documentation"));
            docMenu.Click();

            var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(drv => drv.Title.Contains("Documentation"));
           
            //Assert
            driver.Url.ShouldBe("http://www.seleniumhq.org/docs/");
            driver.Title.ShouldContain("Selenium Documentation");

            // clean up
            driver.Quit();
        }

让我们执行如下所示的测试。右键单击,运行选定的测试(即 WEB 特征),然后这两个测试应该会触发,您应该会看到它们执行并运行并通过。

我们已经运行了第一个 Selenium 测试,执行并通过了,所以恭喜您坚持到这里并通过了您的第一个测试!逻辑上,如果您是 Selenium 新手,下一个问题是实际发生了什么?让我们看看...

  1. 我们需要创建一个所谓的 WebDriver,它负责启动我们的浏览器版本并最大化屏幕。在这种情况下,我们使用 FirefoxDriver(),这意味着我们必须安装 Firefox,否则我们的测试将失败,因为我们无法与指定的浏览器进行通信。我们将在后续章节中介绍 Internet Explorer、Chrome、Edge 和 Safari,但现在我们使用的是 Firefox,这是 Selenium 的默认选择。下面的代码很重要,因为没有它,我们就无法开始,这大致是我们的安排部分。
    // Arrange
    var driver = new FirefoxDriver();
    driver.Manage().Window.Maximize();
    driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));
  2. 让我们来做一些如下所示的事情,让我们导航到 Selenium 网站,我们通过将 URL 传递到 GoToUrl 方法的 Driver 对象中来做到这一点,这非常直接和合乎逻辑,这就是我喜欢 Selenium 的地方,它在 99% 的时间里都是合乎逻辑的。我们可以争论“导航”。
    //Act
    driver.Navigate().GoToUrl("http://www.seleniumhq.org/");
  3. 现在我们已经导航到页面,这是我们想要断言我们所处的 URL。现在有多种方法可以做到这一点。让我们保持简单,断言标题不为空,并且断言标题为 Selenium - Web Browser Automation。如果其中任何一个不正确,那么自然,作为开发人员/测试人员,我们知道这个测试将会失败并向您报告。
    //Assert
    driver.Title.ShouldNotBeEmpty();
    driver.Title.ShouldBe("Selenium - Web Browser Automation");
  4. 最后,在单元测试中,我们通常在断言之后就完成了,但在集成测试或 Web 测试中不是这样,我们需要进行清理,无论是关闭数据库连接还是关闭我们的浏览器实例。在这种情况下,由于我们是 UI 测试人员,并且我们打开了浏览器,所以我们必须关闭浏览器,这在 Selenium 中是通过调用 Quit() 方法来完成的。完成后,我们就通过 UI 使用 Selenium 直接进行了测试并进行了清理。恭喜!
    // clean up
    driver.Quit();

What Next?

为什么不创建第 3 个测试并在解决方案中执行您自己想做的事情,例如断言主页有一个 Logo 或者某个元素中存在一些文本。除此之外,如果您已经按照说明操作,并且一切顺利,那么我感谢您,并期待在第 2 章及之后的章节中更快地进行,以真正开始我们的学习,并使用 Selenium、MsTest 和 Shouldly 扩展我们的测试。

如果您有任何问题,请随时联系!感谢您的阅读。

祝好,
Sean

© . All rights reserved.