Let’s consider the following test:
import de.cronn.validationfile.junit5.JUnit5ValidationFileAssertions;
class MyTest implements JUnit5ValidationFileAssertions {
@Test
void myTestMethod() {
assertWithFile("actual value");
}
}
When we run this test for the first time, it will create the following files:
data/test/output/MyTest_myTestMethod.txt
(this one always contains the actual value from the last run; this file should be ignored in your SCM) withactual value
data/test/validation/MyTest_myTestMethod.txt
(this one is prefilled automatically once during the first test run; on consecutive runs it will not be modified automatically) containing=== new file "data/test/validation/MyTest_myTestMethod.txt" === actual value
The test will fail as long as these two files are different. It’s the developer’s job to manually review the content of the validation
file and remove the "new file" marker to make the test passing.
The reviewed validation file is then committed to the SCM repository together with the test itself.
Starting from this point validation
file is the expected value of the test.
Any change to "actual value"
will cause the test to fail and in this case the developer has to compare the content of output
file with validation
and if satisfied copy output
to validation
- this makes the test green.
We recommend using a good diffing tool, such as the built-in differ of IntelliJ or Meld, that allows you to diff the two directories data/test/actual
vs data/test/validation
.
We also provide an IntelliJ plugin that diffs the two directories with one shortcut.
- Add the dependency
testImplementation 'de.cronn:validation-file-assertions:{version}'
<dependency>
<groupId>de.cronn</groupId>
<artifactId>validation-file-assertions</artifactId>
<version>{version}</version>
<scope>test</scope>
</dependency>
-
Configure your SCM
.gitignore
data/test/output/ data/test/tmp/
-
Let your test class implement the
JUnit5ValidationFileAssertions
interface if you are using JUnit5, otherwise useValidationFileAssertions
-
Pick suitable
assertWithFile
method and enjoy your first validation file assertion.
It is possible to customize path where validation files are stored, in order to do that:
-
Implement
de.cronn.assertions.validationfile.config.Configure
and override methodgetDataDirectory()
with path to desired location. -
Register implemented configuration via Java Service Provider interface (namely: put fully qualified configuration class name in
resources/META-INF/services/de.cronn.assertions.validationfile.config.Configuration
)
File based validation can be combined with AssertJ’s soft assertions.
import org.assertj.core.api.SoftAssertions;
import org.assertj.core.api.junit.jupiter.InjectSoftAssertions;
import org.assertj.core.api.junit.jupiter.SoftAssertionsExtension;
import de.cronn.validationfile.junit5.JUnit5ValidationFileAssertions;
@ExtendWith(SoftAssertionsExtension.class)
class MyTest implements JUnit5ValidationFileAssertions {
@InjectSoftAssertions
private SoftAssertions softly;
@Override
public FailedAssertionHandler failedAssertionHandler() {
return callable -> softly.check(callable::call);
}
@Test
void myTestMethod() {
assertWithFileWithSuffix("actual value 1", "file1");
assertWithFileWithSuffix("actual value 2", "file2");
}
}