Usage
The basic entrance point is Recheck
with its implementation RecheckImpl
.
Methods
The essential methods are called check
. Upon first execution, the object is converted to a Golden Master and saved, identified by the name passed. Subsequent executions convert the object to the domain model to compare it against the existing Golden Master.
Failure
If there is no extension present that can handle the passed object, an exception is thrown. As described in installation, you need to have an extension available that is able to do the conversion.
Lifecycle
To locate the Golden Master (if present), Recheck
uses a lifecycle so that differences can be identified. The lifecycle of Recheck
can be described with three phases, where the earlier stages surround one or more of the directly following stage:
- Report: This is independent of the actual
Recheck
instance. It will simply collect all generated reports into onetests.report
, while preserving the individual report per suite. This phase is usually bound to the JVM. - Suite: Defined by the
Recheck
instance (e.g. a test class within JUnit). It is started by creating a new instance and ended byRecheck#cap()
, which will save the individual report containing all the differences encountered. - Test: Defined by a test execution (e.g. a test method in JUnit). It is started by
Recheck#startTest()
and ended byRecheck#capTest()
, which will produce anAssertionError
if there are differences or if the Golden Master could not be found (e.g. initial execution).
Within the test phase you can execute multiple checks. The created Golden Masters are then associated with the running suite and test phase.
Warning
You should make sure to call the methods in their respective order. While Recheck
will try its best to keep the lifecycle intact, it may still produce unexpected results or even errors.
Tip
You can use the corresponding extension for the test framework of your choice to administer the lifecycle so that the lifecycle methods will be called at the appropriate times.
Modifying the Lifecycle
A phase of the lifecycle is identified by a name that is either identified using the NamingStrategy
or you can overwrite it by passing a String
into the respective starting methods. If nothing is specified, Recheck
will try to automatically identify a name based on a valid test annotation for a class. If this fails or produces an incorrect name, a custom name must be specified.
Reuse Golden Master Files
This naming mechanism basically allows you to share Golden Masters. This can be used to test different setups for your object. A common use case would check if an operation was undone successfully (see example below).
re.startTest( "custom-name" );
// By defining the name, a golden master with the corresponding name will be created
re.check( object, "initial" );
// Perform an operation that changes the object
object.do();
// Verify the changed operation
re.check( object, "modified" );
// Undo the operation
object.undo();
// Instead of creating a new golden master, the exisiting is used and compared against
re.check( object, "initial" );
re.capTest();
An advanced use case would check different platforms, operating systems, languages, etc., and verify that those are the same. Ideally this would not happen within a single test phase (depending on your test framework), but encompass multiple test phases or even suite phases.
Tip
You may use the filtering mechanism to ignore expected differences. As an example for a language change you would ignore the text, because it changes as you would expect. Thus, you manipulate the definition of same by ignoring expected differences, while still allowing for other differences to be captured.
Integration in Test Frameworks and Plain Java
JUnit 4 (Vintage)
The following examples use JUnit 4 as test framework.
Using plain JUnit 4
public class JUnit4ExampleRecheckTest {
private Recheck re;
@Before
public void setUp() {
// Create your instance
re = new RecheckImpl();
}
@After
public void tearDown() {
// Save the report
re.cap();
}
@Test
public void check_simple_string() {
re.startTest();
// Create your object to check. An appropriate adapter must be present
final var object = ...;
// Create a golden master or check against, does not throw
re.check( object, "check-name" );
// Will fail if there are differences to the golden master
re.capTest();
}
}
Using recheck's JUnit 4 rule
Recheck's JUnit 4 extension can be found at recheck-junit-4-extension. It automatically ensures the lifecycle of recheck tests in JUnit 4.
public class JUnit4ExampleRecheckUsingExtensionTest {
// Will start and cap the test
@Rule
public final RecheckRule recheckRule = new RecheckRule();
private Recheck re;
@Before
public void setUp() {
// Create your instance
re = new RecheckImpl();
// Ensure the rule knows your Recheck instance
recheckRule.use( re );
}
@Test
public void check_simple_string() {
// Create your object to check. An appropriate adapter must be present
final var object = ...;
// Create a golden master or check against, does not throw
re.check( object, "check-name" );
}
}
JUnit 5 (Jupiter)
The following examples use JUnit 5 as test framework.
Using plain JUnit 5
class JUnit5ExampleRecheckTest {
Recheck re;
@BeforeEach
void setUp() {
// Create your instance
re = new RecheckImpl();
}
@AfterEach
void tearDown() {
// Save the report
re.cap();
}
@Test
void check_simple_string() {
re.startTest();
// Create your object to check. An appropriate adapter must be present
final var object = ...;
// Create a golden master or check against, does not throw
re.check( object, "check-name" );
// Will fail if there are differences to the golden master
re.capTest();
}
}
Using recheck's JUnit 5 extension
Recheck's JUnit Jupiter extension can be found at recheck-junit-jupiter-extension. It automatically ensures the lifecycle of recheck tests in JUnit 5.
// Will start and cap the test
@ExtendWith( RecheckExtension.class )
class JUnit5ExampleRecheckUsingExtensionTest {
Recheck re;
@BeforeEach
void setUp() {
// Create your instance
re = new RecheckImpl();
}
@Test
void check_simple_string() {
// Create your object to check. An appropriate adapter must be present
final var object = ...;
// Create a golden master or check against, does not throw
re.check( object, "check-name" );
}
}
TestNG
The following examples use JUnit 5 as test framework.
Using plain TestNG
class TestNGExampleRecheckTest {
Recheck re;
@BeforeMethod( alwaysRun = true )
void setUp() {
// Create your instance
re = new RecheckImpl();
}
@AfterMethod( alwaysRun = true )
void tearDown() {
// Save the report
re.cap();
}
@Test
void check_simple_string() {
re.startTest();
// Create your object to check. An appropriate adapter must be present
final var object = ...;
// Create a golden master or check against, does not throw
re.check( object, "check-name" );
// Will fail if there are differences to the golden master
re.capTest();
}
}
Using recheck's TestNG hook
// Will start and cap the test
@Listener( RecheckHook.class )
class TestNGExampleRecheckUsingExtensionTest {
Recheck re;
@Test
void check_simple_string() {
// Create your object to check. An appropriate adapter must be present
final var object = ...;
// Create a golden master or check against, does not throw
re.check( object, "check-name" );
}
}
Plain Java
class PlainJavaExampleRecheckTest {
public static void main( String[] args ) {
// Create your instance
var re = new RecheckImpl();
try {
re.startTest();
// Create your object to check. An appropriate adapter must be present
final var object = ...;
// Create a golden master or check against, does not throw
re.check( object, "check-name" );
// Will fail if there are differences to the golden master
re.capTest();
} finally {
// Save the report
re.cap();
}
}
}