The JUnit Framework

Péter Jeszenszky

2021.05.09.

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

SUnit is a unit testing framework for the SmallTalk programming language that is considered to be the mother of all unit testing frameworks. It was written by Kent Beck in 1994. Website: http://sunit.sourceforge.net/ See: Martin Fowler. xUnit. 17 January 2006. https://martinfowler.com/bliki/Xunit.html

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

xUnit is a family of unit testing frameworks that follow the architecture of the SUnit unit testing framework for the SmallTalk programming language. 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 languages.

Péter Jeszenszky The JUnit Unit Testing Framework 2021.05.09. 3 / 25 xUnit (3)

Other notable members of the xUnit family: C++: CppUnit (license: GNU LGPLv2.1) https://www.freedesktop.org/wiki/Software/cppunit/ .NET: NUnit (license: MIT License) https://nunit.org/ https://github.com/nunit/nunit 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. 4 / 25 JUnit History

JUnit was written by Kent Beck and Erich Gamma in 1997. The current major version is 5.

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

License: Eclipse Public License 2.0 Website: https://junit.org/junit5/ Repository: https://github.com/junit-team/junit5 Maven Central: JUnit artifacts are available in Maven Central The list of JUnit artifacts: https://junit.org/junit5/docs/current/user- guide/#dependency-metadata Documentation: JUnit 5 User Guide https://junit.org/junit5/docs/current/user-guide/ Javadoc: https://junit.org/junit5/docs/current/api/

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

JUnit 5 has a modular structure: JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage

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

JUnit Platform: It serves as a foundation for launching testing frameworks on the JVM. It defines the TestEngine API for developing testing frameworks that runs on the platform. It also provides a ConsoleLauncher to launch the platform from the command line. JUnit Platform is supported by popular IDEs (e.g., IntelliJ IDEA, Eclipse, NetBeans, and Visual Studio Code) and build tools (e.g., Apache Maven and Gradle). JUnit Jupiter: It defines a programming model and an extension model for writing tests and extensions in JUnit 5. It also provides a 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. 8 / 25 IDE support

Apache NetBeans: Writing JUnit Tests in NetBeans IDE http://netbeans.apache.org/kb/docs/java/junit-intro.html Eclipse IDE: IntelliJ IDEA: https://www.jetbrains.com/help/idea/testing.html

Péter Jeszenszky The JUnit Unit Testing Framework 2021.05.09. 9 / 25 Apache Maven Support

Apache Maven Surefire https://maven.apache.org/surefire/ https://github.com/apache/maven-surefire Maven Surefire Plugin https://maven.apache.org/surefire/maven-surefire-plugin/ Maven Surefire Report Plugin https://maven.apache.org/surefire/maven-surefire-report-plugin/

Péter Jeszenszky The JUnit Unit Testing Framework 2021.05.09. 10 / 25 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. Test method: any instance method that is annotated with @Test, @RepeatedTest, @ParameterizedTest, @TestFactory, or @TestTemplate. 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. 11 / 25 Test Classes and Methods (2)

Test classes, test methods, and lifecycle methods are not required to be public, but they must not be private. Test methods and lifecycle methods: May be declared locally within the current test class, inherited from superclasses, or inherited from interfaces. Must not be abstract and must not return a value. 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. 12 / 25 Test Execution Lifecycle (1)

By default, JUnit creates a new instance of each test class before executing each test method that allows individual test methods to be executed in isolation. This “per-method” behavior can be changed, to execute all test methods on the same test instance, annotate a test class with @TestInstance(Lifecycle.PER_CLASS).

Péter Jeszenszky The JUnit Unit Testing Framework 2021.05.09. 13 / 25 Test Execution Lifecycle (2)

Example:

import org.junit.jupiter.api.*;

public class LifeCycleTest {

LifeCycleTest() { System.out.printf("Constructor creates %s\n", this); }

@BeforeAll static void beforeAll() { System.out.println("@BeforeAll static method invoked"); }

@AfterAll static void afterAll() { System.out.println("@AfterAll static method invoked"); }

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

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

@Test 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 Test Execution Lifecycle (3)

Example: @BeforeAll static method invoked Constructor creates LifeCycleTest@2145433b @BeforeEach method invoked on LifeCycleTest@2145433b testMethod1() method invoked on LifeCycleTest@2145433b @AfterEach method invoked on LifeCycleTest@2145433b Constructor creates LifeCycleTest@fdefd3f @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. 15 / 25 Test Execution Order

By default, test methods will be ordered using an algorithm that is deterministic but intentionally nonobvious. This ensures that subsequent runs of a test suite execute test methods in the same order, thereby allowing for repeatable builds. Although true unit tests typically should not rely on the order in which they are executed, there are times when it is necessary to enforce a specific test method execution order. The @TestMethodOrder annotation is provided to control the order in which test methods are executed.

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

Assertion/matcher libraries: AssertJ (license: Apache License 2.0) https://assertj.github.io/doc/ https://github.com/assertj/assertj-core Hamcrest http://hamcrest.org/ Hamcrest (license: BSD 3-Clause License) http://hamcrest.org/JavaHamcrest/ https://github.com/hamcrest/JavaHamcrest PyHamcrest (license: BSD 3-Clause License) https://github.com/hamcrest/PyHamcrest ...

Péter Jeszenszky The JUnit Unit Testing Framework 2021.05.09. 17 / 25 Related Libraries and Frameworks (2)

Mocking frameworks: EasyMock (license: Apache License 2.0) https://easymock.org/ https://github.com/easymock/easymock (license: MIT License) https://site.mockito.org/ https://github.com/mockito/mockito PowerMock (license: Apache License 2.0) https://github.com/powermock/powermock

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

Databases: DbUnit (license: GNU LGPLv2.1) http://dbunit.sourceforge.net/ Headless browsers: HtmlUnit (license: Apache License 2.0) https://htmlunit.sourceforge.io/ https://github.com/HtmlUnit/htm

Péter Jeszenszky The JUnit Unit Testing Framework 2021.05.09. 19 / 25 Capturing System.out with System Lambda (1)

The System Lambda library provides support for testing code that uses java.lang.System. License: MIT License Repository: https://github.com/stefanbirkner/system-lambda Availability in Maven Central: com.github.stefanbirkner:system-lambda:1.2.0

Péter Jeszenszky The JUnit Unit Testing Framework 2021.05.09. 20 / 25 Capturing System.out with System Lambda (2)

Example: @Test void testMain() throws Exception { String output = tapSystemOut(() -> HelloWorld.main( new String[] {})); assertEquals("Hello, World!\n", output); }

Péter Jeszenszky The JUnit Unit Testing Framework 2021.05.09. 21 / 25 Capturing System.out with System Lambda (3)

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. Example: @Test void testMain() throws Exception { 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 Examples from the Industry: Apache Commons Lang (1)

org.apache.commons.lang3.StringUtils: StringUtils.java Javadoc JUnit 5 unit tests: StringUtilsContainsTest.java StringUtilsSubstringTest.java StringUtilsTest.java

Péter Jeszenszky The JUnit Unit Testing Framework 2021.05.09. 23 / 25 Examples from the Industry: Apache Commons Lang (2)

org.apache.commons.lang3.BitField: BitField.java Javadoc BitFieldTest.java

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