Selenium使用注意事项
行为的重试在WebDriver测试过程中,糟糕的问题在于误判的错误,这为自动化构建过程带来了很大的困难。对于Yarn的团队来说,这个问题也是他们所面对的头号大敌。为了克服这一点,他们为测试加入了重试的功能,使得测试结果得到很大的改善。 以下是这个重试方法的代码:
/**
* Try and take an action until it returns a value or we timeout
* @param maxWaitMillis the maximum amount of time to keep trying for in milliseconds
* @param pollIntervalMillis the amount of time to wait between retries in milliseconds
* @param callback a function that gets a value
* @tparam A the type of the callback
* @return whatever the callback returns, or throws an exception
*/
@annotation.tailrec
private def retry[A](maxWaitMillis: Long, pollIntervalMillis: Long)(callback: => A): A = {
val start = System.currentTimeMillis
Try {
callback
} match {
case Success(value) => value
case Failure(thrown) => {
val timeForTest = System.currentTimeMillis - start
val maxTimeToSleep = Math.min(maxWaitMillis - pollIntervalMillis, pollIntervalMillis)
val timeLeftToSleep = maxTimeToSleep - timeForTest
if (maxTimeToSleep <= 0) { throw thrown } else { if (timeLeftToSleep > 0) {
Thread.sleep(timeLeftToSleep)
}
retry(maxWaitMillis - pollIntervalMillis, pollIntervalMillis)(callback)
}
}
}
}这段代码的功能是通过一个简单的递归算法执行所传入的实际行为,直到该行为成功,或是运行超时为止。以下是使用这个方法的简单示例:
def numberOfChildren(implicit user: LucidUser): Int = {
getWithRetry() {
user.driver.getCssElement(visibleCss).children.size
}
}
测试集重试Yarn的团队所做的后一项改善是配置测试集的重试,测试集重试会将失败的测试缓存起来,然后重新运行这些失败的测试。只要在后续的重试中有一次成功,这项测试会被认为通过。否则将继续重试,直到重试次数达到上限为止。 Yarn的做法是尽量将一些依赖于第三方功能的行为区分开来,特意为这些功能的集成编写非常健壮的代码似乎没有什么意义,因此可以将它们放到一个可重试的测试集中。对于他们来说,重试的目的不是为了修复测试代码中的问题,而是为了消除测试报告中由误判所带来的影响。
创造乐趣Selenium的开发很容易令人感到疲惫,许多测试会无故地失败,让这些测试得到正确的结果是非常繁琐的工作,重复性的样板代码令人提不起兴致。而在Yarn的团队建立了一个可靠的、可维护以及可伸缩的框架之后,工作变得有趣起来了。各种有趣的想法层出不穷,有一位开发者实现了对绘画canvas截图并上传至Amazon S3服务的功能,随后又加入了一个截图比较的工具以实现图片比较测试。其它令人印象深刻的测试还包括与Google Drive、Yahoo与Google的单点登录等功能的整合。整个测试工作开始变得生动起来,这也为团队终实现了重构的目标带来了极大的推动力