我有一套scalatest测试,可以测试RESTful API的不同端点。 我真的希望将它们分成不同的文件以便最佳组织。
我的问题是如何在所有测试之前启动某些东西(在我的情况下是一个HTTP服务器,但它并不重要),并在所有测试完成后关闭它。
我知道BeforeAndAfterAll,但这只能在一个测试文件内部/之后完成。我需要这样的东西,但对于所有测试,例如:
- 在测试之前启动http服务器
- 运行所有测试套件
- 关闭http服务器
答案 0 :(得分:48)
执行此操作的预期方法是使用嵌套套件。 Suite有一个nestedSuites方法,它返回一个IndexedSeq [Suite](在2.0中,在1.9.1中它是一个List [Suite])。 Suite还有一个runNestedSuites方法,负责执行任何嵌套套件。默认情况下,runNestedSuites调用nestedSuites,并且在每个返回的Suite上直接调用run,或者如果传递了Distributor,则将嵌套套件放入分发器中,以便它们可以并行运行。
所以你真正想要做的是将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,以便它通过使用DoNotDiscover注释的其他可发现的套件,但这将是sbt 0.13,这还没有结束。在此期间,您可以通过向Foo和Bar添加未使用的构造函数参数来让sbt忽略它们。
答案 1 :(得分:10)
或者你可以只使用一个物体。
object TestServer {
startServer()
}
当您访问该对象时,它将被初始化,启动服务器。 只需在您访问该对象的主体中创建一个共同特征。 然后将这种特性混合到所有测试中。完成。
如果您的服务器以守护进程模式运行(例如,测试模式下的Play!应用程序),它将在所有测试运行后自动关闭。
答案 2 :(得分:8)
好的,找到了办法。似乎(除非有人在这里纠正我)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!") { }
}
}