diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4e3e64c77..450a8d029 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -116,6 +116,16 @@ All tests shall use [AssertJ](https://joel-costigliola.github.io/assertj/)'s ass Yes, use it even if Jupiter's assertions are as good or better (c.f. `assertTrue(bool)` vs `assertThat(bool).isTrue()`) - that will spare us the discussion which assertion to use in a specific case. +Pioneer now has its own assertions for asserting not directly executed tests. +This means asserting `ExecutionResults`. +We can divide those kinds of assertions into two categories: test case assertions and test suite assertions. + - Test case assertions are the ones where you assert a single test, e.g.: it failed with an exception or succeeded. + For those, use the assertions that being with `hasSingle...`, e.g.: `hasSingleSucceededTest()`. + - Test suite assertions are the ones where you assert multiple tests and their outcomes, e.g.: three tests started, two failed, one succeeded. + For those, use the assertions that being with `hasNumberOf...`, e.g.: `hasNumberOfFailedTests(1)`. + +Do not mix the two - while technically correct (meaning you _can_ write `hasNumberOfFailedTests(3).hasSingleSucceededTest()`) it is better to handle them separately. + ### Documentation There are several aspects of this project's documentation. diff --git a/src/test/java/org/junitpioneer/jupiter/DefaultLocaleTests.java b/src/test/java/org/junitpioneer/jupiter/DefaultLocaleTests.java index 94c8c8c1a..f15fddd61 100644 --- a/src/test/java/org/junitpioneer/jupiter/DefaultLocaleTests.java +++ b/src/test/java/org/junitpioneer/jupiter/DefaultLocaleTests.java @@ -13,6 +13,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junitpioneer.testkit.PioneerTestKit.executeTestClass; import static org.junitpioneer.testkit.PioneerTestKit.executeTestMethod; +import static org.junitpioneer.testkit.assertion.PioneerAssert.assertThat; import java.util.Locale; @@ -98,7 +99,7 @@ void setUp() { void shouldExecuteTestsWithConfiguredLocale() { ExecutionResults results = executeTestClass(ClassLevelTestCase.class); - assertThat(results.numberOfSucceededTests()).isEqualTo(2); + assertThat(results).hasNumberOfSucceededTests(2); } @AfterEach @@ -177,7 +178,9 @@ void shouldFailWhenNothingIsConfigured() { ExecutionResults results = executeTestMethod(MethodLevelInitializationFailureTestCase.class, "shouldFailMissingConfiguration"); - results.assertTestFailedWithThrowable(ExtensionConfigurationException.class); + assertThat(results) + .hasSingleFailedTest() + .withExceptionInstanceOf(ExtensionConfigurationException.class); } @Test @@ -186,7 +189,9 @@ void shouldFailWhenVariantIsSetButCountryIsNot() { ExecutionResults results = executeTestMethod(MethodLevelInitializationFailureTestCase.class, "shouldFailMissingCountry"); - results.assertTestFailedWithExtensionConfigurationException(); + assertThat(results) + .hasSingleFailedTest() + .withExceptionInstanceOf(ExtensionConfigurationException.class); } @Test @@ -195,7 +200,9 @@ void shouldFailWhenLanguageTagAndLanguageIsSet() { ExecutionResults results = executeTestMethod(MethodLevelInitializationFailureTestCase.class, "shouldFailLanguageTagAndLanguage"); - results.assertTestFailedWithExtensionConfigurationException(); + assertThat(results) + .hasSingleFailedTest() + .withExceptionInstanceOf(ExtensionConfigurationException.class); } @Test @@ -204,7 +211,9 @@ void shouldFailWhenLanguageTagAndCountryIsSet() { ExecutionResults results = executeTestMethod(MethodLevelInitializationFailureTestCase.class, "shouldFailLanguageTagAndCountry"); - results.assertTestFailedWithExtensionConfigurationException(); + assertThat(results) + .hasSingleFailedTest() + .withExceptionInstanceOf(ExtensionConfigurationException.class); } @Test @@ -213,7 +222,9 @@ void shouldFailWhenLanguageTagAndVariantIsSet() { ExecutionResults results = executeTestMethod(MethodLevelInitializationFailureTestCase.class, "shouldFailLanguageTagAndVariant"); - results.assertTestFailedWithExtensionConfigurationException(); + assertThat(results) + .hasSingleFailedTest() + .withExceptionInstanceOf(ExtensionConfigurationException.class); } } @@ -227,8 +238,9 @@ class ClassLevel { void shouldFailWhenVariantIsSetButCountryIsNot() { ExecutionResults results = executeTestClass(ClassLevelInitializationFailureTestCase.class); - assertThat(results.numberOfFailedContainers()).isEqualTo(1); - assertThat(results.firstFailuresThrowable()).isInstanceOf(ExtensionConfigurationException.class); + assertThat(results) + .hasSingleFailedContainer() + .withExceptionInstanceOf(ExtensionConfigurationException.class); } } diff --git a/src/test/java/org/junitpioneer/jupiter/DefaultTimeZoneTests.java b/src/test/java/org/junitpioneer/jupiter/DefaultTimeZoneTests.java index 2282e2d7c..c1ed6325c 100644 --- a/src/test/java/org/junitpioneer/jupiter/DefaultTimeZoneTests.java +++ b/src/test/java/org/junitpioneer/jupiter/DefaultTimeZoneTests.java @@ -14,6 +14,7 @@ import static org.assertj.core.api.Assertions.fail; import static org.junitpioneer.testkit.PioneerTestKit.executeTestClass; import static org.junitpioneer.testkit.PioneerTestKit.executeTestMethod; +import static org.junitpioneer.testkit.assertion.PioneerAssert.assertThat; import java.util.TimeZone; @@ -68,11 +69,11 @@ void doesNothingWhenAnnotationNotPresent() { void throwsWhenConfigurationIsBad() { ExecutionResults results = executeTestMethod(BadMethodLevelConfigurationTestCase.class, "badConfiguration"); - assertThat(results.numberOfFailedTests()).isEqualTo(1); - assertThat(results.firstFailuresThrowable()).isExactlyInstanceOf(ExtensionConfigurationException.class); - assertThat(results.firstFailuresThrowableMessage()) - .doesNotContain("should never execute") - .contains("@DefaultTimeZone not configured correctly."); + assertThat(results) + .hasSingleFailedTest() + .withExceptionInstanceOf(ExtensionConfigurationException.class) + .hasMessageNotContaining("should never execute") + .hasMessageContaining("@DefaultTimeZone not configured correctly."); } @DefaultTimeZone("GMT") @@ -112,7 +113,7 @@ void setUp() { void shouldExecuteTestsWithConfiguredTimeZone() { ExecutionResults results = executeTestClass(ClassLevelTestCase.class); - assertThat(results.numberOfSucceededTests()).isEqualTo(2); + assertThat(results).hasNumberOfSucceededTests(2); } @Test @@ -120,9 +121,11 @@ void shouldExecuteTestsWithConfiguredTimeZone() { void shouldThrowWithBadConfiguration() { ExecutionResults results = executeTestClass(BadClassLevelConfigurationTestCase.class); - assertThat(results.numberOfStartedTests()).isEqualTo(0); - assertThat(results.firstFailuresThrowable()).isExactlyInstanceOf(ExtensionConfigurationException.class); - assertThat(results.firstFailuresThrowableMessage()).contains("@DefaultTimeZone not configured correctly."); + assertThat(results).hasNumberOfStartedTests(0); + assertThat(results) + .hasSingleFailedContainer() + .withExceptionInstanceOf(ExtensionConfigurationException.class) + .hasMessageContaining("@DefaultTimeZone not configured correctly."); } @Test @@ -130,7 +133,7 @@ void shouldThrowWithBadConfiguration() { void shouldNotThrowForExplicitGmt() { ExecutionResults results = executeTestClass(ExplicitGmtClassLevelTestCase.class); - assertThat(results.numberOfSucceededTests()).isEqualTo(1); + assertThat(results).hasSingleSucceededTest(); } @AfterEach diff --git a/src/test/java/org/junitpioneer/jupiter/EnvironmentVariableExtensionTests.java b/src/test/java/org/junitpioneer/jupiter/EnvironmentVariableExtensionTests.java index 2032ab943..bc9d4e0af 100644 --- a/src/test/java/org/junitpioneer/jupiter/EnvironmentVariableExtensionTests.java +++ b/src/test/java/org/junitpioneer/jupiter/EnvironmentVariableExtensionTests.java @@ -15,6 +15,7 @@ import static org.junitpioneer.jupiter.EnvironmentVariableExtension.WARNING_VALUE; import static org.junitpioneer.testkit.PioneerTestKit.executeTestClass; import static org.junitpioneer.testkit.PioneerTestKit.executeTestMethod; +import static org.junitpioneer.testkit.assertion.PioneerAssert.assertThat; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; @@ -23,6 +24,7 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtensionConfigurationException; import org.junitpioneer.testkit.ExecutionResults; @DisplayName("EnvironmentVariable extension") @@ -209,7 +211,7 @@ void shouldFailWhenClearAndSetSameEnvironmentVariable() { ExecutionResults results = executeTestMethod(MethodLevelInitializationFailureTestCase.class, "shouldFailWhenClearAndSetSameEnvironmentVariable"); - results.assertTestFailedWithExtensionConfigurationException(); + assertThat(results).hasSingleFailedTest().withExceptionInstanceOf(ExtensionConfigurationException.class); } @Test @@ -221,7 +223,7 @@ void shouldFailWhenClearSameEnvironmentVariableTwice() { ExecutionResults results = executeTestMethod(MethodLevelInitializationFailureTestCase.class, "shouldFailWhenClearSameEnvironmentVariableTwice"); - results.assertTestFailedWithExtensionConfigurationException(); + assertThat(results).hasSingleFailedTest().withExceptionInstanceOf(ExtensionConfigurationException.class); } @Test @@ -230,7 +232,7 @@ void shouldFailWhenSetSameEnvironmentVariableTwice() { ExecutionResults results = executeTestMethod(MethodLevelInitializationFailureTestCase.class, "shouldFailWhenSetSameEnvironmentVariableTwice"); - results.assertTestFailedWithExtensionConfigurationException(); + assertThat(results).hasSingleFailedTest().withExceptionInstanceOf(ExtensionConfigurationException.class); } } @@ -247,21 +249,21 @@ void resetWarning() { void shouldNotReportWarningIfExtensionNotUsed() { ExecutionResults results = executeTestMethod(ReportWarningTestCases.class, "testWithoutExtension"); - assertThat(results.reportEntries()).hasSize(0); + assertThat(results).hasNoReportEntries(); } @Test void shouldReportWarningIfExtensionUsed() { ExecutionResults results = executeTestMethod(ReportWarningTestCases.class, "testWithExtension"); - assertThat(results.singleReportEntry()).isEqualTo(TestUtils.entryOf(WARNING_KEY, WARNING_VALUE)); + assertThat(results).hasSingleReportEntry().withKeyAndValue(WARNING_KEY, WARNING_VALUE); } @Test void shouldReportWarningExactlyOnce() { ExecutionResults results = executeTestClass(ReportWarningTestCases.class); - assertThat(results.reportEntries()).hasSize(1); + assertThat(results).hasSingleReportEntry(); } } diff --git a/src/test/java/org/junitpioneer/jupiter/PioneerAnnotationUtilsTests.java b/src/test/java/org/junitpioneer/jupiter/PioneerAnnotationUtilsTests.java index 0b812492e..b8058ec07 100644 --- a/src/test/java/org/junitpioneer/jupiter/PioneerAnnotationUtilsTests.java +++ b/src/test/java/org/junitpioneer/jupiter/PioneerAnnotationUtilsTests.java @@ -10,6 +10,8 @@ package org.junitpioneer.jupiter; +import static org.junitpioneer.testkit.assertion.PioneerAssert.assertThat; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; @@ -52,7 +54,7 @@ void discoversMethodAnnotation() { ExecutionResults results = PioneerTestKit .executeTestMethod(PioneerAnnotationUtilsTestCases.FailTestCases.class, "methodIsAnnotated"); - results.assertFailedTestHasMessage("method"); + assertThat(results).hasSingleFailedTest().withException().hasMessageContaining("method"); } @Test @@ -60,7 +62,7 @@ void discoversRootClassAnnotation() { ExecutionResults results = PioneerTestKit .executeTestMethod(PioneerAnnotationUtilsTestCases.FailTestCases.RootClassTestCases.class, "rootClassIsAnnotated"); - results.assertFailedTestHasMessage("root class"); + assertThat(results).hasSingleFailedTest().withException().hasMessageContainingAll("root class"); } @Test @@ -68,7 +70,7 @@ void discoversClassAnnotation() { ExecutionResults results = PioneerTestKit .executeTestMethod(PioneerAnnotationUtilsTestCases.FailTestCases.NestedTestCases.class, "classIsAnnotated"); - results.assertFailedTestHasMessage("nested class"); + assertThat(results).hasSingleFailedTest().withException().hasMessageContaining("nested class"); } @Test @@ -77,7 +79,7 @@ void discoversOuterClassAnnotation() { .executeTestMethod( PioneerAnnotationUtilsTestCases.FailTestCases.NestedTestCases.TwiceNestedTestCases.class, "outerClassIsAnnotated"); - results.assertFailedTestHasMessage("nested class"); + assertThat(results).hasSingleFailedTest().withException().hasMessageContaining("nested class"); } @Test @@ -86,7 +88,7 @@ void discoversOuterOuterClassAnnotation() { .executeTestMethod( PioneerAnnotationUtilsTestCases.FailTestCases.NestedTestCases.TwiceNestedTestCases.ThriceNestedTestCases.class, "outerClassIsAnnotated"); - results.assertFailedTestHasMessage("nested class"); + assertThat(results).hasSingleFailedTest().withException().hasMessageContaining("nested class"); } } @@ -105,7 +107,10 @@ void discoversMethodAnnotation() { ExecutionResults results = PioneerTestKit .executeTestMethod(PioneerAnnotationUtilsTestCases.FailTestCases.class, "methodIsAnnotated"); - results.assertFailedTestHasMessage("method", "root class"); + assertThat(results) + .hasSingleFailedTest() + .withException() + .hasMessageContainingAll("method", "root class"); } @Test @@ -113,7 +118,7 @@ void discoversRootClassAnnotation() { ExecutionResults results = PioneerTestKit .executeTestMethod(PioneerAnnotationUtilsTestCases.FailTestCases.RootClassTestCases.class, "rootClassIsAnnotated"); - results.assertFailedTestHasMessage("root class"); + assertThat(results).hasSingleFailedTest().withException().hasMessageContaining("root class"); } @Test @@ -121,7 +126,10 @@ void discoversClassAnnotation() { ExecutionResults results = PioneerTestKit .executeTestMethod(PioneerAnnotationUtilsTestCases.FailTestCases.NestedTestCases.class, "classIsAnnotated"); - results.assertFailedTestHasMessage("nested class", "root class"); + assertThat(results) + .hasSingleFailedTest() + .withException() + .hasMessageContainingAll("nested class", "root class"); } @Test @@ -130,7 +138,10 @@ void discoversOuterClassAnnotation() { .executeTestMethod( PioneerAnnotationUtilsTestCases.FailTestCases.NestedTestCases.TwiceNestedTestCases.class, "outerClassIsAnnotated"); - results.assertFailedTestHasMessage("nested class", "root class"); + assertThat(results) + .hasSingleFailedTest() + .withException() + .hasMessageContainingAll("nested class", "root class"); } @Test @@ -139,7 +150,10 @@ void discoversOuterOuterClassAnnotation() { .executeTestMethod( PioneerAnnotationUtilsTestCases.FailTestCases.NestedTestCases.TwiceNestedTestCases.ThriceNestedTestCases.class, "outerClassIsAnnotated"); - results.assertFailedTestHasMessage("nested class", "root class"); + assertThat(results) + .hasSingleFailedTest() + .withException() + .hasMessageContainingAll("nested class", "root class"); } } @@ -164,7 +178,7 @@ void discoversMethodAnnotation() { ExecutionResults results = PioneerTestKit .executeTestMethod(PioneerAnnotationUtilsTestCases.RepeatableFailTestCases.class, "methodIsAnnotated"); - results.assertFailedTestHasMessage("method"); + assertThat(results).hasSingleFailedTest().withException().hasMessageContainingAll("method"); } @Test @@ -173,7 +187,7 @@ void discoversRootClassAnnotation() { .executeTestMethod( PioneerAnnotationUtilsTestCases.RepeatableFailTestCases.RootClassTestCases.class, "rootClassIsAnnotated"); - results.assertFailedTestHasMessage("root class"); + assertThat(results).hasSingleFailedTest().withException().hasMessageContainingAll("root class"); } @Test @@ -181,7 +195,10 @@ void discoversRepeatedMethodAnnotation() { ExecutionResults results = PioneerTestKit .executeTestMethod(PioneerAnnotationUtilsTestCases.RepeatableFailTestCases.class, "methodIsRepeatablyAnnotated"); - results.assertFailedTestHasMessage("repeated", "annotation"); + assertThat(results) + .hasSingleFailedTest() + .withException() + .hasMessageContainingAll("repeated", "annotation"); } @Test @@ -190,7 +207,7 @@ void discoversClassAnnotation() { .executeTestMethod( PioneerAnnotationUtilsTestCases.RepeatableFailTestCases.NestedTestCases.class, "classIsAnnotated"); - results.assertFailedTestHasMessage("nested class"); + assertThat(results).hasSingleFailedTest().withException().hasMessageContainingAll("nested class"); } @Test @@ -199,7 +216,7 @@ void discoversOuterClassAnnotation() { .executeTestMethod( PioneerAnnotationUtilsTestCases.RepeatableFailTestCases.NestedTestCases.TwiceNestedTestCases.class, "outerClassIsAnnotated"); - results.assertFailedTestHasMessage("nested class"); + assertThat(results).hasSingleFailedTest().withException().hasMessageContainingAll("nested class"); } @Test @@ -208,7 +225,7 @@ void discoversOuterOuterClassAnnotation() { .executeTestMethod( PioneerAnnotationUtilsTestCases.RepeatableFailTestCases.NestedTestCases.TwiceNestedTestCases.ThriceNestedTestCases.class, "outerClassIsAnnotated"); - results.assertFailedTestHasMessage("nested class"); + assertThat(results).hasSingleFailedTest().withException().hasMessageContainingAll("nested class"); } @Test @@ -217,7 +234,10 @@ void discoversRepeatedOuterClassAnnotation() { .executeTestMethod( PioneerAnnotationUtilsTestCases.RepeatableFailTestCases.NestedRepeatableTestCases.class, "outerClassIsRepeatablyAnnotatedAnnotated"); - results.assertFailedTestHasMessage("repeated", "annotation"); + assertThat(results) + .hasSingleFailedTest() + .withException() + .hasMessageContainingAll("repeated", "annotation"); } } @@ -236,7 +256,10 @@ void discoversMethodAnnotation() { ExecutionResults results = PioneerTestKit .executeTestMethod(PioneerAnnotationUtilsTestCases.RepeatableFailTestCases.class, "methodIsAnnotated"); - results.assertFailedTestHasMessage("method", "root class"); + assertThat(results) + .hasSingleFailedTest() + .withException() + .hasMessageContainingAll("method", "root class"); } @Test @@ -245,7 +268,7 @@ void discoversRootClassAnnotation() { .executeTestMethod( PioneerAnnotationUtilsTestCases.RepeatableFailTestCases.RootClassTestCases.class, "rootClassIsAnnotated"); - results.assertFailedTestHasMessage("root class"); + assertThat(results).hasSingleFailedTest().withException().hasMessageContainingAll("root class"); } @Test @@ -253,7 +276,10 @@ void discoversRepeatedMethodAnnotation() { ExecutionResults results = PioneerTestKit .executeTestMethod(PioneerAnnotationUtilsTestCases.RepeatableFailTestCases.class, "methodIsRepeatablyAnnotated"); - results.assertFailedTestHasMessage("repeated", "annotation", "root class"); + assertThat(results) + .hasSingleFailedTest() + .withException() + .hasMessageContainingAll("repeated", "annotation", "root class"); } @Test @@ -262,7 +288,10 @@ void discoversClassAnnotation() { .executeTestMethod( PioneerAnnotationUtilsTestCases.RepeatableFailTestCases.NestedTestCases.class, "classIsAnnotated"); - results.assertFailedTestHasMessage("nested class", "root class"); + assertThat(results) + .hasSingleFailedTest() + .withException() + .hasMessageContainingAll("nested class", "root class"); } @Test @@ -271,7 +300,10 @@ void discoversOuterClassAnnotation() { .executeTestMethod( PioneerAnnotationUtilsTestCases.RepeatableFailTestCases.NestedTestCases.TwiceNestedTestCases.class, "outerClassIsAnnotated"); - results.assertFailedTestHasMessage("nested class", "root class"); + assertThat(results) + .hasSingleFailedTest() + .withException() + .hasMessageContainingAll("nested class", "root class"); } @Test @@ -280,7 +312,10 @@ void discoversOuterOuterClassAnnotation() { .executeTestMethod( PioneerAnnotationUtilsTestCases.RepeatableFailTestCases.NestedTestCases.TwiceNestedTestCases.ThriceNestedTestCases.class, "outerClassIsAnnotated"); - results.assertFailedTestHasMessage("nested class", "root class"); + assertThat(results) + .hasSingleFailedTest() + .withException() + .hasMessageContainingAll("nested class", "root class"); } @Test @@ -290,7 +325,10 @@ void discoversRepeatedOuterClassAnnotation() { PioneerAnnotationUtilsTestCases.RepeatableFailTestCases.NestedRepeatableTestCases.class, "outerClassIsRepeatablyAnnotatedAnnotated"); - results.assertFailedTestHasMessage("repeated", "annotation", "root class"); + assertThat(results) + .hasSingleFailedTest() + .withException() + .hasMessageContainingAll("repeated", "annotation", "root class"); } } diff --git a/src/test/java/org/junitpioneer/jupiter/ReportEntryExtensionTests.java b/src/test/java/org/junitpioneer/jupiter/ReportEntryExtensionTests.java index 79f5ff870..25824a8fb 100644 --- a/src/test/java/org/junitpioneer/jupiter/ReportEntryExtensionTests.java +++ b/src/test/java/org/junitpioneer/jupiter/ReportEntryExtensionTests.java @@ -10,16 +10,12 @@ package org.junitpioneer.jupiter; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.fail; import static org.junitpioneer.jupiter.ReportEntry.PublishCondition.ALWAYS; import static org.junitpioneer.jupiter.ReportEntry.PublishCondition.ON_ABORTED; import static org.junitpioneer.jupiter.ReportEntry.PublishCondition.ON_FAILURE; import static org.junitpioneer.jupiter.ReportEntry.PublishCondition.ON_SUCCESS; - -import java.util.List; -import java.util.Map; +import static org.junitpioneer.testkit.assertion.PioneerAssert.assertThat; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.DisplayName; @@ -40,11 +36,7 @@ public class ReportEntryExtensionTests { void explicitKey_keyAndValueAreReported() { ExecutionResults results = PioneerTestKit.executeTestMethod(ReportEntriesTest.class, "explicitKey"); - List> reportEntries = results.reportEntries(); - assertThat(reportEntries).hasSize(1); - Map reportEntry = reportEntries.get(0); - assertThat(reportEntry).hasSize(1); - assertThat(reportEntry).containsExactly(TestUtils.entryOf("Crow2", "While I pondered weak and weary")); + assertThat(results).hasSingleReportEntry().withKeyAndValue("Crow2", "While I pondered weak and weary"); } @Test @@ -52,12 +44,7 @@ void explicitKey_keyAndValueAreReported() { void implicitKey_keyIsNamedValue() { ExecutionResults results = PioneerTestKit.executeTestMethod(ReportEntriesTest.class, "implicitKey"); - List> reportEntries = results.reportEntries(); - assertThat(reportEntries).hasSize(1); - assertThat(reportEntries.get(0)).satisfies(reportEntry -> { - assertThat(reportEntry).hasSize(1); - assertThat(reportEntry).containsExactly(TestUtils.entryOf("value", "Once upon a midnight dreary")); - }); + assertThat(results).hasSingleReportEntry().withKeyAndValue("value", "Once upon a midnight dreary"); } @Test @@ -65,9 +52,10 @@ void implicitKey_keyIsNamedValue() { void emptyKey_fails() { ExecutionResults results = PioneerTestKit.executeTestMethod(ReportEntriesTest.class, "emptyKey"); - assertThat(results.numberOfFailedTests()).isEqualTo(1); - assertThat(results.firstFailuresThrowableMessage()) - .contains("Report entries can't have blank key or value", + assertThat(results) + .hasSingleFailedTest() + .withException() + .hasMessageContainingAll("Report entries can't have blank key or value", "Over many a quaint and curious volume of forgotten lore"); } @@ -76,9 +64,11 @@ void emptyKey_fails() { void emptyValue_fails() { ExecutionResults results = PioneerTestKit.executeTestMethod(ReportEntriesTest.class, "emptyValue"); - assertThat(results.numberOfFailedTests()).isEqualTo(1); - assertThat(results.firstFailuresThrowableMessage()) - .contains("Report entries can't have blank key or value", "While I nodded, nearly napping"); + assertThat(results) + .hasSingleFailedTest() + .withException() + .hasMessageContainingAll("Report entries can't have blank key or value", + "While I nodded, nearly napping"); } @Test @@ -86,15 +76,10 @@ void emptyValue_fails() { void repeatedAnnotation_logEachKeyValuePairAsIndividualEntry() { ExecutionResults results = PioneerTestKit.executeTestMethod(ReportEntriesTest.class, "repeatedAnnotation"); - List> reportEntries = results.reportEntries(); - - assertAll("Verifying report entries " + reportEntries, // - () -> assertThat(reportEntries).hasSize(3), - () -> assertThat(reportEntries).extracting(Map::size).containsExactlyInAnyOrder(1, 1, 1), - () -> assertThat(reportEntries) - .extracting(entry -> entry.get("value")) - .containsExactlyInAnyOrder("suddenly there came a tapping", "As if some one gently rapping", - "rapping at my chamber door")); + assertThat(results) + .hasNumberOfReportEntries(3) + .withValues("suddenly there came a tapping", "As if some one gently rapping", + "rapping at my chamber door"); } @Nested @@ -110,14 +95,8 @@ class LogAlways { void successfulTest_logsMessage() { ExecutionResults results = PioneerTestKit.executeTestMethod(ReportEntriesTest.class, "always_success"); - List> successReportEntries = results.reportEntries(); - - assertThat(results.numberOfSucceededTests()).isEqualTo(1); - assertThat(successReportEntries.get(0)).satisfies(reportEntry -> { - assertThat(reportEntry).hasSize(1); - assertThat(reportEntry) - .containsExactly(TestUtils.entryOf("value", "'Tis some visitor', I muttered")); - }); + assertThat(results).hasSingleSucceededTest(); + assertThat(results).hasSingleReportEntry().withKeyAndValue("value", "'Tis some visitor', I muttered"); } @Test @@ -125,14 +104,8 @@ void successfulTest_logsMessage() { void failingTest_logsMessage() { ExecutionResults results = PioneerTestKit.executeTestMethod(ReportEntriesTest.class, "always_failure"); - List> failureReportEntries = results.reportEntries(); - - assertThat(results.numberOfFailedTests()).isEqualTo(1); - assertThat(failureReportEntries.get(0)).satisfies(reportEntry -> { - assertThat(reportEntry).hasSize(1); - assertThat(reportEntry) - .containsExactly(TestUtils.entryOf("value", "'Tapping at my chamber door' -")); - }); + assertThat(results).hasSingleFailedTest(); + assertThat(results).hasSingleReportEntry().withKeyAndValue("value", "'Tapping at my chamber door' -"); } @Test @@ -140,14 +113,8 @@ void failingTest_logsMessage() { void abortedTest_logsMessage() { ExecutionResults results = PioneerTestKit.executeTestMethod(ReportEntriesTest.class, "always_aborted"); - List> failureReportEntries = results.reportEntries(); - - assertThat(results.numberOfAbortedTests()).isEqualTo(1); - assertThat(failureReportEntries.get(0)).satisfies(reportEntry -> { - assertThat(reportEntry).hasSize(1); - assertThat(reportEntry) - .containsExactly(TestUtils.entryOf("value", "'Only this and nothing more.'")); - }); + assertThat(results).hasSingleAbortedTest(); + assertThat(results).hasSingleReportEntry().withKeyAndValue("value", "'Only this and nothing more.'"); } @Test @@ -155,10 +122,8 @@ void abortedTest_logsMessage() { void disabledTest_logsNoMessage() { ExecutionResults results = PioneerTestKit.executeTestMethod(ReportEntriesTest.class, "always_disabled"); - List> reportEntries = results.reportEntries(); - - assertThat(results.numberOfStartedTests()).isEqualTo(0); - assertThat(reportEntries).isEmpty(); + assertThat(results).hasSingleSkippedTest(); + assertThat(results).hasNoReportEntries(); } } @@ -173,13 +138,8 @@ void successfulTest_logsMessage() { ExecutionResults results = PioneerTestKit .executeTestMethod(ReportEntriesTest.class, "onSuccess_success"); - List> reportEntries = results.reportEntries(); - - assertThat(results.numberOfSucceededTests()).isEqualTo(1); - assertThat(reportEntries.get(0)).satisfies(reportEntry -> { - assertThat(reportEntry).hasSize(1); - assertThat(reportEntry).containsExactly(TestUtils.entryOf("value", "it was in the bleak December")); - }); + assertThat(results).hasSingleSucceededTest(); + assertThat(results).hasSingleReportEntry().withKeyAndValue("value", "it was in the bleak December"); } @Test @@ -188,10 +148,8 @@ void failedTest_logsNoMessage() { ExecutionResults results = PioneerTestKit .executeTestMethod(ReportEntriesTest.class, "onSuccess_failure"); - List> reportEntries = results.reportEntries(); - - assertThat(results.numberOfFailedTests()).isEqualTo(1); - assertThat(reportEntries).isEmpty(); + assertThat(results).hasSingleFailedTest(); + assertThat(results).hasNoReportEntries(); } @Test @@ -200,10 +158,8 @@ void abortedTest_logsNoMessage() { ExecutionResults results = PioneerTestKit .executeTestMethod(ReportEntriesTest.class, "onSuccess_aborted"); - List> reportEntries = results.reportEntries(); - - assertThat(results.numberOfAbortedTests()).isEqualTo(1); - assertThat(reportEntries).isEmpty(); + assertThat(results).hasSingleAbortedTest(); + assertThat(results).hasNoReportEntries(); } @Test @@ -212,10 +168,8 @@ void disabledTest_logsNoMessage() { ExecutionResults results = PioneerTestKit .executeTestMethod(ReportEntriesTest.class, "onSuccess_disabled"); - List> reportEntries = results.reportEntries(); - - assertThat(results.numberOfStartedTests()).isEqualTo(0); - assertThat(reportEntries).isEmpty(); + assertThat(results).hasSingleSkippedTest(); + assertThat(results).hasNoReportEntries(); } } @@ -230,10 +184,8 @@ void successfulTest_logsNoMessage() { ExecutionResults results = PioneerTestKit .executeTestMethod(ReportEntriesTest.class, "onFailure_success"); - List> reportEntries = results.reportEntries(); - - assertThat(results.numberOfSucceededTests()).isEqualTo(1); - assertThat(reportEntries).isEmpty(); + assertThat(results).hasSingleSucceededTest(); + assertThat(results).hasNoReportEntries(); } @Test @@ -242,13 +194,8 @@ void failedTest_logsMessage() { ExecutionResults results = PioneerTestKit .executeTestMethod(ReportEntriesTest.class, "onFailure_failure"); - List> reportEntries = results.reportEntries(); - - assertThat(results.numberOfFailedTests()).isEqualTo(1); - assertThat(reportEntries.get(0)).satisfies(reportEntry -> { - assertThat(reportEntry).hasSize(1); - assertThat(reportEntry).containsExactly(TestUtils.entryOf("value", "Nameless here for evermore.")); - }); + assertThat(results).hasSingleFailedTest(); + assertThat(results).hasSingleReportEntry().withKeyAndValue("value", "Nameless here for evermore."); } @Test @@ -257,10 +204,8 @@ void abortedTest_logsNoMessage() { ExecutionResults results = PioneerTestKit .executeTestMethod(ReportEntriesTest.class, "onFailure_aborted"); - List> reportEntries = results.reportEntries(); - - assertThat(results.numberOfAbortedTests()).isEqualTo(1); - assertThat(reportEntries).isEmpty(); + assertThat(results).hasSingleAbortedTest(); + assertThat(results).hasNoReportEntries(); } @Test @@ -269,10 +214,8 @@ void disabledTest_logsNoMessage() { ExecutionResults results = PioneerTestKit .executeTestMethod(ReportEntriesTest.class, "onFailure_disabled"); - List> reportEntries = results.reportEntries(); - - assertThat(results.numberOfStartedTests()).isEqualTo(0); - assertThat(reportEntries).isEmpty(); + assertThat(results).hasSingleSkippedTest(); + assertThat(results).hasNoReportEntries(); } } @@ -287,10 +230,8 @@ void successfulTest_logsNoMessage() { ExecutionResults results = PioneerTestKit .executeTestMethod(ReportEntriesTest.class, "onAborted_success"); - List> reportEntries = results.reportEntries(); - - assertThat(results.numberOfSucceededTests()).isEqualTo(1); - assertThat(reportEntries).isEmpty(); + assertThat(results).hasSingleSucceededTest(); + assertThat(results).hasNoReportEntries(); } @Test @@ -299,10 +240,8 @@ void failedTest_logsNoMessage() { ExecutionResults results = PioneerTestKit .executeTestMethod(ReportEntriesTest.class, "onAborted_failure"); - List> reportEntries = results.reportEntries(); - - assertThat(results.numberOfFailedTests()).isEqualTo(1); - assertThat(reportEntries).isEmpty(); + assertThat(results).hasSingleFailedTest(); + assertThat(results).hasNoReportEntries(); } @Test @@ -311,15 +250,9 @@ void abortedTest_logsMessage() { ExecutionResults results = PioneerTestKit .executeTestMethod(ReportEntriesTest.class, "onAborted_aborted"); - List> reportEntries = results.reportEntries(); - - assertThat(results.numberOfAbortedTests()).isEqualTo(1); - assertThat(reportEntries.get(0)).satisfies(reportEntry -> { - assertThat(reportEntry).hasSize(1); - assertThat(reportEntry) - .containsExactly(TestUtils - .entryOf("value", "Some late visitor entreating entrance at my chamber door;—")); - }); + assertThat(results) + .hasSingleReportEntry() + .withKeyAndValue("value", "Some late visitor entreating entrance at my chamber door;—"); } @Test @@ -328,10 +261,8 @@ void disabledTest_logsNoMessage() { ExecutionResults results = PioneerTestKit .executeTestMethod(ReportEntriesTest.class, "onAborted_disabled"); - List> reportEntries = results.reportEntries(); - - assertThat(results.numberOfStartedTests()).isEqualTo(0); - assertThat(reportEntries).isEmpty(); + assertThat(results).hasSingleSkippedTest(); + assertThat(results).hasNoReportEntries(); } } @@ -346,17 +277,11 @@ void conditional_logOnSuccessIndependently() { ExecutionResults results = PioneerTestKit .executeTestMethod(ReportEntriesTest.class, "repeated_success"); - List> reportEntries = results.reportEntries(); - - assertThat(results.numberOfSucceededTests()).isEqualTo(1); - assertAll("Verifying report entries " + reportEntries, // - () -> assertThat(reportEntries).hasSize(2), - () -> assertThat(reportEntries).extracting(Map::size).containsExactlyInAnyOrder(1, 1), - () -> assertThat(reportEntries) - .extracting(entry -> entry.get("value")) - .containsExactlyInAnyOrder( - "Deep into that darkness peering, long I stood there wondering, fearing,", - "Doubting, dreaming dreams no mortal ever dared to dream before;")); + assertThat(results).hasSingleSucceededTest(); + assertThat(results) + .hasNumberOfReportEntries(2) + .withValues("Deep into that darkness peering, long I stood there wondering, fearing,", + "Doubting, dreaming dreams no mortal ever dared to dream before;"); } @Test @@ -365,17 +290,11 @@ void conditional_logOnFailureIndependently() { ExecutionResults results = PioneerTestKit .executeTestMethod(ReportEntriesTest.class, "repeated_failure"); - List> reportEntries = results.reportEntries(); - - assertThat(results.numberOfFailedTests()).isEqualTo(1); - assertAll("Verifying report entries " + reportEntries, // - () -> assertThat(reportEntries).hasSize(2), - () -> assertThat(reportEntries).extracting(Map::size).containsExactlyInAnyOrder(1, 1), - () -> assertThat(reportEntries) - .extracting(entry -> entry.get("value")) - .containsExactlyInAnyOrder( - "And the only word there spoken was the whispered word, “Lenore?”", - "murmured back the word, “Lenore!”—")); + assertThat(results).hasSingleFailedTest(); + assertThat(results) + .hasNumberOfReportEntries(2) + .withValues("And the only word there spoken was the whispered word, “Lenore?”", + "murmured back the word, “Lenore!”—"); } @Test @@ -384,16 +303,11 @@ void conditional_logOnAbortedIndependently() { ExecutionResults results = PioneerTestKit .executeTestMethod(ReportEntriesTest.class, "repeated_aborted"); - List> reportEntries = results.reportEntries(); - - assertThat(results.numberOfAbortedTests()).isEqualTo(1); - assertAll("Verifying report entries " + reportEntries, // - () -> assertThat(reportEntries).hasSize(2), - () -> assertThat(reportEntries).extracting(Map::size).containsExactlyInAnyOrder(1, 1), - () -> assertThat(reportEntries) - .extracting(entry -> entry.get("value")) - .containsExactlyInAnyOrder("Back into the chamber turning, all my soul within me burning,", - "“surely that is something at my window lattice;")); + assertThat(results).hasSingleAbortedTest(); + assertThat(results) + .hasNumberOfReportEntries(2) + .withValues("Back into the chamber turning, all my soul within me burning,", + "“surely that is something at my window lattice;"); } @Test @@ -402,10 +316,8 @@ void conditional_doesNotLogOnDisabled() { ExecutionResults results = PioneerTestKit .executeTestMethod(ReportEntriesTest.class, "repeated_disabled"); - List> reportEntries = results.reportEntries(); - - assertThat(results.numberOfStartedTests()).isEqualTo(0); - assertThat(reportEntries).isEmpty(); + assertThat(results).hasSingleSkippedTest(); + assertThat(results).hasNoReportEntries(); } } diff --git a/src/test/java/org/junitpioneer/jupiter/RetryingTestTests.java b/src/test/java/org/junitpioneer/jupiter/RetryingTestTests.java index 5673648b0..4ee397e66 100644 --- a/src/test/java/org/junitpioneer/jupiter/RetryingTestTests.java +++ b/src/test/java/org/junitpioneer/jupiter/RetryingTestTests.java @@ -12,8 +12,8 @@ import static java.lang.annotation.ElementType.ANNOTATION_TYPE; import static java.lang.annotation.ElementType.METHOD; -import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.parallel.ExecutionMode.SAME_THREAD; +import static org.junitpioneer.testkit.assertion.PioneerAssert.assertThat; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -33,9 +33,8 @@ void invalidConfigurationWithTest() { ExecutionResults results = PioneerTestKit .executeTestMethod(RetryingTestTestCase.class, "invalidConfigurationWithTest"); - assertThat(results.numberOfDynamicRegisteredTests()).isEqualTo(1); - assertThat(results.numberOfStartedTests()).isEqualTo(2); - assertThat(results.numberOfSucceededTests()).isEqualTo(2); + assertThat(results).hasSingleDynamicallyRegisteredTest(); + assertThat(results).hasNumberOfStartedTests(2).hasNumberOfSucceededTests(2); } @Test @@ -43,17 +42,14 @@ void executedOneEvenWithTwoTestTemplatesTest() { ExecutionResults results = PioneerTestKit .executeTestMethod(RetryingTestTestCase.class, "executedOneEvenWithTwoTestTemplates"); - assertThat(results.numberOfDynamicRegisteredTests()).isEqualTo(1); - assertThat(results.numberOfStartedTests()).isEqualTo(1); - assertThat(results.numberOfSucceededTests()).isEqualTo(1); + assertThat(results).hasSingleDynamicallyRegisteredTest().whichSucceeded(); } @Test void failsNever_executedOnce_passes() { ExecutionResults results = PioneerTestKit.executeTestMethod(RetryingTestTestCase.class, "failsNever"); - assertThat(results.numberOfDynamicRegisteredTests()).isEqualTo(1); - assertThat(results.numberOfSucceededTests()).isEqualTo(1); + assertThat(results).hasSingleDynamicallyRegisteredTest().whichSucceeded(); } @Test @@ -61,26 +57,28 @@ void failsOnlyOnFirstInvocation_executedTwice_passes() { ExecutionResults results = PioneerTestKit .executeTestMethod(RetryingTestTestCase.class, "failsOnlyOnFirstInvocation"); - assertThat(results.numberOfDynamicRegisteredTests()).isEqualTo(2); - assertThat(results.numberOfAbortedTests()).isEqualTo(1); - assertThat(results.numberOfSucceededTests()).isEqualTo(1); + assertThat(results) + .hasNumberOfDynamicallyRegisteredTests(2) + .hasNumberOfAbortedTests(1) + .hasNumberOfSucceededTests(1); } @Test void failsAlways_executedThreeTimes_fails() { ExecutionResults results = PioneerTestKit.executeTestMethod(RetryingTestTestCase.class, "failsAlways"); - assertThat(results.numberOfDynamicRegisteredTests()).isEqualTo(3); - assertThat(results.numberOfAbortedTests()).isEqualTo(2); - assertThat(results.numberOfFailedTests()).isEqualTo(1); + assertThat(results) + .hasNumberOfDynamicallyRegisteredTests(3) + .hasNumberOfAbortedTests(2) + .hasNumberOfFailedTests(1); } @Test void skipByAssumption_executedOnce_skipped() { ExecutionResults results = PioneerTestKit.executeTestMethod(RetryingTestTestCase.class, "skipByAssumption"); - assertThat(results.numberOfDynamicRegisteredTests()).isEqualTo(1); - assertThat(results.numberOfAbortedTests()).isEqualTo(1); + assertThat(results).hasSingleDynamicallyRegisteredTest(); + assertThat(results).hasSingleAbortedTest(); } // TEST CASES ------------------------------------------------------------------- diff --git a/src/test/java/org/junitpioneer/jupiter/StdIoExtensionTests.java b/src/test/java/org/junitpioneer/jupiter/StdIoExtensionTests.java index c9a60ac63..33200e99b 100644 --- a/src/test/java/org/junitpioneer/jupiter/StdIoExtensionTests.java +++ b/src/test/java/org/junitpioneer/jupiter/StdIoExtensionTests.java @@ -11,6 +11,7 @@ package org.junitpioneer.jupiter; import static org.assertj.core.api.Assertions.assertThat; +import static org.junitpioneer.testkit.assertion.PioneerAssert.assertThat; import java.io.BufferedReader; import java.io.IOException; @@ -45,8 +46,9 @@ void needsType() { .executeTestMethodWithParameterTypes(StdIOExtensionConfigurations.class, "badType", Boolean.class.getName()); - assertThat(results.firstFailuresThrowable()) - .isInstanceOf(ParameterResolutionException.class) + assertThat(results) + .hasSingleFailedTest() + .withExceptionInstanceOf(ParameterResolutionException.class) .hasMessageContaining("No ParameterResolver registered"); } @@ -57,8 +59,9 @@ void needsAnnotation() { .executeTestMethodWithParameterTypes(StdIOExtensionConfigurations.class, "noAnnotation", StdIn.class.getName()); - assertThat(results.firstFailuresThrowable()) - .isInstanceOf(ParameterResolutionException.class) + assertThat(results) + .hasSingleFailedTest() + .withExceptionInstanceOf(ParameterResolutionException.class) .hasMessageContainingAll("Can not resolve test method parameter", "Method has to be annotated"); } @@ -68,7 +71,7 @@ void goodConfig_stdIn() { ExecutionResults results = PioneerTestKit .executeTestMethodWithParameterTypes(StdIOExtensionConfigurations.class, "resolveStdIn", StdIn.class.getName()); - assertThat(results.numberOfStartedTests()).isGreaterThan(0); + assertThat(results).hasSingleSucceededTest(); } @Test @@ -77,7 +80,7 @@ void goodConfig_stdOut() { ExecutionResults results = PioneerTestKit .executeTestMethodWithParameterTypes(StdIOExtensionConfigurations.class, "resolveStdOut", StdOut.class.getName()); - assertThat(results.numberOfStartedTests()).isGreaterThan(0); + assertThat(results).hasSingleSucceededTest(); } } diff --git a/src/test/java/org/junitpioneer/jupiter/SystemPropertyExtensionTests.java b/src/test/java/org/junitpioneer/jupiter/SystemPropertyExtensionTests.java index 9dff20cee..47bf648a5 100644 --- a/src/test/java/org/junitpioneer/jupiter/SystemPropertyExtensionTests.java +++ b/src/test/java/org/junitpioneer/jupiter/SystemPropertyExtensionTests.java @@ -11,6 +11,7 @@ package org.junitpioneer.jupiter; import static org.assertj.core.api.Assertions.assertThat; +import static org.junitpioneer.testkit.assertion.PioneerAssert.assertThat; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; @@ -19,6 +20,7 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtensionConfigurationException; +import org.junitpioneer.testkit.ExecutionResults; import org.junitpioneer.testkit.PioneerTestKit; @DisplayName("SystemProperty extension") @@ -198,12 +200,11 @@ class ConfigurationFailureTests { @Test @DisplayName("should fail when clear and set same system property") void shouldFailWhenClearAndSetSameSystemProperty() { - Throwable thrown = PioneerTestKit + ExecutionResults results = PioneerTestKit .executeTestMethod(MethodLevelInitializationFailureTestCase.class, - "shouldFailWhenClearAndSetSameSystemProperty") - .firstFailuresThrowable(); + "shouldFailWhenClearAndSetSameSystemProperty"); - assertThat(thrown).isInstanceOf(ExtensionConfigurationException.class); + assertThat(results).hasSingleFailedTest().withExceptionInstanceOf(ExtensionConfigurationException.class); } @Test @@ -212,23 +213,20 @@ void shouldFailWhenClearAndSetSameSystemProperty() { + "deduplicates identical annotations like the ones required for this test: " + "https://github.com/junit-team/junit5/issues/2131") void shouldFailWhenClearSameSystemPropertyTwice() { - Throwable thrown = PioneerTestKit + ExecutionResults results = PioneerTestKit .executeTestMethod(MethodLevelInitializationFailureTestCase.class, - "shouldFailWhenClearSameSystemPropertyTwice") - .firstFailuresThrowable(); + "shouldFailWhenClearSameSystemPropertyTwice"); - assertThat(thrown).isInstanceOf(ExtensionConfigurationException.class); + assertThat(results).hasSingleFailedTest().withExceptionInstanceOf(ExtensionConfigurationException.class); } @Test @DisplayName("should fail when set same system property twice") void shouldFailWhenSetSameSystemPropertyTwice() { - Throwable thrown = PioneerTestKit + ExecutionResults results = PioneerTestKit .executeTestMethod(MethodLevelInitializationFailureTestCase.class, - "shouldFailWhenSetSameSystemPropertyTwice") - .firstFailuresThrowable(); - - assertThat(thrown).isInstanceOf(ExtensionConfigurationException.class); + "shouldFailWhenSetSameSystemPropertyTwice"); + assertThat(results).hasSingleFailedTest().withExceptionInstanceOf(ExtensionConfigurationException.class); } } diff --git a/src/test/java/org/junitpioneer/jupiter/TempDirectoryExtensionTests.java b/src/test/java/org/junitpioneer/jupiter/TempDirectoryExtensionTests.java index 9fdfb712e..8e369b4d5 100644 --- a/src/test/java/org/junitpioneer/jupiter/TempDirectoryExtensionTests.java +++ b/src/test/java/org/junitpioneer/jupiter/TempDirectoryExtensionTests.java @@ -13,6 +13,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.fail; import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS; +import static org.junitpioneer.testkit.assertion.PioneerAssert.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; @@ -101,9 +102,8 @@ void resolvesSeparateTempDirWhenAnnotationIsUsedOnAfterAllMethodParameterOnly() ExecutionResults results = PioneerTestKit .executeTestClass(AnnotationOnAfterAllMethodParameterTestCase.class); - assertThat(results.numberOfStartedTests()).isEqualTo(1); - assertThat(results.numberOfFailedTests()).isEqualTo(0); - assertThat(results.numberOfSucceededTests()).isEqualTo(1); + assertThat(results).hasSingleStartedTest().whichSucceeded(); + assertThat(results).hasNumberOfFailedTests(0); assertThat(AnnotationOnAfterAllMethodParameterTestCase.firstTempDir).isPresent(); assertThat(AnnotationOnAfterAllMethodParameterTestCase.firstTempDir.get()).doesNotExist(); @@ -158,8 +158,7 @@ void deletesTempDirAfterExecution() { ExecutionResults results = PioneerTestKit .executeTestMethodWithParameterTypes(DeletionTestCase.class, "test", "java.nio.file.Path"); - assertThat(results.numberOfStartedTests()).isEqualTo(1); - assertThat(results.numberOfSucceededTests()).isEqualTo(1); + assertThat(results).hasSingleStartedTest().whichSucceeded(); assertThat(DeletionTestCase.tempDir).isPresent(); assertThat(DeletionTestCase.tempDir.get()).doesNotExist(); @@ -172,8 +171,7 @@ void ignoresDeletedDirectory() { .executeTestMethodWithParameterTypes(DeletionTestCase.class, "testThatDeletes", "java.nio.file.Path"); - assertThat(results.numberOfStartedTests()).isEqualTo(1); - assertThat(results.numberOfSucceededTests()).isEqualTo(1); + assertThat(results).hasSingleStartedTest().whichSucceeded(); assertThat(DeletionTestCase.tempDir).isPresent(); assertThat(DeletionTestCase.tempDir.get()).doesNotExist(); @@ -190,9 +188,10 @@ class Failures { void onlySupportsParametersOfTypePath() { ExecutionResults results = PioneerTestKit.executeTestClass(InvalidTestCase.class); - results - .assertTestFailedWithThrowableWhichContainsMessage(ParameterResolutionException.class, - "Can only resolve parameter of type java.nio.file.Path"); + assertThat(results) + .hasSingleFailedTest() + .withExceptionInstanceOf(ParameterResolutionException.class) + .hasMessageContainingAll("Can only resolve parameter of type java.nio.file.Path"); } @Test @@ -200,9 +199,10 @@ void onlySupportsParametersOfTypePath() { void failedCreationAttemptMakesTestFail() { ExecutionResults results = PioneerTestKit.executeTestClass(FailedCreationAttemptTestCase.class); - results - .assertTestFailedWithThrowableWhichContainsMessage(ParameterResolutionException.class, - "Failed to create custom temp directory"); + assertThat(results) + .hasSingleFailedTest() + .withExceptionInstanceOf(ParameterResolutionException.class) + .hasMessageContainingAll("Failed to create custom temp directory"); } @Test @@ -210,9 +210,10 @@ void failedCreationAttemptMakesTestFail() { void failedDeletionAttemptMakesTestFail() { ExecutionResults results = PioneerTestKit.executeTestClass(FailedDeletionAttemptTestCase.class); - results - .assertTestFailedWithThrowableWhichContainsMessage(IOException.class, - "Failed to delete temp directory"); + assertThat(results) + .hasSingleFailedTest() + .withExceptionInstanceOf(IOException.class) + .hasMessageContainingAll("Failed to delete temp directory"); } @Test @@ -220,9 +221,10 @@ void failedDeletionAttemptMakesTestFail() { void erroneousParentDirProviderMakesTestFail() { ExecutionResults results = PioneerTestKit.executeTestClass(ErroneousParentDirProviderTestCase.class); - results - .assertTestFailedWithThrowableWhichContainsMessage(ParameterResolutionException.class, - "Failed to get parent directory"); + assertThat(results) + .hasSingleFailedTest() + .withExceptionInstanceOf(ParameterResolutionException.class) + .hasMessageContainingAll("Failed to get parent directory"); } } @@ -230,9 +232,7 @@ void erroneousParentDirProviderMakesTestFail() { private void assertResolvesShareTempDir(Class testClass) { ExecutionResults results = PioneerTestKit.executeTestClass(testClass); - assertThat(results.numberOfStartedTests()).isEqualTo(2); - assertThat(results.numberOfFailedTests()).isEqualTo(0); - assertThat(results.numberOfSucceededTests()).isEqualTo(2); + assertThat(results).hasNumberOfStartedTests(2).hasNumberOfSucceededTests(2).hasNumberOfFailedTests(0); assertThat(BaseSharedTempDirTestCase.tempDir).isPresent(); assertThat(BaseSharedTempDirTestCase.tempDir.get()).doesNotExist(); @@ -241,9 +241,7 @@ private void assertResolvesShareTempDir(Class testClass) { ExecutionResults results = PioneerTestKit.executeTestClass(testClass); - assertThat(results.numberOfStartedTests()).isEqualTo(2); - assertThat(results.numberOfFailedTests()).isEqualTo(0); - assertThat(results.numberOfSucceededTests()).isEqualTo(2); + assertThat(results).hasNumberOfStartedTests(2).hasNumberOfSucceededTests(2).hasNumberOfFailedTests(0); Deque tempDirs = BaseSeparateTempDirsTestCase.tempDirs; assertThat(tempDirs).hasSize(2); } diff --git a/src/test/java/org/junitpioneer/jupiter/TestUtils.java b/src/test/java/org/junitpioneer/jupiter/TestUtils.java deleted file mode 100644 index 1925c8ea7..000000000 --- a/src/test/java/org/junitpioneer/jupiter/TestUtils.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2015-2020 the original author or authors. - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v2.0 which - * accompanies this distribution and is available at - * - * http://www.eclipse.org/legal/epl-v20.html - */ - -package org.junitpioneer.jupiter; - -import java.util.AbstractMap; -import java.util.Map; - -public class TestUtils { - - static Map.Entry entryOf(String key, String value) { - return new AbstractMap.SimpleEntry<>(key, value); - } - -} diff --git a/src/test/java/org/junitpioneer/jupiter/params/DisabledIfNameExtensionTests.java b/src/test/java/org/junitpioneer/jupiter/params/DisabledIfNameExtensionTests.java index 9d67dc80c..44f6d5ca1 100644 --- a/src/test/java/org/junitpioneer/jupiter/params/DisabledIfNameExtensionTests.java +++ b/src/test/java/org/junitpioneer/jupiter/params/DisabledIfNameExtensionTests.java @@ -10,8 +10,8 @@ package org.junitpioneer.jupiter.params; -import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.fail; +import static org.junitpioneer.testkit.assertion.PioneerAssert.assertThat; import java.util.Arrays; @@ -32,9 +32,7 @@ void single_correctTestsSkipped() { ExecutionResults results = PioneerTestKit .executeTestMethodWithParameterTypes(SubstringTestCases.class, "single", "java.lang.String"); - assertThat(results.numberOfFailedTests()).isEqualTo(0); - assertThat(results.numberOfSucceededTests()).isEqualTo(1); - assertThat(results.numberOfSkippedTests()).isEqualTo(5); + assertThat(results).hasNumberOfFailedTests(0).hasNumberOfSucceededTests(1).hasNumberOfSkippedTests(5); } @Test @@ -42,9 +40,7 @@ void multiple_correctTestsSkipped() { ExecutionResults results = PioneerTestKit .executeTestMethodWithParameterTypes(SubstringTestCases.class, "multiple", "int"); - assertThat(results.numberOfFailedTests()).isEqualTo(0); - assertThat(results.numberOfSucceededTests()).isEqualTo(3); - assertThat(results.numberOfSkippedTests()).isEqualTo(2); + assertThat(results).hasNumberOfFailedTests(0).hasNumberOfSucceededTests(3).hasNumberOfSkippedTests(2); } @Test @@ -52,7 +48,7 @@ void methodNameContainsSubstring_containerNotSkipped() { ExecutionResults results = PioneerTestKit .executeTestMethodWithParameterTypes(SubstringTestCases.class, "methodNameContains", "int"); - assertThat(results.numberOfStartedTests()).isEqualTo(3); + assertThat(results).hasNumberOfStartedTests(3); } } @@ -65,9 +61,7 @@ void single_correctTestsSkipped() { ExecutionResults results = PioneerTestKit .executeTestMethodWithParameterTypes(RegExpTestCases.class, "single", "java.lang.String"); - assertThat(results.numberOfFailedTests()).isEqualTo(0); - assertThat(results.numberOfSucceededTests()).isEqualTo(2); - assertThat(results.numberOfSkippedTests()).isEqualTo(4); + assertThat(results).hasNumberOfFailedTests(0).hasNumberOfSucceededTests(2).hasNumberOfSkippedTests(4); } @Test @@ -75,9 +69,7 @@ void multiple_correctTestsSkipped() { ExecutionResults results = PioneerTestKit .executeTestMethodWithParameterTypes(RegExpTestCases.class, "multiple", "int"); - assertThat(results.numberOfFailedTests()).isEqualTo(0); - assertThat(results.numberOfSucceededTests()).isEqualTo(2); - assertThat(results.numberOfSkippedTests()).isEqualTo(3); + assertThat(results).hasNumberOfFailedTests(0).hasNumberOfSkippedTests(3).hasNumberOfSucceededTests(2); } @Test @@ -85,7 +77,7 @@ void methodNameMatchesRegExp_containerNotSkipped() { ExecutionResults results = PioneerTestKit .executeTestMethodWithParameterTypes(RegExpTestCases.class, "methodNameMatches", "int"); - assertThat(results.numberOfStartedTests()).isEqualTo(3); + assertThat(results).hasNumberOfStartedTests(3); } } @@ -99,7 +91,7 @@ void noContainsNoMatches_configurationException() { .executeTestMethodWithParameterTypes(ConfigurationTestCases.class, "noContainsNoMatches", "java.lang.String"); - assertThat(results.numberOfFailedTests()).isEqualTo(1); + assertThat(results).hasSingleFailedTest(); } @Test @@ -108,9 +100,7 @@ void containsAndMatches_contains_correctTestsSkipped() { .executeTestMethodWithParameterTypes(ConfigurationTestCases.class, "containsAndMatches_contains", "int"); - assertThat(results.numberOfFailedTests()).isEqualTo(0); - assertThat(results.numberOfSucceededTests()).isEqualTo(3); - assertThat(results.numberOfSkippedTests()).isEqualTo(2); + assertThat(results).hasNumberOfFailedTests(0).hasNumberOfSkippedTests(2).hasNumberOfSucceededTests(3); } @Test @@ -119,9 +109,7 @@ void containsAndMatches_matches_correctTestsSkipped() { .executeTestMethodWithParameterTypes(ConfigurationTestCases.class, "containsAndMatches_matches", "int"); - assertThat(results.numberOfFailedTests()).isEqualTo(0); - assertThat(results.numberOfSucceededTests()).isEqualTo(2); - assertThat(results.numberOfSkippedTests()).isEqualTo(3); + assertThat(results).hasNumberOfFailedTests(0).hasNumberOfSucceededTests(2).hasNumberOfSkippedTests(3); } @Test @@ -130,9 +118,7 @@ void containsAndMatches_containsAndMatches_correctTestsSkipped() { .executeTestMethodWithParameterTypes(ConfigurationTestCases.class, "containsAndMatches_containsAndMatches", "int"); - assertThat(results.numberOfFailedTests()).isEqualTo(0); - assertThat(results.numberOfSucceededTests()).isEqualTo(1); - assertThat(results.numberOfSkippedTests()).isEqualTo(4); + assertThat(results).hasNumberOfFailedTests(0).hasNumberOfSucceededTests(1).hasNumberOfSkippedTests(4); } } diff --git a/src/test/java/org/junitpioneer/jupiter/params/RangeSourceArgumentsProviderTests.java b/src/test/java/org/junitpioneer/jupiter/params/RangeSourceArgumentsProviderTests.java index f71880fc2..160727e8d 100644 --- a/src/test/java/org/junitpioneer/jupiter/params/RangeSourceArgumentsProviderTests.java +++ b/src/test/java/org/junitpioneer/jupiter/params/RangeSourceArgumentsProviderTests.java @@ -11,6 +11,7 @@ package org.junitpioneer.jupiter.params; import static org.assertj.core.api.Assertions.assertThat; +import static org.junitpioneer.testkit.assertion.PioneerAssert.assertThat; import java.lang.reflect.Method; import java.util.List; @@ -168,34 +169,41 @@ class InvalidRangeTestCases { @Test void twoAnnotations() { ExecutionResults results = PioneerTestKit.executeTestMethod(InvalidRanges.class, "twoAnnotations"); - results - .assertContainerFailedWithThrowableWhichContainsMessage(PreconditionViolationException.class, - "Expected exactly one annotation to provide an ArgumentSource, found 2."); + assertThat(results) + .hasSingleFailedContainer() + .withExceptionInstanceOf(PreconditionViolationException.class) + .hasMessageContainingAll("Expected exactly one annotation to provide an ArgumentSource, found 2."); } @Test void zeroStep() { ExecutionResults results = PioneerTestKit.executeTestMethod(InvalidRanges.class, "zeroStep"); - results - .assertContainerFailedWithThrowableWhichContainsMessage(PreconditionViolationException.class, - "Illegal range. The step cannot be zero."); + + assertThat(results) + .hasSingleFailedContainer() + .withExceptionInstanceOf(PreconditionViolationException.class) + .hasMessageContainingAll("Illegal range. The step cannot be zero."); } @Test void illegalStep() { ExecutionResults results = PioneerTestKit.executeTestMethod(InvalidRanges.class, "illegalStep"); - results - .assertContainerFailedWithThrowableWhichContainsMessage(PreconditionViolationException.class, - "Illegal range. There's no way to get from 10 to 0 with a step of 1."); + + assertThat(results) + .hasSingleFailedContainer() + .withExceptionInstanceOf(PreconditionViolationException.class) + .hasMessageContainingAll("Illegal range. There's no way to get from 10 to 0 with a step of 1."); } @Test void emptyRange() { ExecutionResults results = PioneerTestKit.executeTestMethod(InvalidRanges.class, "emptyRange"); - results - .assertContainerFailedWithThrowableWhichContainsMessage(PreconditionViolationException.class, - "Illegal range. Equal from and to will produce an empty range."); + + assertThat(results) + .hasSingleFailedContainer() + .withExceptionInstanceOf(PreconditionViolationException.class) + .hasMessageContainingAll("Illegal range. Equal from and to will produce an empty range."); } } diff --git a/src/test/java/org/junitpioneer/testkit/ExecutionResults.java b/src/test/java/org/junitpioneer/testkit/ExecutionResults.java index 5b6ec1fb9..ad11362ac 100644 --- a/src/test/java/org/junitpioneer/testkit/ExecutionResults.java +++ b/src/test/java/org/junitpioneer/testkit/ExecutionResults.java @@ -10,24 +10,14 @@ package org.junitpioneer.testkit; -import static java.util.stream.Collectors.toList; -import static org.assertj.core.api.Assertions.assertThat; - -import java.util.List; -import java.util.Map; -import java.util.Optional; - -import org.junit.jupiter.api.extension.ExtensionConfigurationException; -import org.junit.platform.engine.TestExecutionResult; import org.junit.platform.engine.discovery.DiscoverySelectors; -import org.junit.platform.engine.reporting.ReportEntry; import org.junit.platform.testkit.engine.EngineExecutionResults; import org.junit.platform.testkit.engine.EngineTestKit; import org.junit.platform.testkit.engine.Events; /** * Pioneers' class to handle JUnit Jupiter's {@link org.junit.platform.testkit.engine.EngineExecutionResults}. - * + *

* Instantiate with the static factory methods in {@link PioneerTestKit}. */ public class ExecutionResults { @@ -89,178 +79,4 @@ public Events testEvents() { return executionResults.tests(); } - /** - * Returns the number of all tests. - * - * @return number of all tests - */ - public long totalNumberOfTests() { - return executionResults.tests().count(); - } - - /** - * Returns the number of started tests. - * - * @return number of started tests - */ - public long numberOfStartedTests() { - return executionResults.tests().started().count(); - } - - /** - * Returns the number of failed tests. - * - * @return number of failed tests - */ - public long numberOfFailedTests() { - return executionResults.tests().failed().count(); - } - - /** - * Returns the number of successful tests. - * - * @return number of successful tests - */ - public long numberOfSucceededTests() { - return executionResults.tests().succeeded().count(); - } - - /** - * Returns the number of skipped tests. - * - * @return number of skipped tests - */ - public long numberOfSkippedTests() { - return executionResults.tests().skipped().count(); - } - - /** - * Returns the number of aborted tests. - * - * @return number of aborted events results - */ - public long numberOfAbortedTests() { - return executionResults.tests().aborted().count(); - } - - /** - * Returns the number of failed containers. - * - * @return number of failed containers - */ - public long numberOfFailedContainers() { - return executionResults.containers().failed().count(); - } - - /** - * Returns the number of dynamically registered tests. - * - * @return number of dynamically registered tests - */ - public long numberOfDynamicRegisteredTests() { - return executionResults.tests().dynamicallyRegistered().count(); - } - - /** - * Returns the number of published report entries. - * - * @return number of published report entries - */ - public long numberOfPublishedReportEntries() { - return executionResults.all().reportingEntryPublished().count(); - } - - /** - * Returns the message of the first failed event. - * This can be used if you expect a test to fail with an exception and want to check the exception message. - * - * @return message of the first failed event - */ - public String firstFailuresThrowableMessage() { - return firstFailuresThrowable().getMessage(); - } - - public Map.Entry singleReportEntry() { - List> reportEntries = reportEntries(); - assertThat(reportEntries).hasSize(1); - Map reportEntry = reportEntries.get(0); - assertThat(reportEntry).hasSize(1); - return reportEntry.entrySet().iterator().next(); - } - - public List> reportEntries() { - return executionResults - .all() - .reportingEntryPublished() - .stream() - .map(event -> event.getPayload(ReportEntry.class)) - .filter(Optional::isPresent) - .map(Optional::get) - .map(ReportEntry::getKeyValuePairs) - .collect(toList()); - } - - /** - * Returns the {@link Throwable} of the first failed event. - * This can be used if you expect a test to fail with a specific exception type. - * - * @return Throwable of the first failed event - */ - public Throwable firstFailuresThrowable() { - return executionResults - .all() - .failed() - .stream() - .findFirst() - .orElseThrow(AssertionError::new) - .getPayload(TestExecutionResult.class) - .flatMap(TestExecutionResult::getThrowable) - .orElseThrow(AssertionError::new); - } - - public void assertTestFailedWithThrowableWhichContainsMessage(Class thrown, String message) { - assertThat(numberOfFailedTests()).isEqualTo(1); - assertThat(firstFailuresThrowable()).isInstanceOf(thrown); - assertThat(firstFailuresThrowableMessage()).contains(message); - } - - public void assertContainerFailedWithThrowableWhichContainsMessage(Class thrown, - String message) { - assertThat(numberOfFailedContainers()).isEqualTo(1); - assertThat(firstFailuresThrowable()).isInstanceOf(thrown); - assertThat(firstFailuresThrowableMessage()).contains(message); - } - - public void assertTestFailedWithThrowable(Class thrown) { - assertThat(numberOfFailedTests()).isEqualTo(1); - assertThat(firstFailuresThrowable()).isInstanceOf(thrown); - } - - public void assertTestFailedWithExtensionConfigurationException() { - assertThat(numberOfFailedTests()).isEqualTo(1); - assertThat(firstFailuresThrowable()).isInstanceOf(ExtensionConfigurationException.class); - } - - public void assertFailedTestHasMessage(String... messages) { - assertThat(numberOfFailedTests()).isEqualTo(1); - assertThat(firstFailuresThrowableMessage()).isEqualTo(String.join(",", messages)); - } - - /** - * Returns the published report entries of all tests. - * - * @return published report entries of all tests - */ - public List> publishedTestReportEntries() { - return executionResults - .tests() - .reportingEntryPublished() - .stream() - .map(executionEvent -> executionEvent.getPayload(org.junit.platform.engine.reporting.ReportEntry.class)) - .filter(Optional::isPresent) - .map(Optional::get) - .map(org.junit.platform.engine.reporting.ReportEntry::getKeyValuePairs) - .collect(toList()); - } - } diff --git a/src/test/java/org/junitpioneer/testkit/assertion/AbstractPioneerAssert.java b/src/test/java/org/junitpioneer/testkit/assertion/AbstractPioneerAssert.java new file mode 100644 index 000000000..13233d27c --- /dev/null +++ b/src/test/java/org/junitpioneer/testkit/assertion/AbstractPioneerAssert.java @@ -0,0 +1,41 @@ +/* + * Copyright 2015-2020 the original author or authors. + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v2.0 which + * accompanies this distribution and is available at + * + * http://www.eclipse.org/legal/epl-v20.html + */ + +package org.junitpioneer.testkit.assertion; + +import org.assertj.core.api.AbstractAssert; + +/** + * A very basic extension of the AbstractAssert, used to add a quantity to assertions. + * By storing this value in a field we don't have to refer back to it every time. + * + * Instead of + *

assertThat(results).hasTests().thatStarted(3).thenFailed(3)

+ * + * We can write + *

assertThat(results).hasNumberOfTests(3).thatStarted().andAllOfThemFailed()

+ * + * @param the "self" type of this assertion class. Please read + * " + * Emulating 'self types' using Java Generics to simplify fluent API implementation" + * for more details. + * @param the type of the "actual" value. + */ +abstract class AbstractPioneerAssert, ACTUAL> + extends AbstractAssert { + + protected final int expected; + + protected AbstractPioneerAssert(ACTUAL actual, Class self, int expected) { + super(actual, self); + this.expected = expected; + } + +} diff --git a/src/test/java/org/junitpioneer/testkit/assertion/ExecutionResultAssert.java b/src/test/java/org/junitpioneer/testkit/assertion/ExecutionResultAssert.java new file mode 100644 index 000000000..3ee662ff4 --- /dev/null +++ b/src/test/java/org/junitpioneer/testkit/assertion/ExecutionResultAssert.java @@ -0,0 +1,92 @@ +/* + * Copyright 2015-2020 the original author or authors. + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v2.0 which + * accompanies this distribution and is available at + * + * http://www.eclipse.org/legal/epl-v20.html + */ + +package org.junitpioneer.testkit.assertion; + +/** + * Base interface for all {@link org.junitpioneer.testkit.ExecutionResults} assertions. + */ +public interface ExecutionResultAssert { + + /** + * Asserts that the expected number of report entries were published across all executed tests. + * @param expected the number of report entries expected to be published + * @return a {@link ReportEntryAssert} for further assertions. + */ + ReportEntryAssert hasNumberOfReportEntries(int expected); + + /** + * Asserts that exactly one report entry was published across all executed tests. + * @return a {@link ReportEntryAssert} for further assertions. + */ + ReportEntryAssert hasSingleReportEntry(); + + /** + * Asserts that no report entries were published across all executed tests. + */ + void hasNoReportEntries(); + + TestCaseAssert hasSingleStartedTest(); + + FailureAssert hasSingleFailedTest(); + + void hasSingleAbortedTest(); + + /** + * Asserts that there was exactly one successful test. + *

+ * This is a convenience method that should be used by itself. + * If you want to assert an entire test suite with multiple tests, + * you should use {@code hasNumberOfSucceededTests(1)} (even if + * it is your last method) for better clarity. + */ + void hasSingleSucceededTest(); + + void hasSingleSkippedTest(); + + TestCaseAssert hasSingleDynamicallyRegisteredTest(); + + TestCaseAssert hasSingleStartedContainer(); + + FailureAssert hasSingleFailedContainer(); + + void hasSingleAbortedContainer(); + + void hasSingleSucceededContainer(); + + void hasSingleSkippedContainer(); + + TestCaseAssert hasSingleDynamicallyRegisteredContainer(); + + ExecutionResultAssert hasNumberOfStartedTests(int expected); + + ExecutionResultAssert hasNumberOfFailedTests(int expected); + + ExecutionResultAssert hasNumberOfAbortedTests(int expected); + + ExecutionResultAssert hasNumberOfSucceededTests(int expected); + + ExecutionResultAssert hasNumberOfSkippedTests(int expected); + + ExecutionResultAssert hasNumberOfDynamicallyRegisteredTests(int expected); + + ExecutionResultAssert hasNumberOfStartedContainers(int expected); + + ExecutionResultAssert hasNumberOfFailedContainers(int expected); + + ExecutionResultAssert hasNumberOfAbortedContainers(int expected); + + ExecutionResultAssert hasNumberOfSucceededContainers(int expected); + + ExecutionResultAssert hasNumberOfSkippedContainers(int expected); + + ExecutionResultAssert hasNumberOfDynamicallyRegisteredContainers(int expected); + +} diff --git a/src/test/java/org/junitpioneer/testkit/assertion/FailureAssert.java b/src/test/java/org/junitpioneer/testkit/assertion/FailureAssert.java new file mode 100644 index 000000000..aa07a4d05 --- /dev/null +++ b/src/test/java/org/junitpioneer/testkit/assertion/FailureAssert.java @@ -0,0 +1,33 @@ +/* + * Copyright 2015-2020 the original author or authors. + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v2.0 which + * accompanies this distribution and is available at + * + * http://www.eclipse.org/legal/epl-v20.html + */ + +package org.junitpioneer.testkit.assertion; + +import org.assertj.core.api.AbstractThrowableAssert; + +/** + * Used to assert a single failed container or test. + */ +public interface FailureAssert { + + /** + * Asserts that the test/container failed because of a specific type of exception. + * @param exceptionType the expected type of the thrown exception + * @return an {@link AbstractThrowableAssert} for further assertions + */ + AbstractThrowableAssert withExceptionInstanceOf(Class exceptionType); + + /** + * Asserts that the test/container failed because an exception was thrown. + * @return an {@link AbstractThrowableAssert} for further assertions + */ + AbstractThrowableAssert withException(); + +} diff --git a/src/test/java/org/junitpioneer/testkit/assertion/PioneerAssert.java b/src/test/java/org/junitpioneer/testkit/assertion/PioneerAssert.java new file mode 100644 index 000000000..4ba487b1e --- /dev/null +++ b/src/test/java/org/junitpioneer/testkit/assertion/PioneerAssert.java @@ -0,0 +1,215 @@ +/* + * Copyright 2015-2020 the original author or authors. + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v2.0 which + * accompanies this distribution and is available at + * + * http://www.eclipse.org/legal/epl-v20.html + */ + +package org.junitpioneer.testkit.assertion; + +import static java.util.stream.Collectors.toList; + +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import org.assertj.core.api.AbstractAssert; +import org.assertj.core.api.Assertions; +import org.junit.platform.engine.reporting.ReportEntry; +import org.junitpioneer.testkit.ExecutionResults; + +public class PioneerAssert extends AbstractAssert implements ExecutionResultAssert { + + public static ExecutionResultAssert assertThat(ExecutionResults actual) { + return new PioneerAssert(actual); + } + + private PioneerAssert(ExecutionResults actual) { + super(actual, PioneerAssert.class); + } + + @Override + public ReportEntryAssert hasNumberOfReportEntries(int expected) { + List> entries = reportEntries(); + Assertions.assertThat(entries).hasSize(expected); + Integer[] ones = IntStream.generate(() -> 1).limit(expected).boxed().toArray(Integer[]::new); + Assertions.assertThat(entries).extracting(Map::size).containsExactly(ones); + + List> entryList = entries + .stream() + .flatMap(map -> map.entrySet().stream()) + .collect(Collectors.toList()); + + return new ReportEntryAssert(entryList, expected); + } + + @Override + public ReportEntryAssert hasSingleReportEntry() { + return hasNumberOfReportEntries(1); + } + + @Override + public void hasNoReportEntries() { + Assertions.assertThat(reportEntries()).isEmpty(); + } + + @Override + public TestCaseAssert hasSingleStartedTest() { + return assertSingleTest(actual.testEvents().started().count()); + } + + @Override + public FailureAssert hasSingleFailedTest() { + return assertSingleTest(actual.testEvents().failed().count()); + } + + @Override + public void hasSingleAbortedTest() { + Assertions.assertThat(actual.testEvents().aborted().count()).isEqualTo(1); + } + + @Override + public void hasSingleSucceededTest() { + Assertions.assertThat(actual.testEvents().succeeded().count()).isEqualTo(1); + } + + @Override + public void hasSingleSkippedTest() { + Assertions.assertThat(actual.testEvents().skipped().count()).isEqualTo(1); + } + + @Override + public TestCaseAssert hasSingleDynamicallyRegisteredTest() { + return assertSingleTest(actual.testEvents().dynamicallyRegistered().count()); + } + + private TestAssertBase assertSingleTest(long numberOfTestsWithOutcome) { + Assertions.assertThat(numberOfTestsWithOutcome).isEqualTo(1); + return new TestAssertBase(actual.testEvents()); + } + + @Override + public TestCaseAssert hasSingleStartedContainer() { + return assertSingleContainer(actual.containerEvents().started().count()); + } + + @Override + public FailureAssert hasSingleFailedContainer() { + return assertSingleContainer(actual.containerEvents().failed().count()); + } + + @Override + public void hasSingleAbortedContainer() { + Assertions.assertThat(actual.containerEvents().aborted().count()).isEqualTo(1); + } + + @Override + public void hasSingleSucceededContainer() { + Assertions.assertThat(actual.containerEvents().succeeded().count()).isEqualTo(1); + } + + @Override + public void hasSingleSkippedContainer() { + Assertions.assertThat(actual.containerEvents().skipped().count()).isEqualTo(1); + } + + @Override + public TestCaseAssert hasSingleDynamicallyRegisteredContainer() { + return assertSingleContainer(actual.containerEvents().dynamicallyRegistered().count()); + } + + private TestAssertBase assertSingleContainer(long numberOfContainersWithOutcome) { + Assertions.assertThat(numberOfContainersWithOutcome).isEqualTo(1); + return new TestAssertBase(actual.containerEvents()); + } + + @Override + public ExecutionResultAssert hasNumberOfStartedTests(int expected) { + Assertions.assertThat(actual.testEvents().started().count()).isEqualTo(expected); + return this; + } + + @Override + public ExecutionResultAssert hasNumberOfFailedTests(int expected) { + Assertions.assertThat(actual.testEvents().failed().count()).isEqualTo(expected); + return this; + } + + @Override + public ExecutionResultAssert hasNumberOfAbortedTests(int expected) { + Assertions.assertThat(actual.testEvents().aborted().count()).isEqualTo(expected); + return this; + } + + @Override + public ExecutionResultAssert hasNumberOfSucceededTests(int expected) { + Assertions.assertThat(actual.testEvents().succeeded().count()).isEqualTo(expected); + return this; + } + + @Override + public ExecutionResultAssert hasNumberOfSkippedTests(int expected) { + Assertions.assertThat(actual.testEvents().skipped().count()).isEqualTo(expected); + return this; + } + + @Override + public ExecutionResultAssert hasNumberOfDynamicallyRegisteredTests(int expected) { + Assertions.assertThat(actual.testEvents().dynamicallyRegistered().count()).isEqualTo(expected); + return this; + } + + @Override + public ExecutionResultAssert hasNumberOfStartedContainers(int expected) { + Assertions.assertThat(actual.containerEvents().started().count()).isEqualTo(expected); + return this; + } + + @Override + public ExecutionResultAssert hasNumberOfFailedContainers(int expected) { + Assertions.assertThat(actual.containerEvents().failed().count()).isEqualTo(expected); + return this; + } + + @Override + public ExecutionResultAssert hasNumberOfAbortedContainers(int expected) { + Assertions.assertThat(actual.containerEvents().aborted().count()).isEqualTo(expected); + return this; + } + + @Override + public ExecutionResultAssert hasNumberOfSucceededContainers(int expected) { + Assertions.assertThat(actual.containerEvents().succeeded().count()).isEqualTo(expected); + return this; + } + + @Override + public ExecutionResultAssert hasNumberOfSkippedContainers(int expected) { + Assertions.assertThat(actual.containerEvents().skipped().count()).isEqualTo(expected); + return this; + } + + @Override + public ExecutionResultAssert hasNumberOfDynamicallyRegisteredContainers(int expected) { + Assertions.assertThat(actual.containerEvents().dynamicallyRegistered().count()).isEqualTo(expected); + return this; + } + + private List> reportEntries() { + return actual + .allEvents() + .reportingEntryPublished() + .stream() + .map(event -> event.getPayload(ReportEntry.class)) + .filter(Optional::isPresent) + .map(Optional::get) + .map(ReportEntry::getKeyValuePairs) + .collect(toList()); + } + +} diff --git a/src/test/java/org/junitpioneer/testkit/assertion/ReportEntryAssert.java b/src/test/java/org/junitpioneer/testkit/assertion/ReportEntryAssert.java new file mode 100644 index 000000000..7b6eaa5d5 --- /dev/null +++ b/src/test/java/org/junitpioneer/testkit/assertion/ReportEntryAssert.java @@ -0,0 +1,55 @@ +/* + * Copyright 2015-2020 the original author or authors. + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v2.0 which + * accompanies this distribution and is available at + * + * http://www.eclipse.org/legal/epl-v20.html + */ + +package org.junitpioneer.testkit.assertion; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.AbstractMap; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; + +/** + * Used to assert a report entries. + */ +public class ReportEntryAssert extends AbstractPioneerAssert>> { + + ReportEntryAssert(List> entries, int expected) { + super(entries, ReportEntryAssert.class, expected); + } + + public void withKeyAndValue(String key, String value) { + if (expected != 1) + throw new IllegalArgumentException("Can not verify key and value for non-single report entry!"); + assertThat(actual).containsExactly(new AbstractMap.SimpleEntry<>(key, value)); + } + + public void withValues(String... expected) { + Stream values = actual.stream().map(Map.Entry::getValue); + assertThat(values).containsExactlyInAnyOrder(expected); + } + + public void withKeyValuePairs(String... keyAndValuePairs) { + if (keyAndValuePairs.length % 2 != 0) + throw new IllegalArgumentException("Can not verify key-value pairs because some elements are missing."); + assertThat(actual).containsExactlyInAnyOrderElementsOf(asEntryList(keyAndValuePairs)); + } + + private Iterable> asEntryList(String... values) { + List> entryList = new ArrayList<>(); + for (int i = 0; i < values.length; i += 2) { + entryList.add(new AbstractMap.SimpleEntry<>(values[i], values[i + 1])); + } + return entryList; + } + +} diff --git a/src/test/java/org/junitpioneer/testkit/assertion/TestAssertBase.java b/src/test/java/org/junitpioneer/testkit/assertion/TestAssertBase.java new file mode 100644 index 000000000..4d2f3236c --- /dev/null +++ b/src/test/java/org/junitpioneer/testkit/assertion/TestAssertBase.java @@ -0,0 +1,69 @@ +/* + * Copyright 2015-2020 the original author or authors. + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v2.0 which + * accompanies this distribution and is available at + * + * http://www.eclipse.org/legal/epl-v20.html + */ + +package org.junitpioneer.testkit.assertion; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Optional; + +import org.assertj.core.api.AbstractThrowableAssert; +import org.assertj.core.api.ThrowableAssert; +import org.junit.platform.engine.TestExecutionResult; +import org.junit.platform.testkit.engine.Events; + +class TestAssertBase extends AbstractPioneerAssert implements TestCaseAssert, FailureAssert { + + TestAssertBase(Events events) { + super(events, TestAssertBase.class, 1); + } + + @Override + public AbstractThrowableAssert withExceptionInstanceOf( + Class exceptionType) { + Optional thrown = throwable(); + assertThat(thrown).isPresent(); + assertThat(thrown.get()).isInstanceOf(exceptionType); + return new ThrowableAssert(thrown.get()); + } + + @Override + public AbstractThrowableAssert withException() { + Optional thrown = throwable(); + assertThat(thrown).isPresent(); + return new ThrowableAssert(thrown.get()); + } + + private Optional throwable() { + return actual + .failed() + .stream() + .findFirst() + .flatMap(fail -> fail.getPayload(TestExecutionResult.class)) + .flatMap(TestExecutionResult::getThrowable); + } + + @Override + public FailureAssert whichFailed() { + assertThat(actual.failed().count()).isEqualTo(1); + return this; + } + + @Override + public void whichSucceeded() { + assertThat(actual.succeeded().count()).isEqualTo(1); + } + + @Override + public void whichAborted() { + assertThat(actual.aborted().count()).isEqualTo(1); + } + +} diff --git a/src/test/java/org/junitpioneer/testkit/assertion/TestCaseAssert.java b/src/test/java/org/junitpioneer/testkit/assertion/TestCaseAssert.java new file mode 100644 index 000000000..44b98fff2 --- /dev/null +++ b/src/test/java/org/junitpioneer/testkit/assertion/TestCaseAssert.java @@ -0,0 +1,34 @@ +/* + * Copyright 2015-2020 the original author or authors. + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v2.0 which + * accompanies this distribution and is available at + * + * http://www.eclipse.org/legal/epl-v20.html + */ + +package org.junitpioneer.testkit.assertion; + +/** + * This interface contains methods for asserting a single test or a single container. + */ +public interface TestCaseAssert { + + /** + * Asserts that the test/container has succeeded. + */ + void whichSucceeded(); + + /** + * Asserts that the test/container was aborted. + */ + void whichAborted(); + + /** + * Asserts that the test/container has failed. + * @return a {@link FailureAssert} for further assertions. + */ + FailureAssert whichFailed(); + +} diff --git a/src/test/java/org/junitpioneer/vintage/TestIntegrationTests.java b/src/test/java/org/junitpioneer/vintage/TestIntegrationTests.java index bcb96a52d..c9667401d 100644 --- a/src/test/java/org/junitpioneer/vintage/TestIntegrationTests.java +++ b/src/test/java/org/junitpioneer/vintage/TestIntegrationTests.java @@ -12,10 +12,12 @@ import static java.lang.String.format; import static org.assertj.core.api.Assertions.assertThat; +import static org.junitpioneer.testkit.assertion.PioneerAssert.assertThat; import static org.junitpioneer.vintage.ExpectedExceptionExtension.EXPECTED_EXCEPTION_WAS_NOT_THROWN; import java.nio.file.InvalidPathException; +import org.junit.jupiter.api.extension.ExtensionConfigurationException; import org.junitpioneer.testkit.ExecutionResults; import org.junitpioneer.testkit.PioneerTestKit; @@ -28,16 +30,14 @@ class TestIntegrationTests { void test_successfulTest_passes() throws Exception { ExecutionResults results = PioneerTestKit.executeTestMethod(TestTestCase.class, "test_successfulTest"); - assertThat(results.numberOfStartedTests()).isEqualTo(1); - assertThat(results.numberOfSucceededTests()).isEqualTo(1); + assertThat(results).hasSingleStartedTest().whichSucceeded(); } @org.junit.jupiter.api.Test void test_exceptionThrown_fails() throws Exception { ExecutionResults results = PioneerTestKit.executeTestMethod(TestTestCase.class, "test_exceptionThrown"); - assertThat(results.numberOfStartedTests()).isEqualTo(1); - assertThat(results.numberOfFailedTests()).isEqualTo(1); + assertThat(results).hasSingleStartedTest().whichFailed(); } // expected exception @@ -47,12 +47,11 @@ void testWithExpectedException_successfulTest_fails() { ExecutionResults results = PioneerTestKit .executeTestMethod(TestTestCase.class, "testWithExpectedException_successfulTest"); - assertThat(results.numberOfStartedTests()).isEqualTo(1); - assertThat(results.numberOfFailedTests()).isEqualTo(1); - - String failedTestMessage = results.firstFailuresThrowableMessage(); - String expectedMessage = format(EXPECTED_EXCEPTION_WAS_NOT_THROWN, IllegalArgumentException.class); - assertThat(failedTestMessage).contains(expectedMessage); + assertThat(results) + .hasSingleStartedTest() + .whichFailed() + .withException() + .hasMessageContainingAll(format(EXPECTED_EXCEPTION_WAS_NOT_THROWN, IllegalArgumentException.class)); } @org.junit.jupiter.api.Test @@ -60,8 +59,7 @@ void testWithExpectedException_exceptionThrownOfRightType_passes() { ExecutionResults results = PioneerTestKit .executeTestMethod(TestTestCase.class, "testWithExpectedException_exceptionThrownOfRightType"); - assertThat(results.numberOfStartedTests()).isEqualTo(1); - assertThat(results.numberOfSucceededTests()).isEqualTo(1); + assertThat(results).hasSingleStartedTest().whichSucceeded(); } @org.junit.jupiter.api.Test @@ -69,8 +67,7 @@ void testWithExpectedException_exceptionThrownOfSubtype_passes() { ExecutionResults results = PioneerTestKit .executeTestMethod(TestTestCase.class, "testWithExpectedException_exceptionThrownOfSubtype"); - assertThat(results.numberOfStartedTests()).isEqualTo(1); - assertThat(results.numberOfSucceededTests()).isEqualTo(1); + assertThat(results).hasSingleStartedTest().whichSucceeded(); } @org.junit.jupiter.api.Test @@ -78,10 +75,7 @@ void testWithExpectedException_exceptionThrownOfSupertype_fails() { ExecutionResults results = PioneerTestKit .executeTestMethod(TestTestCase.class, "testWithExpectedException_exceptionThrownOfSupertype"); - assertThat(results.numberOfStartedTests()).isEqualTo(1); - assertThat(results.numberOfFailedTests()).isEqualTo(1); - - results.assertTestFailedWithThrowable(RuntimeException.class); + assertThat(results).hasSingleStartedTest().whichFailed().withExceptionInstanceOf(RuntimeException.class); } // timeout @@ -90,32 +84,29 @@ void testWithExpectedException_exceptionThrownOfSupertype_fails() { void testWithTimeout_belowZero_failsConfiguration() { ExecutionResults results = PioneerTestKit.executeTestMethod(TestTestCase.class, "testWithTimeout_belowZero"); - results.assertTestFailedWithExtensionConfigurationException(); + assertThat(results).hasSingleFailedTest().withExceptionInstanceOf(ExtensionConfigurationException.class); } @org.junit.jupiter.api.Test void testWithTimeout_belowTimeout_passes() { ExecutionResults results = PioneerTestKit.executeTestMethod(TestTestCase.class, "testWithTimeout_belowTimeout"); - assertThat(results.numberOfStartedTests()).isEqualTo(1); - assertThat(results.numberOfSucceededTests()).isEqualTo(1); + assertThat(results).hasSingleStartedTest().whichSucceeded(); } @org.junit.jupiter.api.Test void testWithTimeout_exceedsTimeout_fails() throws Exception { ExecutionResults results = PioneerTestKit .executeTestMethod(TestTestCase.class, "testWithTimeout_exceedsTimeout"); - - assertThat(results.numberOfStartedTests()).isEqualTo(1); - assertThat(results.numberOfFailedTests()).isEqualTo(1); - - String failedTestMessage = results.firstFailuresThrowableMessage(); - String expectedMessage = String - .format(TimeoutExtension.TEST_RAN_TOO_LONG, "testWithTimeout_exceedsTimeout()", 1, 10); + String expectedMessage = format(TimeoutExtension.TEST_RAN_TOO_LONG, "testWithTimeout_exceedsTimeout()", 1); // the message contains the actual run time, which is unpredictable, so it has to be cut off for the assertion String expectedKnownPrefix = expectedMessage.substring(0, expectedMessage.length() - 6); - assertThat(failedTestMessage).isNotNull(); - assertThat(failedTestMessage).startsWith(expectedKnownPrefix); + + assertThat(results) + .hasSingleStartedTest() + .whichFailed() + .withException() + .hasMessageContainingAll(expectedKnownPrefix); } // TEST CASES -------------------------------------------------------------------