ScalaTest是否可以在没有同步调用的情况下(例如在无限循环中)检测超时? [英] Can ScalaTest detect timeout without synchronization calls (like in an infinite loop?)
问题描述
在下面的代码中,名为sleep
的测试正常失败,而测试freeze
导致测试永无止境.
In a following code the test called sleep
fails gracefully, while the test freeze
causes the testing to never end.
import org.scalatest.FunSuite
import org.scalatest.concurrent.TimeLimitedTests
import org.scalatest.time.SpanSugar._
import scala.language.postfixOps
class MainTest extends FunSuite with TimeLimitedTests {
def timeLimit = 1 second
test("sleep") {
Thread.sleep(10000)
}
test("unintentional freeze") {
var i = 100
var j = 0
while (i>0) {
i += 1 // a bug: should be j += 1
i -= 1
}
}
}
我理解这一点是因为TimeLimitedTests
如何使用ThreadInterruptor
中止超时的测试.还有其他方法可以使ScalaTest检测到此类代码并使其失败吗?如果没有,是否存在一些常见的做法,如何避免或检测经过测试的代码中的此类错误?
I understand this because of the way how TimeLimitedTests
uses ThreadInterruptor
to abort timeouted tests. Is there some other way how can ScalaTest detect and fail such code? If not, is there some common practice how avoid or detect this type of bugs in the tested code?
当我在IDE中手动运行测试时,我可以手动中止测试,并且具有无限循环的测试将被标记为未启动,但是我担心当在提交的代码中发生这种情况时,Jenkins的构建过程会被冻结为结果,需要在构建服务器上手动中止.
When I run tests manually in the IDE, I can abort them manually and those with infinite loops will be marked as not started, but I am concerned that when this happens in a code committed, the Jenkins build process is frozen as a result, requiring a manual abort on the build server.
推荐答案
首先,您的示例是人为的.在现实生活中,甚至无限循环也至少在毫秒级内调用线程休眠:Thread.sleep(1)
.在这种情况下,interrupt
将正常工作.
First of all your example is artificial. In real life even infinite loops has invokes thread sleeping at least for millisecond: Thread.sleep(1)
. And in such case interrupt
will properly work.
但是假设没有睡觉.因此,您需要重写defaultInterrruptor
,以更可靠"的方式杀死线程.
But assume there are no sleeping. So you need to override defaultInterrruptor
to kill thread in more "reliable" way.
import org.scalatest.FunSuite
import org.scalatest.concurrent.{Interruptor, TimeLimitedTests, ThreadInterruptor, Timeouts}
import org.scalatest.time.SpanSugar._
import scala.language.postfixOps
class MainTest extends FunSuite with TimeLimitedTests {
override val defaultTestInterruptor: Interruptor = new Interruptor {
override def apply(testThread: Thread): Unit = {
println("Kindly die")
testThread.stop() // deprecated. unsafe. do not use
}
}
def timeLimit = 1 second
test("sleep") {
Thread.sleep(10000)
}
test("freeze") {
while (true) {}
}
}
这篇关于ScalaTest是否可以在没有同步调用的情况下(例如在无限循环中)检测超时?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!