在所有Scalatest测试之前或之后做一些事情

Gre*_*reg 70 scala scalatest

我有一套最新的测试,可以测试RESTful API的不同端点.我真的希望将它们分成不同的文件以获得最佳组织.

我的问题是如何在所有测试之前启动某些东西(在我的情况下是一个HTTP服务器,但它并不重要),并在完成所有测试后将其关闭.

我知道BeforeAndAfterAll,但这只能在一个测试文件内部/之后完成.我需要类似的东西,但对于所有测试,例如:

- 在测试之前启动http服务器
- 运行所有测试套件
- 关闭http服务器

Bil*_*ers 54

实现此目的的预期方法是使用嵌套套件.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
  }         
}
Run Code Online (Sandbox Code Playgroud)

但是,一个潜在的问题是,如果您使用发现来查找要运行的套件,则将发现所有三个EndpointTests,Foo和Bar.在ScalaTest 2.0中,您可以使用@DoNotDiscover注释Foo和Bar,而ScalaTest的Runner将不会发现它们.但是仍然会.我们目前正在增强sbt,以便它通过使用DoNotDiscover注释的其他可发现的套件,但这将是sbt 0.13,这还没有结束.在此期间,您可以通过向Foo和Bar添加未使用的构造函数参数来让sbt忽略它们.

  • 需要注意的是,使用这种方法我们失去了运行单个套件的能力. (3认同)
  • 有没有办法显示内部测试的结果?目前,如果它失败了,它只是认为EndpointTests失败了.很高兴看到套件里面的哪些测试失败了. (2认同)

Mac*_*uji 11

或者,您可以只使用一个对象.

object TestServer {
  startServer()
}
Run Code Online (Sandbox Code Playgroud)

当您访问该对象时,它将被初始化,启动服务器.只需在您访问该对象的主体中创建一个共同特征.然后将这种特性混合到所有测试中.完成.

如果您的服务器以守护进程模式运行(例如,测试模式下的Play!应用程序),它将在运行所有测试后自动关闭.


Gre*_*reg 9

好的,找到了办法.似乎(除非有人在这里纠正我)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
        }   
}
Run Code Online (Sandbox Code Playgroud)

好的,但测试怎么样?请注意with 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!") {  }
    }
}
Run Code Online (Sandbox Code Playgroud)