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

框架 – 你的第一个框架 - 第 1 部分

starIconstarIconstarIconstarIconstarIcon

5.00/5 (2投票s)

2018年8月26日

CPOL

4分钟阅读

viewsIcon

6513

在上篇文章中,我们讨论了框架的定义并进行了扩展。并且我们尝试理解,编写你自己的框架的想法并没有你想象的那么可怕。

在上篇文章中,我们讨论了框架的定义并进行了扩展。并且我们尝试理解,编写你自己的框架的想法并没有你想象的那么可怕。

所以今天,我们将开始创建你的第一个用于在 Selenium 中测试 Web 应用程序的框架。在开始之前,我建议阅读“Selenium – 是什么?” 这篇文章,以便你至少了解 Selenium 和 WebDriver 代码的基础知识。

任何基于 Selenium 的框架最重要的部分是它能够启动浏览器,并且具有启动各种浏览器以进行跨浏览器测试的灵活性。 这就是我们的第一个类要做的事情。 我不会像大多数网站在进行框架教程时那样做,而是将每个类都写在一篇文章中,但要确保在文章结束时,你了解正在做什么、为什么要这样做以及我这样做的想法。 在给出例子时,很容易假设你理解代码,但如果我将 5 个类放在一篇文章中并略读它们,而你根本不理解任何一个类,那么下一篇文章又有什么用呢? 说了这么多,让我们开始吧

using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System;
using System.Net;
using NUnit.Framework;

namespace AutomationFramework.Engine
{
    public static partial class Driver
    {
        public static TimeSpan TimeOut = new TimeSpan(0, 1, 0);
        public static TimeSpan PollingInterval = new TimeSpan(0, 0, 2);

        public static void SetImplicitTimeout(TimeSpan timeout)
        {
            DriverBase.Instance.Manage().Timeouts().ImplicitWait = timeout;
        }
        
        public static void SetImplicitTimeout()
        {
            SetImplicitTimeout(TimeOut);
        }

        public enum DriverType
        {
            InternetExplorer,
            Chrome,
            Edge
        }

        public static void Initialise(DriverType driverType, TimeSpan? implicitWait)
        {
            var initialiseTimeout = implicitWait ?? TimeOut;

            try
            {
                switch (driverType)
                {
                    case DriverType.InternetExplorer:
                        var internetExplorerOptions = new InternetExplorerOptions 
                                { IntroduceInstabilityByIgnoringProtectedModeSettings = true, 
                                  AcceptInsecureCertificates = true };
                        DriverBase.Instance = new InternetExplorerDriver
                           (TestContext.CurrentContext.TestDirectory, internetExplorerOptions));
                        break;
                    case DriverType.Edge:
                        var edgeExplorerOptions = new EdgeOptions { AcceptInsecureCertificates = true };
                        DriverBase.Instance = new EdgeDriver(TestContext.CurrentContext.TestDirectory, 
                                                 edgeExplorerOptions));
                        break;
                    case DriverType.Chrome:
                        var chromeOptions = new ChromeOptions();
                        chromeOptions.AddArguments("test-type");
                        chromeOptions.AddArguments("chrome.switches", "--disable.extensions");
                        DriverBase.Instance = new ChromeDriver
                           (TestContext.CurrentContext.TestDirectory, chromeOptions, implicitWait);
                        break;
                }
            }
            catch (WebDriverException)
            {
                throw new WebDriverException($"Failed to initialise the 
                     {driverType.DescriptionAttribute()} web driver for Selenium");
            }

            DriverBase.Instance.Manage().Window.Maximize();
            
            if(null != implicitWait)
            {
                SetImplicitTimeout((TimeSpan)implicitWait);
            }
        }
    }
}

有很多方法可以实现这一点,但我们在本示例中采用的方法是通过一个 switch 语句来创建我们的 WebDriver 实例,该语句将在框架中的另一个点上接受一个参数。 根据传递的参数,我们将创建带有某些选项的特定于浏览器的 WebDriver 实例。 但让我们将每一段代码分解成细节。

我应该首先介绍的是我们的类是一个 partial 类。 partial 关键字用于将大型类分解成多个文件中的较小类,这纯粹是为了提高可读性和保持代码整洁。 但这是更大的 Driver 类的一部分。 我们将在后面介绍其他 partial 类。

