Can ScalaTest detect timeout without synchronization calls (like in an infinite loop?)

怎甘沉沦 提交于 2019-12-10 17:57:07

问题


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
    }
  }

}

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?

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.


回答1:


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.

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) {}
  }


}


来源:https://stackoverflow.com/questions/33742779/can-scalatest-detect-timeout-without-synchronization-calls-like-in-an-infinite

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!