Convenient snapshot testing for JUnit5 and JUnit4.
This library allows to conveniently assert on the structure and contents of complex objects. It does so by storing a serialized version of the object during the first test execution and during subsequent test executions, compare the actual object against the stored snapshot.
- Requires Java 11, supports Java 17
Supported test frameworks:
- JUnit5 (tested against
5.10.1
) via snapshot-tests-junit5 - JUnit4 (tested against
4.13.2
) via snapshot-tests-junit4
Supported snapshot formats:
- generic plain text (included by default via snapshot-tests-core)
- Json via snapshot-tests-json
- XML via snapshot-tests-xml xor snapshot-tests-xml-legacy
- HTML via snapshot-tests-html
Read more about snapshot testing in this accompanying blog post.
Please check out the GitHub release page to find Maven & Gradle coordinates for the latest release 1.11.0
Starting with release 1.8.0
we provide a new external reference documentation:
Over the course of the next releases most of the contents of this README will be transitioned into the new reference documentation.
(assumes using maven
, JUnit5
and snapshot-tests-json
artifact)
Add the following dependencies to your build
<dependency>
<groupId>de.skuzzle.test</groupId>
<artifactId>snapshot-tests-junit5</artifactId>
<version>1.11.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>de.skuzzle.test</groupId>
<artifactId>snapshot-tests-json</artifactId>
<version>1.11.0</version>
<scope>test</scope>
</dependency>
Annotate a test class with @EnableSnapshotTests
and declare a Snapshot
parameter in your test case:
@EnableSnapshotTests
class ComplexTest {
private WhatEverService classUnderTest = ...;
@Test
void testCreateComplexObject(Snapshot snapshot) throws Exception {
ComplexObject actual = classUnderTest.createComplexObject();
snapshot.assertThat(actual).as(JsonSnapshot.json).matchesSnapshotStructure();
}
}
Snapshot testing workflow:
- Implement your test cases and add one ore more snapshot assertions as shown above.
- When you now execute these tests the first time, serialized snapshots of your test results will be persisted and the tests will fail
- Execute the same tests again. Now, the framework will compare the test results against the persisted snapshots. If your code under test produces deterministic results, tests should now be green
- Check in the persisted snapshots into your SCM
Historically, JUnit5 is the preferred test framework and has always natively been supported. The preferred way of
configuring the build is to add a dependency to snapshot-tests-junit5
and optionally add a dependency for your
preferred snapshot format (i.e. like snapshot-tests-jackson
).
The snapshot-tests-junit5
module has been introduced with version 1.8.0
. Prior to that, you would either add a
direct dependency to snapshot-tests-core
or just use a single dependency to you preferred snapshot format which
would pull in the -core
module transitively. This setup still works but is discouraged. You will see a warning being
printed to System.err
stating the required migration steps.
Warning Starting from version
2.0.0
this scenario will no longer be supported.
JUnit4 support was introduced with version 1.8.0
. Add a dependency to snapshot-tests-junit4
and optionally
add a dependency for your preferred snapshot format like snapshot-tests-jackson
.
Warning In order to seamlessly support the JUnit5 legacy scenario described above, all snapshot format modules will still transitively pull in a JUnit5 dependency. Unfortunately this can only be fixed with the next major release. So long you might want to add a respective exclusion to your dependency:
<dependency>
<groupId>de.skuzzle.test</groupId>
<artifactId>snapshot-tests-json</artifactId>
<version>1.11.0</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
</exclusion>
</exclusions>
</dependency>
or
testImplementation('de.skuzzle.test:snapshot-tests-json:1.11.0') {
exclude group: 'org.junit.jupiter', module: 'junit-jupiter-api'
}
NOTE: Most parts of this readme have been migrated to the new reference documentation and thus were already removed from the readme.
New
Since version 1.7.0
there is a new @SnapshotTestOptions
annotation that can either be placed on a test method or
test class. It allows to configure some details of the snapshot testing engine.
Using @SnapshotTestOptions.textDiffContextLines()
you can advise the framework to print more lines surrounding a
detected change in the unified diffs. Per default, we will only print 5 lines around a change.
By default, line numbers in the diffs that are rendered in our assertion failure messages reflect the physical line number within the snapshot file. That number differs from the line number within the raw test result data because snapshot files contain some header information at the beginning. If you want line numbers in the diffs to reflect the number within the raw data, you can use
@SnapshotTestOptions(renderLineNumbers = DiffLineNumbers.ACCORDING_TO_RAW_DATA)