JUnit: Difference between revisions
imported>Lent m →Previous versions of JUnit: wikilink OOPSLA |
(No difference)
|
Latest revision as of 21:01, 17 April 2025
Template:Short description Template:Redirect Template:Infobox software
JUnit is a test automation framework for the Java programming language. JUnit is often used for unit testing, and is one of the xUnit frameworks.
JUnit is linked as a JAR at compile-time. The latest version of the framework, JUnit 5, resides under package Template:Code.Template:Sfn Previous versions JUnit 4Template:Sfn and JUnit 3 were under packages Template:Code and Template:Code, respectively.
A research survey performed in 2013 across 10,000 Java projects hosted on GitHub found that JUnit (in a tie with slf4j-api) was the most commonly included external library. Each library was used by 30.7% of projects.<ref>Template:Cite web</ref>
JUnit Lifecycle
[edit]Every JUnit test class usually has several test cases. These test cases are subject to the test life cycle. The full JUnit Lifecycle has three major phases:Template:Sfn
- Setup phase - This phase is where the test infrastructure is prepared. Two levels of setup are available. The first type of setup is class-level setup in which a computationally expensive object, such as a database connection, is created and reused, with minimal side effects. Class-level setup is implemented using the Template:Code annotation. The other type is setup before running each test case, which uses the Template:Code annotation.Template:Sfn
- Test execution - This phase is responsible for running the test and verifying the result. The test result will indicate if the test result is a success or a failure. The Template:Code annotation is used here.Template:Sfn
- Clean up phase - After all posttest executions are performed, the system may need to perform cleanup. Similar to class-level setup, there is a corresponding class-level clean up. The Template:Code annotation is used to support class-level clean up. The Template:Code annotation allows for cleanup after test execution.Template:Sfn
Integration with other tools
[edit]JUnit 5 integrates a number of tools, such as build tools, integrated development environments (IDE), continuous integration (CI) tools and many more.Template:Sfn
Build Tools
[edit]Template:Main article JUnit supports Apache Ant, Apache Maven and Gradle build tools, which are the most widely used project build tools.Template:Sfn Build tools are vital for automating the process of building the project. Template:Sfn
Ant Extension
[edit]Template:Main article
Apache Ant, also known as Ant, is one of the build tools with the highest degree of versatility, and has the longest history out of the three build tools listed above.Template:Sfn Ant centers around the build.xml
file, used for configuring the tasks necessary to run a project.Template:Sfn Ant also has an extension called Apache Ivy, which helps deal with dependency resolution. The project dependencies can be declared in the ivy.xml
file. Ant can integrate with JUnit 5 by configuring the Java code coverage tools (JaCoCo), for the ivy.xml
file.Template:Sfn The ivy.xml
can then be configured with the java-platform-console
and junit-platform-runner
dependencies to integrate with JUnit 5. Template:Sfn
Maven Extension
[edit]In contrast to Ant, Apache Maven, also known as Maven, uses a standardized and unified approach to the build process.Template:Sfn Maven follows the paradigm of "convention over configuration" for managing its dependencies.Template:Sfn The Java source code (or "src") can be found under the src/main/java
directory, and the test files can be found under the src/test/java
directory.Template:Sfn Maven can be used for any Java Project.Template:Sfn It uses the Project Object Model (POM), which is an XML-based approach to configuring the build steps for the project.Template:Sfn The minimal Maven with the pom.xml
build file must contain a list of dependencies and a unique project identifier.Template:Sfn Maven must be available on the build path to work.Template:Sfn Maven can integrate with JUnit 5 using the jacoco-maven-plugin
plugin which supports out-of-box functionality for JUnit 5 tests.Template:Sfn Different Maven goals can be specified to achieve these tasks.Template:Sfn
Gradle Extension
[edit]Gradle is a build tool that borrows many concepts from its predecessors, Ant and Maven.Template:Sfn It uses the Template:Code file to declare the steps required for the project build.Template:Sfn Unlike Ant and Maven, which are XML-based, Gradle requires the use of Apache Groovy, which is a Java-based programming language.Template:Sfn Unlike Ant and Maven, Gradle does not require the use of XML.Template:Sfn Gradle still adheres to Maven's "convention over configuration" approach, and follows the same structure for Template:Code and Template:Code directories.Template:Sfn Gradle can integrate with JUnit 5 by configuring a plugin Template:Code alongside the junit-platform plug-in given by the JUnit 5 team in the build file.Template:Sfn
JUnit Extension Model
[edit]JUnit follows the paradigm of preferring extension points over features.Template:Sfn The JUnit team decided not to put all features within the JUnit core, and instead decided to give an extensible way for developers to address their concerns.Template:Sfn
In JUnit 4, there are two extension mechanisms: the Runner API and Rule API.Template:Sfn There were some disadvantages to both the Runner API and the Rule API.
A major limitation of the Runner API is that developers must implement the entire test lifecycle, even if only a specific phase is required.Template:Sfn This is too complicated and heavyweight for most use cases.Template:Sfn Another major limitation is that only one runner class can be used per test case, which makes runners non-composable.Template:Sfn For example, Mockito and Parameterized runners cannot be used together within the same test class.Template:Sfn
A major limitation of the Rule API is that it cannot control the entire test lifecycle and is therefore unsuitable for certain use cases.Template:Sfn Rules are only suitable for operations that need to run before or after test execution.Template:Sfn Another limitation is that class-level and method-level rules must be defined separately.Template:Sfn
In JUnit 5, the extension API is found within the JUnit Jupiter Engine.Template:Sfn The JUnit Team wants to allow the developer to hook to separate stages of a test life cycle by providing a single unified extension API.Template:Sfn Upon reaching a certain life cycle phase, the Jupiter Engine will invoke all registered extensions for that phase.Template:Sfn The developer can hook into five major extension points:Template:Sfn
- Test lifecycle callbacks – allow developers to execute code at specific test lifecycle phases.Template:Sfn
- Test instance post-processing – enables developers to hook into the test instance creation phase using the
TestInstancePostProcessor
interface.Template:Sfn - Conditional test execution – allows tests to run only if certain conditions are met.Template:Sfn
- Parameter resolution – allows parameters to be injected into test methods or constructors.
- Exception handling – allows developers to modify test behavior in response to exceptions instead of failing the test outright.Template:Sfn
Example of a JUnit test fixture
[edit]A JUnit test fixture is a Java object. Test methods must be annotated by the Template:Code annotation. If the situation requires it,<ref>Template:Cite web</ref> it is also possible to define a method to execute before (or after) each (or all) of the test methods with the Template:Code (or Template:Code) and Template:Code (or Template:Code) annotations.<ref name="JUnit 5 User Guide: Writing Tests">Template:Cite web</ref>Template:Sfn
<syntaxhighlight lang=Java> import org.junit.jupiter.api.*;
class FoobarTests {
@BeforeAll static void setUpClass() throws Exception { // Code executed before the first test method }
@BeforeEach void setUp() throws Exception { // Code executed before each test } @Test void oneThing() { // Code that tests one thing }
@Test void anotherThing() { // Code that tests another thing }
@Test void somethingElse() { // Code that tests something else }
@AfterEach void tearDown() throws Exception { // Code executed after each test } @AfterAll static void tearDownClass() throws Exception { // Code executed after the last test method }
} </syntaxhighlight>
Previous versions of JUnit
[edit]According to Martin Fowler, one of the early adopters of JUnit:<ref>Template:Cite web</ref> Template:Blockquote
As a side effect of its wide use, previous versions of JUnit remain popular, with JUnit 4 having over 100,000 usages by other software components on the Maven Central repository.<ref name="Maven Central">Template:Cite web</ref>
In JUnit 4, the annotations for test execution callbacks were Template:Code, Template:Code, Template:Code, and Template:Code, as opposed to JUnit 5's Template:Code, Template:Code, Template:Code, and Template:Code.<ref name="JUnit 5 User Guide: Writing Tests"/>Template:Sfn
In JUnit 3, test fixtures had to inherit from Template:Code.<ref name="JUnitCookbook">Template:Cite web</ref> Additionally, test methods had to be prefixed with 'test'.<ref name="Migrating from JUnit 3 to JUnit 4: Nothing But Good News">Template:Cite web</ref>
See also
[edit]- xUnit, the family name given to testing frameworks including JUnit
- SUnit, the original Smalltalk version written by Kent Beck based on which JUnit was written
- TestNG, another test framework for Java
- Mock object, a technique used during unit testing
- Mockito, a mocking library to assist in writing tests
- EvoSuite, a tool to automatically generate JUnit tests
- List of Java Frameworks