2) } } java.lang.AssertionError: expected:<5> but was:<4> Expected :5 Actual :4 <Click to see difference> Use-Site Coupling Today's tooling depends on JUnit Internals
2) } } java.lang.AssertionError: expected:<null> but was:<null> Expected :null Actual :null <Click to see difference> Use-Site Coupling Today's tooling depends on JUnit Internals
User @Rule val mockitoRule = MockitoJUnitRule.rule() // ... } Runner vs Rule: Two concepts for test extension Ambiguous Evolution Conflicting requirements reduced clarity
@TestFactory fun createDynamicTests(): List<DynamicTest> = listOf( dynamicTest("A Dynamic Test") { assertEquals(4, 2 + 2) }, dynamicTest("Another One") { assertEquals(0, 2 - 2) } ) } • Tests generated at runtime • Individual DynamicTest objects do not partake in the lifecycle of a test case (@BeforeEach etc.) • Generally, prefer @ParameterizedTest
for Test Extension • Replacement for @RunWith & @Rule • Repeatable annotation → allows composition • Different interfaces provide hooks into the system • Usage Example: Integration with existing libraries • Complex topic deserving of its own talk
onView(withId(R.id.textView)).check(...) tested.finishActivity() } } Espresso Test with JUnit 5 @ActivityTest(MyActivity::class) Test Extension with custom Configuration Parameters: •targetPackage •launchFlags •launchActivity •…
onView(withId(R.id.textView)).check(...) tested.finishActivity() } } Espresso Test with JUnit 5 fun testSomething(tested: Tested<MyActivity>) Access to Activity under test, successor to old ActivityTestRule: •Tested#launchActivity •Tested#finishActivity •Tested#getActivityResult