一旦我们进入类内部,我们就会得到以下几行

     public static TimeSpan TimeOut = new TimeSpan(0, 1, 0);
     public static TimeSpan PollingInterval = new TimeSpan(0, 0, 2);

     public static void SetImplicitTimeout(TimeSpan timeout) 
     { 
         DriverBase.Instance.Manage().Timeouts().ImplicitWait = timeout; 
     }

     public static void SetImplicitTimeout() 
     { 
         SetImplicitTimeout(TimeOut); 
     }

这些是我们用来设置 timeout 值的变量,这样我们的测试就会在放弃等待动作发生之前等待一段时间,以及我们的框架将多久检查一次可能即将超时的事件的更新。 在测试自动化中,需要记住两种类型的等待,explicitimplicitImplicit 基本上是告诉测试等待一段时间,可以想象成一个 Thread.Sleep。 而 explicit 等待是告诉测试根据某些条件进行等待。 在自动化测试中,始终首选使用 Explicit 条件,因为 implicit 等待的累积会不必要地增加你的测试运行时间。 过度使用 implicit 等待也被认为是偷懒的行为。

在此之后,我们为不同的 Driver 类型创建一个 enum。 现在这纯粹是我个人的偏好。 你可以直接将一个 string 传递到我们的 initialise 方法中,但传递一个 enum 类型会更整洁,并且更不容易出错。

接下来是 Initialise 方法

        public static void Initialise(DriverType driverType, TimeSpan? implicitWait)
        {
            var initialiseTimeout = implicitWait ?? TimeOut;

            try
            {
                switch (driverType)
                {
                    case DriverType.InternetExplorer:
                        var internetExplorerOptions = new InternetExplorerOptions 
                                { IntroduceInstabilityByIgnoringProtectedModeSettings = true, 
                                  AcceptInsecureCertificates = true };
                        DriverBase.Instance = new InternetExplorerDriver
                             (TestContext.CurrentContext.TestDirectory, internetExplorerOptions));
                        break;
                    case DriverType.Chrome:
                        var edgeExplorerOptions = 
                                  new EdgeOptions { AcceptInsecureCertificates = true };
                        DriverBase.Instance = new EdgeDriver
                                  (TestContext.CurrentContext.TestDirectory, edgeExplorerOptions));
                        break;
                    case DriverType.Chrome:
                        var chromeOptions = new ChromeOptions();
                        chromeOptions.AddArguments("test-type");
                        chromeOptions.AddArguments("chrome.switches", "--disable.extensions");
                        DriverBase.Instance = new ChromeDriver
                          (TestContext.CurrentContext.TestDirectory, chromeOptions, implicitWait);
                        break;
                }
            }
            catch (WebDriverException)
            {
                throw new WebDriverException($"Failed to initialise the 
                               {driverType.DescriptionAttribute()} web driver for Selenium");
            }

            DriverBase.Instance.Manage().Window.Maximize();
            
            if(null != implicitWait)
            {
                SetImplicitTimeout((TimeSpan)implicitWait);
            }
        }

在这里,我们根据传入的 driverType 来设置我们将创建哪个 Driver 版本。 这是一个简单的 switch 语句,它将进入并设置驱动程序的新实例,并配置我们可能想要的任何特定于浏览器的选项。

这些浏览器设置是完全可选的。 并且你也不仅仅局限于我正在使用的那些。 有很多可以使用的,你需要的那些(如果有的话)将完全取决于你正在测试的环境以及你的测试中设置的任何要求。 你可以在 这里 阅读更多关于浏览器特定功能及其含义的信息。

一旦我们设置好了我们的浏览器,并做了一些基本的异常检查以确保它已正确初始化,我们就会对驱动程序实例进行一个基本的调用,以最大化窗口。 我在这里这样做,而不是稍后这样做,只是为了确保在我们离开 initialised 方法之前,我们已经打开并最大化了我们的浏览器窗口。

值得注意的是,目前,我们只是简单地创建一个 WebDriver 的本地实例,但在某个时候,我们将研究添加远程功能。

这就是我们的 DriverFactory 类的全部内容。很简单,对吧? 现在我们需要一个类来包装我们的 WebDriver 代码。 在下一篇文章中,我将介绍 DriverBase 类,以及扩展我们在 Driver 中拥有的一些其他 partial 类。

作为一个挑战,为什么不添加 Firefox 驱动程序功能和一些浏览器选项呢?

这篇文章 框架 – 你的第一个框架 第一部分 最初出现在 Learn Automation

© . All rights reserved.