C# 中的 Selenium WebDriver - "By" class 扩展

Selenium WebDriver in C# - "By" class Extension

我一直在一个 webdriver 项目中工作来自动化我的测试,我试图开发一些类似助手的东西。默认情况下,在 By class 方法中有 CssSelector()、XPath()、ClassName() 等

我的问题是:我是否可以(以及如何?!)扩展此 class 以创建另一种方法来简化我的代码?我想要 By 调用我自己的方法。我搜索并得到了一些关于如何创建 NewBy 的结果,但我认为这会使我的代码将来变得混乱。

Selenium 中默认存在的内容:

FindElement(By.CssSelector("#example"));

我要开发的东西:

FindElement(By.MyOwnMethod("example"));

谢谢!

在css中,#符号是ID选择符。您可以只使用 By.Id(string) 方法。


编辑:

如果你真的想自定义它,你可以定义你自己的实现By。但是您不能扩展静态方法,因此您需要创建一个新的 class 来托管它们。我在这里使用Via,你可以随时使用对你更有意义的名称,例如网站名称:

public class Via
{
    public static By AdminMenu(string Id) // could also just use int
    {
        return By.CssSelector(string.Format("[selenium-admin-menu='{0}']", Id));
    }

    public static By ImgSrc(string source)
    {
        return By.CssSelector(string.Format("img[src='{0}']", source));
    }
}

//usage: 
var menu3 = driver.FindElement(Via.AdminMenu("3"));

简而言之,你不应该这样做。这不会使您的代码更清晰,它会使代码更难阅读,因为任何其他具有 Selenium 经验的人都无法阅读您的代码。不要再添加抽象层,只需按照编写的方式使用 Selenium。如果你有 HTML,其中有多个管理菜单,它们只是索引不同,例如By.CssSelector("[selenium-admin-menu='3']") 然后编写一个函数,它接受一个索引并且 return 是正确的元素。

public WebElement getAdminMenu(int index)
{
    return driver.findElement(By.cssSelector("[selenium-admin-menu='" + index + "']"));
}

或者更好的是,根据其实际名称为每个管理菜单创建一个函数,这样函数的使用者就可以确切地知道该函数的作用,而不必查看 HTML将管理菜单翻页并计数到 return 个正确的菜单。

public WebElement getAdminMenuManageUsers()
{
    return driver.findElement(By.cssSelector("[selenium-admin-menu='1']"));
}

public WebElement getAdminMenuManageSite()
{
    return driver.findElement(By.cssSelector("[selenium-admin-menu='2']"));
}

显然这些都是编造的例子,因为我不知道你的网站。

如果您希望您的驱动程序具有利用特定用例的快捷方式 DOM,您始终可以扩展 IWebDriver 而不是 By

using OpenQA.Selenium;

namespace Tests.Selenium.Utils
{
    public static class DriverExtensions
    {
        public static IWebElement FindAdminMenu(this IWebDriver driver, string Id)
        {
            return driver.FindElement(By.CssSelector(
                string.Format("[selenium-admin-menu='{0}']", Id)
            ));
        }
    }
}

然后这一行...

var menu3 = driver.FindElement(Via.AdminMenu("3"));

减少到

var menu3 = driver.FindAdminMenu("3");

很有趣。 FindAdminMenu 可能是不透明的,尤其是当您真正键入整数时。如果您可以更改 DOM 的书写方式,您最好在那里使用人类可读的 class 名称。

有了人类可读的 classes,我不会担心便捷方法。然后,您所做的实际上与 Page Object Modeling 没有太大区别,我认为对于 Selenium,这通常是一件好事。 POM 将使您的测试的 actions/business 逻辑层从 DOM 更改中抽象出来。并且 DOM 变更 [as or much much with business logic changes]。 ;^)