<<

xUnit (1)

The JUnit Framework xUnit is a family of unit testing frameworks that follow the architecture of the SUnit unit testing framework for the programming language. Péter Jeszenszky JUnit was the first member of the xUnit family that became widely used and popular. Over the years JUnit have been ported to many other programming 2021.05.09. languages.

Péter Jeszenszky The JUnit Unit Testing Framework 2021.05.09. 1 / 25 Péter Jeszenszky The JUnit Unit Testing Framework 2021.05.09. 3 / 25

SUnit xUnit (3)

Other notable members of the xUnit family: C++: SUnit is a unit testing framework for the SmallTalk programming language that is considered to be the mother of all unit testing frameworks. CppUnit (license: GNU LGPLv2.1) https://www.freedesktop.org/wiki/Software/cppunit/ It was written by in 1994. .NET: Website: http://sunit.sourceforge.net/ NUnit (license: MIT License) https://nunit.org/ See: Martin Fowler. xUnit. 17 January 2006. https://github.com/nunit/nunit https://martinfowler.com/bliki/Xunit.html Python: unittest (license: Python Software Foundation License) https://docs.python.org/3/library/unittest.html

Péter Jeszenszky The JUnit Unit Testing Framework 2021.05.09. 2 / 25 Péter Jeszenszky The JUnit Unit Testing Framework 2021.05.09. 4 / 25 JUnit History Architecture (1)

JUnit was written by Kent Beck and Erich Gamma in 1997. JUnit 5 has a modular structure: The current major version is 5. JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage

Péter Jeszenszky The JUnit Unit Testing Framework 2021.05.09. 5 / 25 Péter Jeszenszky The JUnit Unit Testing Framework 2021.05.09. 7 / 25

JUnit Availability Architecture (2)

JUnit Platform: It serves as a foundation for launching testing frameworks on the JVM. It defines the TestEngine API for developing License: Eclipse Public License 2.0 testing frameworks that runs on the platform. It also provides a Website: https://junit.org/junit5/ ConsoleLauncher to launch the platform from the command line. Repository: https://github.com/junit-team/junit5 JUnit Platform is supported by popular IDEs (e.g., IntelliJ IDEA, Maven Central: JUnit artifacts are available in Maven Central Eclipse, NetBeans, and Visual Studio Code) and build tools (e.g., The list of JUnit artifacts: https://junit.org/junit5/docs/current/user- and Gradle). guide/#dependency-metadata Documentation: JUnit Jupiter: It defines a programming model and an extension JUnit 5 User Guide https://junit.org/junit5/docs/current/user-guide/ model for writing tests and extensions in JUnit 5. It also provides a Javadoc: https://junit.org/junit5/docs/current/api/ TestEngine for running Jupiter based tests on the platform. JUnit Vintage: provides a TestEngine for running JUnit 3 and JUnit 4 based tests on the platform.

Péter Jeszenszky The JUnit Unit Testing Framework 2021.05.09. 6 / 25 Péter Jeszenszky The JUnit Unit Testing Framework 2021.05.09. 8 / 25 IDE support Test Classes and Methods (1)

Test class: any top-level class, static member class, or @Nested class that contains at least one test method. Must not be abstract and must have a single constructor. Apache NetBeans: Writing JUnit Tests in NetBeans IDE http://netbeans.apache.org/kb/docs/java/junit-intro.html Test method: any instance method that is annotated with @Test, @RepeatedTest, @ParameterizedTest, @TestFactory, or Eclipse IDE: @TestTemplate. IntelliJ IDEA: https://www.jetbrains.com/help/idea/testing.html Lifecycle Method: any method that is annotated with @BeforeAll, @AfterAll, @BeforeEach, or @AfterEach. Methods annotated with @BeforeAll and @AfterAll must be static (unless the @TestInstance(Lifecycle.PER_CLASS) annotation is present).

Péter Jeszenszky The JUnit Unit Testing Framework 2021.05.09. 9 / 25 Péter Jeszenszky The JUnit Unit Testing Framework 2021.05.09. 11 / 25

Apache Maven Support Test Classes and Methods (2)

Test classes, test methods, and lifecycle methods are not required to be Apache Maven Surefire https://maven.apache.org/surefire/ public, but they must not be private. https://github.com/apache/maven-surefire Test methods and lifecycle methods: Maven Surefire Plugin May be declared locally within the current test class, inherited from https://maven.apache.org/surefire/maven-surefire-plugin/ superclasses, or inherited from interfaces. Maven Surefire Report Plugin Must not be abstract and must not return a value. https://maven.apache.org/surefire/maven-surefire-report-plugin/ Both test constructors and methods are permitted to have parameters that enables dependency injection for constructors and methods.

Péter Jeszenszky The JUnit Unit Testing Framework 2021.05.09. 10 / 25 Péter Jeszenszky The JUnit Unit Testing Framework 2021.05.09. 12 / 25 Test Execution Lifecycle (1) Test Execution Lifecycle (3)

Example: @BeforeAll static method invoked By default, JUnit creates a new instance of each test class before executing Constructor creates LifeCycleTest@2145433b each test method that allows individual test methods to be executed in @BeforeEach method invoked on LifeCycleTest@2145433b isolation. testMethod1() method invoked on LifeCycleTest@2145433b This “per-method” behavior can be changed, to execute all test methods on @AfterEach method invoked on LifeCycleTest@2145433b the same test instance, annotate a test class with Constructor creates LifeCycleTest@fdefd3f @TestInstance(Lifecycle.PER_CLASS). @BeforeEach method invoked on LifeCycleTest@fdefd3f testMethod2() method invoked on LifeCycleTest@fdefd3f @AfterEach method invoked on LifeCycleTest@fdefd3f @AfterAll static method invoked

