【问题标题】:How to instantiate variable like WebDriverWait when test are given driver type as test case?当测试被赋予驱动程序类型作为测试用例时,如何实例化像 WebDriverWait 这样的变量?
【发布时间】:2013-04-14 02:08:23
【问题描述】:

我正在做 UI 测试。一开始我只使用 Firefox 浏览器驱动程序,所以我会在类下声明 WebDriverWait 变量,并在 [SetUp] 方法下分配它,如代码块所示,每个测试都可以使用它。

public class FirefoxTest {
public IWebDriver _driver;
public WebDriverWait _wait;
    [SetUp]
    public void SetupTest() {
          _driver = new FirefoxDriver();
          _wait = new WebDriverWait(_driver, TimeSpan.FromSeconds(30));
    }

然后我尝试通过使用 [TestCaseSource(typeof(WebDriverFactory), "Drivers")] 属性指定更多 BrowserDrivers 来合并它们。所以现在 _driver 变量必须从 [SetUp] 中移出,而 _wait 变量不知道要使用什么 _driver。

我尝试在每个测试中实例化它,但这是重复的,并且那些测试使用的方法也需要 WebDriverWait 变量,并且当另一个测试尝试实现它们时,这些方法不会第二次运行,因为已经声明了 WebDriverWait 变量。

我的问题是,当驱动程序作为 [TestCase] 给出时,我可以在哪里实例化 WebDriverWait 和其他依赖于驱动程序并且通常用 [SetUp] 和 [TearDown] 编写的东西,例如 driver.Quit()。

现在我已经写了类似的测试

[TestCaseSource(typeof(WebDriverFactory), "Drivers")]
public void SomeTest(IWebDriver driver){
    driver.Navigate().GoTo....
}

问题是我必须包括

WebDriverWait _wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30));
driver.Quit()

在所有测试中以及在测试中重用的所有方法中的 _wait。我在 [SetUp] 和 [Teardown] 中拥有的东西。

【问题讨论】:

    标签: c# nunit selenium-webdriver


    【解决方案1】:

    这里有两个选择。您没有提到WebDriverFactory 上的Drivers 属性是静态属性还是实例属性。如果它是一个静态属性,我会添加一个静态的QuitAll 方法,我可以在我的TearDown 方法中调用它。如果它是一个实例方法,事情会变得更棘手,我不确定你是否可以使用 NUnit 从这里到达那里。

    另一方面,不是创建WebDriverFactory 类来实例化驱动程序,而是TestCaseSource 属性的另一种形式,它允许您指定测试所在类的属性或字段。它可能会也适用于基类的属性或字段,但您必须尝试以确保。然后,您可以使用运行测试的同一类的成员,并且可以完全控制驱动程序对象的生命周期。看起来像这样:

    // WARNING! Untested code written from memory
    // without the aid of an IDE. Not guaranteed to
    // work or even compile without modification.
    // Use private field, public property
    // (personal choice). 
    private List<IWebDriver> activeDrivers = new List<IWebDriver>();
    public List<IWebDriver> ActiveDrivers
    {
        get { return this.activeDrivers; }
    }
    
    [TestFixtureSetUp]
    public void InitializeDrivers()
    {
        // Will run once for the class.
        // Use [SetUp] attribute to run
        // before each test method.
        this.activeDrivers.Add(new InternetExplorerDriver());
        this.activeDrivers.Add(new FirefoxDriver());
        this.activeDrivers.Add(new ChromeDriver());
    }
    
    [TestFixtureTearDown]
    public void QuitAllDrivers()
    {
        foreach(IWebDriver driver in this.activeDrivers)
        {
            driver.Quit();
        }
    }
    
    [TestCaseSource("ActiveDrivers")]
    public void MyTest(IWebDriver driver)
    {
        // Test goes here
    }
    

    请注意,我没有提及您的 WebDriverWait 字段。这是因为WebDriverWait 对象非常轻量级,并且构建成本并不高。如果您认为按需构造函数在您的代码中看起来很难看或过于冗长,您可以将其分解为一个可以从测试中调用的单独方法,如下所示:

    private void WaitUntil<T>(IWebDriver driver, Func<IWebDriver, T> until)
    {
        WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30));
        wait.Until<T>(until);
    }
    

    【讨论】:

    • 这解决了我遇到的问题,我特别喜欢 WebDriverWait 的单独方法。谢谢。
    【解决方案2】:

    您可以像这样使用[TestCase] 实例化类型:

    [TestCase(typeof(WebDriverWait))]
    public class Test(Type driverType)
    {
        _driver = Activator.CreateInstance(type, args);
    }
    

    我不知道您的所有确切类型和参数,但 Activator.CreateInstance 可能对您有所帮助。

    【讨论】:

    • 我不确定你是否明白我在问什么。我已经编辑了我的帖子以包含我的测试方法的样子。
    猜你喜欢
    • 1970-01-01
    • 2012-10-03
    • 1970-01-01
    • 1970-01-01
    • 2021-06-05
    • 2022-10-15
    • 1970-01-01
    • 2019-05-16
    • 1970-01-01
    相关资源
    最近更新 更多