scala 在所有 Scalatest 测试之前或之后做一些事情
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15423337/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Doing something before or after all Scalatest tests
提问by Greg
I have a suite of scalatest tests that test different endpoints of a RESTful API. I really want them separated into different files for best organization.
我有一套 scalatest 测试,用于测试 RESTful API 的不同端点。我真的希望将它们分成不同的文件以实现最佳组织。
My problem is how to start something (an HTTP server in my case, but it doesn't matter what it is) before all the tests and shut it down after all the tests are done.
我的问题是如何在所有测试之前启动一些东西(在我的例子中是一个 HTTP 服务器,但它是什么并不重要)并在所有测试完成后关闭它。
I know about BeforeAndAfterAll, but that only accomplishes before/after inside one test file. I need something like that, but for all tests, for example:
我知道BeforeAndAfterAll,但这只能在一个测试文件中之前/之后完成。我需要类似的东西,但对于所有测试,例如:
-- start http server before tests
-- run all test suites
-- shut down http server
-- 在测试前启动 http 服务器
-- 运行所有测试套件
-- 关闭 http 服务器
采纳答案by Bill Venners
The intended way to do this is to use nested suites. Suite has a nestedSuites method that returns an IndexedSeq[Suite] (in 2.0, in 1.9.1 it was a List[Suite]). Suite also has a runNestedSuites method that is responsible for executing any nested suites. By default runNestedSuites calls nestedSuites, and on each returned Suite either invokes run directly, or if a Distributor is passed, puts the nested suites in the distributor so that they can be run in parallel.
这样做的预期方法是使用嵌套套件。Suite 有一个 NestedSuites 方法,它返回一个 IndexedSeq[Suite](在 2.0 中,在 1.9.1 中它是一个 List[Suite])。Suite 还有一个 runNestedSuites 方法,负责执行任何嵌套的套件。默认情况下,runNestedSuites 调用nestedSuites,并且在每个返回的套件上直接调用run,或者如果传递了分发器,则将嵌套套件放入分发器中,以便它们可以并行运行。
So what you really probably want to do is make Foo and Bar into classes, and return instances of them from the nestedSuites method of EndpointTests. There's a class that makes that easy called Suites. Here's an example of its use:
所以你真正可能想做的是将 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
}
}
One potential problem, though, is that if you are using discovery to find Suites to run, all three of EndpointTests, Foo, and Bar will be discovered. In ScalaTest 2.0 you can annotate Foo and Bar with @DoNotDiscover, and ScalaTest's Runner will not discover them. But sbt still will. We are currently enhancing sbt so that it passes over otherwise discoverable Suites that are annotated with DoNotDiscover, but this will be in sbt 0.13, which isn't out yet. In the meantime you can get sbt to ignore them by adding an unused constructor parameter to Foo and Bar.
但是,一个潜在的问题是,如果您使用发现来查找要运行的套件,那么 EndpointTest、Foo 和 Bar 中的所有三个都将被发现。在 ScalaTest 2.0 中,您可以使用 @DoNotDiscover 注释 Foo 和 Bar,而 ScalaTest 的 Runner 不会发现它们。但是 sbt 仍然会。我们目前正在增强 sbt,以便它忽略使用 DoNotDiscover 注释的其他可发现的套件,但这将在 sbt 0.13 中,该版本尚未发布。同时,您可以通过向 Foo 和 Bar 添加未使用的构造函数参数来让 sbt 忽略它们。
回答by Machisuji
Alternatively you can just use an object.
或者,您可以只使用一个对象。
object TestServer {
startServer()
}
When you access the object it will be initialised, starting the server. Just create a common trait in the body of which you access the object. Then mixin that trait into all your tests. Done.
当您访问该对象时,它将被初始化,启动服务器。只需在访问对象的主体中创建一个共同特征。然后将该特征混合到所有测试中。完毕。
If your server runs in daemon mode (e.g. a Play! application in test mode) it will be automatically shut down after all tests are run.
如果您的服务器以守护程序模式运行(例如,测试模式下的 Play! 应用程序),它将在所有测试运行后自动关闭。
回答by Greg
Ok, found a way. It seems (unless someone here can correct me) that Scalatest does not have the facility of a "master" suite. But... you can kinda build one.
好的,找到方法了。似乎(除非这里有人可以纠正我)Scalatest 没有“主”套件的功能。但是......你可以建立一个。
You can compose a suite from traits. So using my endpoint example:
您可以从特征组成一个套件。所以使用我的端点示例:
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
}
}
Ok, but what about the tests? Notice the with Foowith Bar. I'm bringing the dependent tests in as traits.
See here:
好的,但是测试呢?注意Foowith 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!") { }
}
}

