我发现 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,但这似乎并没有更好。硒是我们拥有的最好的。