Skip to content

Shared • Classic fixtures

Pure, immutable values generated once for the entire test suite.

Test fixtures without isolation

Info

The primary way to represent test fixtures with Prepared is to use prepared values. Prepared values are isolated between all test executions, guaranteeing that their access by a test cannot impact test output.

Shared values are computed once on first access, and then are shared between all running tests.

Danger

The result of an operation encapsulated into a shared value must be immutable. Otherwise, a test that mutates the value risks impacting other tests' execution, which could make the test suite flaky or cause different outputs based on execution order.

Using shared values

Shared values can be defined anywhere using the shared builder (including at the top-level) and are accessed using function-call syntax, similarly to prepared values.

import java.nio.file.Path
import kotlin.io.path.readText

val inputData by shared {
    Path.of("test-data/input.txt").readText()
}

test("Test 1") {
    doSomethingWith(inputData())
}

test("Test 2") {
    doSomethingElseWith(inputData())
}

Shared values otherwise behave the same as prepared values, and their syntax is identical.

Creating multiple shared values from the same generator

Although this is supported, it is not recommended. To learn why, see the reference.

Shared values do not have access to the test context

Unlike prepared values, which are executed once per test, and can thus access the current test's context, shared values are reused between multiple tests. Therefore, they cannot access the current test, and thus cannot access most of the functionality from this library.

For example, it is not possible to access randomness management or time control within shared values.

Danger

Shared values must always be produced using operations that are not observable by the test. Since shared values are only generated by the first test that refers to them, if the test is able to observe side effects from the generation, its behavior may be impacted by whether the value was indeed generated.

If this rule isn't respected, test execution order may have an impact on test results.

When to use shared values instead of prepared values?

As we have seen, prepared values are the recommended way to represent fixtures, and shared values have multiple risks.

Shared values are interesting when:

  • The generated value is immutable,
  • The generated value is too expensive to be computed once per test,
  • The generation of the value does not involve side effects which may change the output of a test.