Péter Jeszenszky The JUnit Unit Testing Framework 2021.05.09. 13 / 25 Péter Jeszenszky The JUnit Unit Testing Framework 2021.05.09. 15 / 25

Test Execution Lifecycle (2) Test Execution Order

Example: import org.junit.jupiter.api.*; public class LifeCycleTest { By default, test methods will be ordered using an algorithm that is LifeCycleTest() { deterministic but intentionally nonobvious. This ensures that subsequent System.out.printf("Constructor creates %s\n", this); } runs of a test suite execute test methods in the same order, thereby @BeforeAll allowing for repeatable builds. static void beforeAll() { System.out.println("@BeforeAll static method invoked"); }

@AfterAll Although true unit tests typically should not rely on the order in which they static void afterAll() { System.out.println("@AfterAll static method invoked"); } are executed, there are times when it is necessary to enforce a specific test @BeforeEach void beforeEach() { System.out.printf("@BeforeEach method invoked on %s\n", this); } method execution order.

@AfterEach void afterEach() { System.out.printf("@AfterEach method invoked on %s\n", this); } The @TestMethodOrder annotation is provided to control the order in

@Test which test methods are executed. void testMethod1() { System.out.printf("testMethod1() method invoked on %s\n", this); }

@Test void testMethod2() { System.out.printf("testMethod2() method invoked on %s\n", this); }

}

Péter Jeszenszky The JUnit Unit Testing Framework 2021.05.09. 14 / 25 Péter Jeszenszky The JUnit Unit Testing Framework 2021.05.09. 16 / 25 Related Libraries and Frameworks (1) Related Libraries and Frameworks (3)

Assertion/matcher libraries:

AssertJ (license: Apache License 2.0) https://assertj.github.io/doc/ Databases: https://github.com/assertj/assertj-core DbUnit (license: GNU LGPLv2.1) http://dbunit.sourceforge.net/ Hamcrest http://hamcrest.org/ Headless browsers: Java Hamcrest (license: BSD 3-Clause License) http://hamcrest.org/JavaHamcrest/ HtmlUnit (license: Apache License 2.0) https://github.com/hamcrest/JavaHamcrest https://htmlunit.sourceforge.io/ https://github.com/HtmlUnit/htm PyHamcrest (license: BSD 3-Clause License) https://github.com/hamcrest/PyHamcrest ...

Péter Jeszenszky The JUnit Unit Testing Framework 2021.05.09. 17 / 25 Péter Jeszenszky The JUnit Unit Testing Framework 2021.05.09. 19 / 25

Related Libraries and Frameworks (2) Capturing System.out with System Lambda (1)

Mocking frameworks: The System Lambda library provides support for testing code that uses EasyMock (license: Apache License 2.0) https://easymock.org/ java.lang.System. https://github.com/easymock/easymock License: MIT License (license: MIT License) https://site.mockito.org/ Repository: https://github.com/stefanbirkner/system-lambda https://github.com/mockito/mockito Availability in Maven Central: PowerMock (license: Apache License 2.0) com.github.stefanbirkner:system-lambda:1.2.0 https://github.com/powermock/powermock

Péter Jeszenszky The JUnit Unit Testing Framework 2021.05.09. 18 / 25 Péter Jeszenszky The JUnit Unit Testing Framework 2021.05.09. 20 / 25 Capturing System.out with System Lambda (2) Examples from the Industry: Apache Commons Lang (1)

Example: org.apache.commons.lang3.StringUtils: @Test StringUtils.java void testMain() throws Exception { Javadoc String output = tapSystemOut(() -> HelloWorld.main( JUnit 5 unit tests: new String[] {})); StringUtilsContainsTest.java assertEquals("Hello, World!\n", output); StringUtilsSubstringTest.java } StringUtilsTest.java

Péter Jeszenszky The JUnit Unit Testing Framework 2021.05.09. 21 / 25 Péter Jeszenszky The JUnit Unit Testing Framework 2021.05.09. 23 / 25

Capturing System.out with System Lambda (3) Examples from the Industry: Apache Commons Lang (2)

The methods with the suffix Normalized normalize line breaks to \n so that you can run tests with the same assertions on different operating systems. org.apache.commons.lang3.BitField: Example: BitField.java @Test Javadoc void testMain() throws Exception { BitFieldTest.java String output = tapSystemOutNormalized(() -> HelloWorld.main(new String[] {})); assertEquals("Hello, World!\n", output); }

Péter Jeszenszky The JUnit Unit Testing Framework 2021.05.09. 22 / 25 Péter Jeszenszky The JUnit Unit Testing Framework 2021.05.09. 24 / 25 Further Recommended Reading

Cătălin Tudose. JUnit in Action. 3rd ed. Manning Publications, 2021. https://github.com/ctudose/junit-in-action-third-edition Boni Garcia. Mastering with JUnit 5. Packt Publishing, 2017. https://github.com/PacktPublishing/Mastering- Software-Testing-with-JUnit-5

Péter Jeszenszky The JUnit Unit Testing Framework 2021.05.09. 25 / 25