Scala Specs2测试预期失败却显示通过及调试模式无法正常工作的问题咨询
你的Specs2测试代码存在语法结构错误,导致断言根本没有被执行。
在Specs2的语法规则里,should关键字后面必须紧跟一个代码块{},用来包裹所有测试用例的定义。你当前的写法把new WithApplication(App.application)直接放在should之后,Specs2无法识别这个实例作为有效的测试片段,因此里面的"return true" in { ... }代码块并没有被当作测试用例执行,自然不会触发断言失败。
修正后的代码:
class TestSpec extends Specification { sequential "Test" should { // 必须添加这个代码块来包裹测试用例 "return true" in new WithApplication(App.application) { val truFalse = true truFalse mustEqual false } } }
如果需要给所有测试用例统一注入WithApplication上下文,还可以用around方法简化:
class TestSpec extends Specification { sequential // 给所有测试用例自动绑定Application上下文 override def around[T: AsResult](t: => T): Result = { new WithApplication(App.application) { AsResult.effectively(t) } } "Test" should { "return true" in { val truFalse = true truFalse mustEqual false } } }
修改后断言会被正确执行,测试会按照预期失败。
调试断点不触发、println无输出通常和sbt的测试fork机制、输出缓冲有关,以下是针对性的解决方案:
1. 关闭测试进程fork(优先推荐)
sbt默认会fork新进程运行测试,这会导致调试器无法附加,同时println输出会被缓冲。在build.sbt中添加以下配置:
fork in Test := false logBuffered in Test := false
fork in Test := false:让测试在sbt主进程中运行,调试器可以直接附加,断点正常触发。logBuffered in Test := false:关闭输出缓冲,println内容会实时显示在控制台。
2. 必须fork进程时的调试配置
如果测试需要独立运行环境必须fork,可以配置调试参数让测试进程等待调试器连接:
在build.sbt中添加:
fork in Test := true javaOptions in Test += "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005"
运行测试时先执行sbt testOnly *TestSpec,此时测试进程会暂停等待调试连接。在IntelliJ中创建"Remote JVM Debug"配置,端口设为5005,启动调试器即可触发断点。
3. 清理重复的logback配置(辅助优化)
从你的日志可以看到classpath中存在两个logback.xml文件,这可能导致日志输出异常。建议只保留src/test/resources/logback.xml,删除src/main/resources/logback.xml,避免配置冲突。
4. IntelliJ IDEA额外配置
确保测试运行配置选择的是sbt Test类型,勾选"Debug"选项。如果已经设置fork in Test := false,调试会直接生效。
内容的提问来源于stack exchange,提问作者Slava

