4

在运行 Selenium WebDriver 测试用例时,我想要一个一致的输出。

我在一个 java 类中有 30 多个测试用例。当我运行它时,我在不同的方法中遇到错误。例如。有时它在第 12 次测试用例中失败,有时在第 8 次测试中失败,有时在第二种方法中失败,有时都运行没有任何错误。我确信所有的测试用例都是正确的。

它测试非常快。我认为这将是问题所在。所以我加了

new FireFoxDriver().manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);

虽然不一致

谁能尽快帮助我?

4

3 回答 3

11

我强烈反对 Arran 的说法,即 UI 测试非常不可靠。绝对不必如此。学习解决两个主要问题的可靠方法通常可以解决很多问题。

间歇性故障最常见的原因是围绕动态内容的同步问题,或者定位器不够灵活,无法处理不断变化的条件。

例如,您正在从网格/表格中提取一行,并且您的定位器是基于位置的。(第 3 行,第 5 个单元格)一次运行的排序顺序不同,因此测试中断。像 ASP.NET 这样的一些服务器端技术会生成可以变化的动态 ID,所以这是另一个问题。

我鼓励您仔细评估您的定位器/选择器,看看它们是否可靠。避免使用硬连线的 xpath,尽可能使用 ID——但要确保它们不是动态 ID,如果它们是,则适当地处理它们。

您提到您尝试过使用隐式等待。确保您了解隐式等待和显式等待之间的区别。(在 Selenium 文档中阅读更多内容。)您可能需要明确等待脚本中后续步骤的确切条件。不要重复不要在测试中使用 Thread.Sleep 或类似的手动延迟,除非在特殊情况下。WebDriver's Wait 是一种更好的方法。

于 2012-10-03T18:40:31.313 回答
2

我发现 Selenium 测试经常失败,因为页面元素没有正确加载,即使你设置了隐式等待。如果测试在同一点莫名其妙地失败,这对我有用。试试这个(我的代码是 C#,但你可以用其他语言来做):

在测试初始化​​设置等待:

globalWait = new WebDriverWait(驱动程序,TimeSpan.FromSeconds(20));

然后在加载麻烦的页面时调用等待: globalWait.Until(ExpectedConditions.ElementIsVisible(By.Id("myPageElement")));

这会强制等待,直到元素可见。它为我解决了很多问题。我经常将 id 设置为页脚元素,或者如果它是 AJAX 页面,则设置为 AJAX 检索到的元素之一。这可确保页面已正确加载。

另一种技术是为登录和注销编写一个通用例程,如果您正在执行大量复杂的测试,请登录,进行一些测试,注销,然后登录并进行更多测试。这似乎可以减少 Selenium 中的虚假错误。

我的 C# 登录例程:

private void Login()
{
    driver.Navigate().GoToUrl(base_url + "/login");
    globalWait.Until(ExpectedConditions.ElementIsVisible(By.Id("username")));
    driver.FindElement(By.Id("username")).SendKeys(username);
    // clear IE password autocomplete
    driver.FindElement(By.Id("password")).Clear();
    driver.FindElement(By.Id("password")).SendKeys(password);
    driver.FindElement(By.Id("btn_login")).Click();
}

我的注销程序:

private void LogOut()
{
    driver.FindElement(By.Id("lnkMenuLogout")).Click();
}

使用它们的测试:

[TestMethod]
public void EditAccount()
{
    Login();

    // navigate to account page
    driver.FindElement(By.Id("ulMenu")).FindElement(By.Id("lnkMenuAccount")).Click();
    Assert.IsTrue(driver.FindElement(By.Id("headName")).Displayed, "Player name not displayed");

    string playerChangeName = "Test" + DateTime.Now.ToString("yyyyMMddHHmmss");

    driver.FindElement(By.Id("butEditName")).Click();
    driver.FindElement(By.Id("surname")).Clear();
    driver.FindElement(By.Id("surname")).SendKeys(playerChangeName);
    driver.FindElement(By.Id("butSaveName")).Click();
    driver.Navigate().Refresh();

    // check that edit worked
    Assert.IsTrue(driver.FindElement(By.Id("headName")).Displayed, "Player name not displayed after change");
    IWebElement element = driver.FindElement(By.Id("headName"));
    string playerName = element.Text;
    StringAssert.Contains(playerName,playerChangeName,"Player name has not been changed");

    LogOut();
}

不过,我的最终结论是,目前,Selenium 仍然有些“脆弱”。我目前正在尝试使用 PhantomJS,但这似乎并没有更好。硒是我们拥有的最好的。

于 2016-08-12T13:11:28.357 回答
1

我对您的最佳答案是添加“可靠性和恢复代码”。

例如,也许您的测试试图点击某些东西,但无论出于何种原因,该 web 元素都会随机失效。因此,添加捕获 StaleElementExceptions 的代码并在真正失败之前最多重试 5 次。

或者,有时页面加载速度太慢,并且在 Selenium 认为完成之前内容尚未更新(AJAX 功能)。这会导致检查失败,但在查看屏幕截图时,页面实际上是正确的,因为这一切都发生在不到 0.2 秒的时间内。因此,在使用 assert 调用之前添加一个 selenium wait 等待内容更新。

这实际上为您提供了更可靠的结果,因为您的测试代码现在知道如何使用 selenium 框架处理常见情况。

希望这可以帮助!

于 2013-08-07T19:13:43.790 回答