Scala framework that manages external services for tests (mock HTTP services, docker containers, databases, etc.)
Central concept of the framework is a TestService:
trait TestService {
def name: String
def beforeSuite(): Unit = {}
def beforeTest(): Unit = {}
def afterTest(): Unit = {}
def afterSuite(): Unit = {}
}
It represents some process (OS process, JVM thread) that is run concurrently and separately from the test [suite] and provides useful function for it (inspired by [JUnits Rules] (https://github.com/junit-team/junit/wiki/Rules#externalresource-rules)) Some examples are: database, mock rest service, docker container, etc.
Test Service Kit manages lifecycle of TestService
s by calling following lifecycle methods:
def beforeSuite(): Unit
def beforeTest(): Unit
def afterTest(): Unit
def afterSuite(): Unit
Specific test service could be bound to test suite lifecycle only by mixing SuiteLifecycle trait, in this case it must implement
def start(): Unit // called before suite
def stop(): Unit // called after suite
or to test lifecycle only by mixing TestLifecycle trait, in which case it must implement
def start(): Unit // called before each test
def stop(): Unit // called after each test
Add the test-service-kit dependency to your SBT project
libraryDependencies += "org.zalando" %% "test-service-kit" % "6.0.0"
- Implement your own test service by extending TestService or use one of the already implemented test services:
- MockServerTestService to run MockServer instance. For example usage see MockServerTestServiceSpec
- DockerContainerTestService to run any Docker container. For example usage see DockerContainerTestServiceSpec
- DatabaseTestService to run embedded PostgreSQL server. For example usage see DatabaseTestServiceSpec
- JvmTestService to run JVM process. For example usage see JvmTestServiceSpec
- Mixin trait to your spec
- For ScalaTest: ScalatestServiceKit
- For Specs2: Specs2ServiceKit
- Define services used by your spec:
case MyCoolSpec extends FlatSpec with ScalatestServiceKit {
val oauthApi = new MockServerTestService("Mocked REST API", port = 8080) with SuiteLifecycle
val database = new DatabaseTestService("Embedded Postgres", port = 5432) with SuiteLifecycle
val container = new DockerContainerTestService(config.get[DockerContainerConfig]("docker-container")) with TestLifecycle
val app = new JvmTestService("My JVM App", mainClass = "org.zalando.test.kit.service.TestApplication") with SuiteLifecycle
}
- Define order in which test services are started/stopped:
case MyCoolSpec extends FlatSpec with ScalatestServiceKit {
...
override def testServices = (oauthApi || database) >> container
}
Legend:
a || b
(aliasa inParallelWith b
) means test servicesa
andb
are started/stopped concurrently.a >> b
(aliasa andThen b
) means test services are started one after another (a
thenb
) and stopped in reverse order (b
thena
).- For detailed example of composition see: TestServiceCompositionSpec
Copyright 2017 Yuriy Lazarev
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.