Selenium 硒和jUnit的不可预测行为

Selenium 硒和jUnit的不可预测行为,selenium,junit,Selenium,Junit,我正在开发一个网站,并试图用Selenium和jUnit对其进行测试。尽管我尽了最大的努力,我还是得到了测试和站点之间的比赛条件。 该站点的前端是HTML和jQuery。后端(通过AJAX)是PHP 网站 我有两个必填的文本输入字段(年份和年龄),另外还有一些在出现问题的测试中我不会更改的字段。一旦两个文本输入都非空,就会对后端进行AJAX调用。这将返回0+个结果。如果返回0个结果,屏幕上的results div会收到一些文本,表明没有结果。如果返回的结果大于0,则会将一个表写入显示结果的res

我正在开发一个网站,并试图用Selenium和jUnit对其进行测试。尽管我尽了最大的努力,我还是得到了测试和站点之间的比赛条件。 该站点的前端是HTML和jQuery。后端(通过AJAX)是PHP

网站

我有两个必填的文本输入字段(年份和年龄),另外还有一些在出现问题的测试中我不会更改的字段。一旦两个文本输入都非空,就会对后端进行AJAX调用。这将返回0+个结果。如果返回0个结果,屏幕上的results div会收到一些文本,表明没有结果。如果返回的结果大于0,则会将一个表写入显示结果的results div

我不希望网站等到输入了4位数的年份后再进行AJAX调用,因为它可能会查看古代历史(是的,真的)。因此,只要两者都不为空,就应该进行呼叫。如果您键入速度较慢,这意味着输入例如2015将触发对year=2、year=20、year=201和year=2015的调用。(这没关系。)

测试

我使用的是页面对象——一个用于输入,一个用于输出。在测试开始时,我等待屏幕上出现提示(请输入一些数据),因为这是由检查输入字段状态的JavaScript生成的,所以我知道页面已经加载,JavaScript已经运行

等待提示是在为输出创建页面对象之后立即进行的。这是页面对象中的相关方法:

// Wait until the prompt / help text is displayed.  Assumes that the prompt text always contains the word "Please"
public void waitForText() {
    wait.until(ExpectedConditions.textToBePresentInElementLocated(By.id("resultContainer"), "Please"));
}
设置年份的方法是

public void setYear(String year){

    WebElement yearField = driver.findElement(By.id(yearInputId));

    if (yearField == null) {
        // This should never happen
        Assert.fail("Can't find year input field using id " + yearInputId);
    } else {
        yearField.sendKeys(new String [] {year});
        driver.findElement(By.id(ageInputId)).click();  // click somewhere else
    }
}
还有一个对应的年龄

我有一系列等待事情发生的方法,这些方法似乎并没有阻止问题的发生(见下文)。这些操作包括等待当前结果值与以前的快照不同,等待返回一定数量的结果等

我为Chrome创建了一个驱动程序,如下所示:

import org.openqa.selenium.chrome.ChromeDriver;
// ...
        case CHROME: {
            System.setProperty("webdriver.chrome.driver", "C:\\path\\chromedriver.exe");
            result = new ChromeDriver();
            break;
        }
问题

有些时候,事情进展顺利。有时,两个输入都由测试用合理的值填充,但会显示“结果为0”消息。有时,通过填充输入,测试部分挂起。当我使用Firefox进行测试时,它看起来不错,但Chrome经常失败

存在不可预测的行为这一事实表明,我没有控制我需要控制的所有事情(和/或我控制事情的尝试是错误的)。我看不出我在做什么特别奇怪的事情,所以一定有人以前碰到过这种问题

是否存在我没有解决的浏览器问题? 我在设定值时有没有做错什么?
在我的测试编排中有什么地方我做错了吗?

可能是当您开始键入时,脚本仍在加载,或者当您开始处理下一个字段或验证时,有一个挂起的Ajax调用。 您可以尝试使用低级脚本同步调用:

const String JS_WAIT_NO_AJAX = 
    "var callback = arguments[0]; (function fn(){ " +
    "  if(window.$ && window.$.active == 0) " +
    "      return callback(); " +
    "  setTimeout(fn, 60); " +
    "})();";

JavascriptExecutor js = (JavascriptExecutor)driver;
driver.manage().timeouts().setScriptTimeout(20, TimeUnit.SECONDS);

js.executeAsyncScript(JS_WAIT_NO_AJAX);
driver.findElement(By.Id("...")).sendKeys("...");

js.executeAsyncScript(JS_WAIT_NO_AJAX);
driver.findElement(By.Id("...")).click();

通常情况下,实际的问题是其他的(如果AJAX调用提前将日期发送到后端,这可能导致查询的日期字符串为“16-01-01”,我没有填充到“0016-01-01”,以避免MySQL假设为“2016-01-01”)。不过还是要谢谢你,非常有用。