Suite • opensavvy.prepared.suite • Prepared
Prepared¶
Lazily-generated value unique to a test case.
Usage¶
This helper allows to declare values that are needed by multiple tests, whilst ensuring each test gets its own distinct instance. Within a given test, however, the value is always the same:
suite("Random integers") {
val randomInteger by prepared { random.nextInt() }
test("First test") {
println(randomInteger()) // some integer
println(randomInteger()) // the same integer
}
test("Second test") {
println(randomInteger()) // another integer
}
}
Prepared values are constructed lazily when they are accessed within a test. Because of this, they have access to the test's TestDsl and can suspend
.
For the specific use-case of generating random values, see random.
Comparison with other frameworks¶
Test frameworks usually provide a construct like @BeforeTest
or similar. These constructs allow to declare instantiation code that is run before tests, however:
-
they are implicitly used by tests: in a large test file, it is difficult to know which ones may impact the test (whereas, prepared values must always be referred to in the test),
-
they have implicit ordering relationships: some
@BeforeTest
may use the result from previous ones, which makes it hard to know if removing one will impact test results (whereas, prepared values explicitly depend on each other), -
they require the need of some kind of
lateinit
variable to store their state (whereas, prepared values' state is available in all test scopes), -
they are not compatible with coroutines.
Test frameworks also tend to provide a construct like @AfterTest
, but again, this is covered by cleanUp. Prepared values can use cleanUp as well:
val database by prepared(Dispatchers.IO) {
val db = Database.connect()
cleanUp("Disconnect from the database") {
db.close()
}
db
}
test("Test") {
// if a prepared value is accessed in a test, it is automatically cleaned at the end of the test
database().listTables()
}
Values are instantiated using the prepared helper.