sbt运行Dynamicaly Created Tests无执行记录问题及Scala动态测试方案问询
ScalaTest动态测试sbt无执行问题解决方案
问题根因
你提供的测试代码不符合AnyWordSpec的语法规范:测试断言块前缺少必要的in关键字。IntelliJ内置的测试运行器对非标准写法做了兼容,因此可以正常识别执行测试;但sbt调用的官方ScalaTest运行器仅会识别通过in关键字显式注册的测试用例,因此出现测试套件被加载、但无测试执行的情况。
另外注意sbt的标准测试执行命令为sbt test,拼写错误也可能导致执行异常。
修复方案
补全in关键字,规范测试注册逻辑即可,修改后的参考代码如下:
import org.scalatest.wordspec.AnyWordSpec class ExampleTest extends AnyWordSpec { def runTests() = { for( n <- 1 until 10){ testNumber(n) } } def testNumber(n: Int) = { "testNumber" when { s"gets the number ${n}" should { // 补全in关键字,完成测试注册 "fail if the number is different than 0" in { assert(n == 0) } } } } runTests() }
修改后执行sbt test即可正常识别9条测试用例,全部返回预期的失败结果。
其他动态创建测试的实现方式
1. 类体直接循环注册
不需要封装额外的测试注册方法,直接在类初始化阶段循环注册测试,写法更简洁,避免方法执行时机导致的注册失败问题:
import org.scalatest.wordspec.AnyWordSpec class ExampleTest extends AnyWordSpec { for( n <- 1 until 10) { "testNumber" when { s"gets the number ${n}" should { "fail if the number is different than 0" in { assert(n == 0) } } } } }
2. 表驱动参数化测试
ScalaTest官方推荐的批量测试实现方式,可读性和可维护性更高,需要引入scalatestplus-scalacheck依赖,示例如下:
import org.scalatest.wordspec.AnyWordSpec import org.scalatestplus.scalacheck.ScalaCheckDrivenPropertyChecks class ExampleTest extends AnyWordSpec with ScalaCheckDrivenPropertyChecks { // 定义测试参数表,首项为参数名,后续为所有测试用例入参 private val testCases = Table( "testNumber", 1,2,3,4,5,6,7,8,9 ) "testNumber" when { "gets input n" should { "fail if n is not 0" in { forAll(testCases) { n => assert(n == 0) } } } } }
3. 单测试内循环断言
如果不需要每个参数对应单独的测试报告条目,可以直接在单个测试内循环执行断言,性能更高,适合测试用例数量较大的场景。
内容的提问来源于stack exchange,提问作者dod haim
相关产品推荐
相关产品推荐

