【发布时间】:2014-05-21 10:26:19
【问题描述】:
一旦我的测试尝试从一页移动到另一页,我真的很难弄清楚如何阻止 PHPUnit+Selenium 中断。例如,我做这样的事情:
public function myTest()
{
$this->clickOnElement('somelink');
$this->assertEquals('content', $this->byId('newElement'));
}
当我尝试运行它时,我收到如下错误:
1) myTestClass::myTest
PHPUnit_Extensions_Selenium2TestCase_WebDriverException: Element not found in the cache
- perhaps the page has changed since it was looked up
Command duration or timeout: 107 milliseconds
只有在两个页面之间移动时才会出现问题,并且您要查找的元素在两个页面上都存在(如标题或标题)。这里实际上有两个问题,都是竞争条件:
clickOnElement()开始加载下一页,但在此之前byId()在当前页面 上运行并找到该元素。然后浏览器完成加载新页面,assertContains()尝试从元素中获取值。但是新页面现在已经加载,我们拥有的元素引用来自 previous 页面。由于该元素不再存在于当前 DOM 中,因此您会收到有关过时元素的错误。clickOnElement()开始加载下一页,但在加载完成之前byId()在新的但未完全加载的页面上运行。由于页面尚未完成加载,您会收到“未找到元素”错误。
任何想法如何解决这两个问题?
【问题讨论】:
-
我可以问一个明显的问题:您确定页面上确实存在“somelink”吗?您的代码示例看起来应该在正常情况下工作。
-
还可以尝试分解为 clickOnElement 快捷方式:
$this->element($this->using('id')->value($id))->click();,但要分阶段进行并首先测试元素是否存在。 -
它确实存在于页面上,因为某些测试会在前几次失败但后来成功,即某处存在竞争条件。但是像这样的测试总是失败。此外,如果页面上不存在该元素,我会收到“找不到元素”错误而不是上面的错误,所以我相信这不是问题的原因。
-
body onload 触发时,原始页面源中的元素是否由后端提供?还是以后由 JavaScript 动态生成?还是任何其他的 ansyc 进程,例如 Api 回调?