我有一套 scalatest 测试,可以测试 RESTful API 的不同端点。 我真的希望它们分成不同的文件以便最好的组织。
我的问题是如何在所有测试之前启动某些东西(在我的例子中是一个HTTP服务器,但它是什么并不重要)并在所有测试完成后关闭它。
我知道 BeforeAndAfterAll,但这只能在一个测试文件内完成之前/之后。我需要类似的东西,但对于所有测试,例如:
-- 在测试之前启动 http 服务器
-- 运行所有测试套件
-- 关闭http服务器
执行此操作的预期方法是使用嵌套套件。 Suite 有一个nestedSuites 方法,它返回一个IndexedSeq[Suite](在2.0 中,在1.9.1 中它是一个List[Suite])。 Suite 还有一个 runNestedSuites 方法,负责执行任何嵌套套件。默认情况下,runNestedSuites 调用nestedSuites,并且在每个返回的 Suite 上直接调用运行,或者如果传递了分发器,则将嵌套套件放入分发器中,以便它们可以并行运行。
因此,您真正可能想要做的是将 Foo 和 Bar 放入类中,并从 EndpointTests 的nestedSuites 方法返回它们的实例。有一个类可以让这一切变得简单,称为“套房”。这是它的使用示例:
import org.scalatest._
import matchers.MustMatchers
class Foo extends FunSpec with MustMatchers {
describe("Message here...") {
it("Must do something") { }
it("Must be ok") { }
}
}
class Bar extends FunSpec with MustMatchers {
describe("Hello you...") {
it("One more!") { }
}
}
class EndpointTests extends Suites(new Foo, new Bar) with BeforeAndAfterAll {
override def beforeAll(configMap: Map[String, Any]) {
println("Before!") // start up your web server or whatever
}
override def afterAll(configMap: Map[String, Any]) {
println("After!") // shut down the web server
}
}
但是,一个潜在的问题是,如果您使用发现来查找要运行的套件,则所有三个 EndpointTests、Foo 和 Bar 都会被发现。在ScalaTest 2.0中,您可以使用@DoNotDiscover注释Foo和Bar,ScalaTest的Runner将不会发现它们。但 sbt 仍然会。我们目前正在增强 sbt,以便它超越其他可发现的带有 DoNotDiscover 注释的套件,但这将出现在尚未发布的 sbt 0.13 中。同时,您可以通过向 Foo 和 Bar 添加未使用的构造函数参数来让 sbt 忽略它们。
好的,找到方法了。看来(除非这里有人可以纠正我)Scalatest 没有“主”套件的设施。但是...你可以建造一个。
您可以根据特征组成套件。所以使用我的端点示例:
class EndpointTests extends FunSpec with MustMatchers with BeforeAndAfterAll
with Foo with Bar {
override def beforeAll(configMap: Map[String, Any]) {
println("Before!") // start up your web server or whatever
}
override def afterAll(configMap: Map[String, Any]) {
println("After!") // shut down the web server
}
}
好的,但是测试呢?注意
Foo
和 Bar
。我将依赖测试作为特征引入。
请看这里:
trait Foo extends FunSpec with MustMatchers {
describe("Message here...") {
it("Must do something") { }
it("Must be ok") { }
}
}
trait Bar extends FunSpec with MustMatchers {
describe("Hello you...") {
it("One more!") { }
}
}
或者你也可以只使用一个对象。
object TestServer {
startServer()
}
当您访问该对象时,它将被初始化,从而启动服务器。 只需在您访问对象的主体中创建一个公共特征即可。 然后将该特征混合到您的所有测试中。完成。
如果您的服务器在守护程序模式下运行(例如,Play!应用程序处于测试模式),它将在所有测试运行后自动关闭。
我没有足够的声誉来发表评论,但现在我们在scalatest中有
beforeAndAfterEach
https://www.scalatest.org/scaladoc/3.0.6/org/scalatest/BeforeAndAfterEach.html