Jump to content

JUnit

From Wikipedia, the free encyclopedia
JUnit
Developer(s)Kent Beck,Erich Gamma,David Saff, Kris Vasudevan
Stable release
5.10.0 / July 23, 2023;13 months ago(2023-07-23)[1]
Repository
Written inJava
Operating systemCross-platform
TypeUnit testingtool
LicenseEclipse Public License 2.0[2](relicensedpreviously)
Websitejunit.org

JUnitis atest automationframeworkfor theJava programming language.JUnit is often used forunit testing,and is one of thexUnitframeworks.

JUnit is linked as aJARat compile-time. The latest version of the framework, JUnit 5, resides under packageorg.junit.jupiter.[3]Previous versions JUnit 4[3]and JUnit 3 were under packagesorg.junitandjunit.framework,respectively.

A research survey performed in 2013 across 10,000 Java projects hosted on GitHub found that JUnit (in a tie withslf4j-api) was the most commonly included external library. Each library was used by 30.7% of projects.[4]

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:[5]

  1. 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@BeforeAllannotation. The other type is setup before running each test case, which uses the@BeforeEachannotation.[5]
  2. 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@Testannotation is used here.[5]
  3. 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@AfterAllannotation is used to support class-level clean up. The@AfterEachannotation allows for cleanup after test execution.[5]

Integration with other tools

[edit]

JUnit 5 integrates a number of tools, such asbuild tools,integrated development environments(IDE),continuous integration(CI) tools and many more.[6]

Build Tools

[edit]

JUnit supportsApache Ant,Apache MavenandGradlebuild tools, which are the most widely used project build tools.[7]Build tools are vital for automating the process of building the project.[6]

Ant Extension

[edit]

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.[8]Ant centers around thebuild.xmlfile, used for configuring the tasks necessary to run a project.[8]Ant also has an extension calledApache Ivy,which helps deal with dependency resolution. The project dependencies can be declared in theivy.xmlfile. Ant can integrate with JUnit 5 by configuring theJava code coverage tools(JaCoCo), for theivy.xmlfile.[8]Theivy.xmlcan then be configured with thejava-platform-consoleandjunit-platform-runnerdependencies to integrate with JUnit 5.[9]

Maven Extension

[edit]

In contrast to Ant, Apache Maven, also known as Maven, uses a standardized and unified approach to the build process.[10]Maven follows the paradigm of "convention over configuration" for managing its dependencies.[11]The Java source code (or "src" ) can be found under thesrc/main/javadirectory, and the test files can be found under thesrc/test/javadirectory.[11]Maven can be used for any Java Project.[10]It uses theProject Object Model(POM), which is an XML-based approach to configuring the build steps for the project.[10]The minimal Maven with thepom.xmlbuild file must contain a list of dependencies and a unique project identifier.[10]Maven must be available on the build path to work.[10]Maven can integrate with JUnit 5 using thejacoco-maven-pluginpluginwhich supports out-of-box functionality for JUnit 5 tests.[12]Different Maven goals can be specified to achieve these tasks.[12]

Gradle Extension

[edit]

Gradle is a build tool that borrows many concepts from its predecessors, Ant and Maven.[11]It uses thebuild.gradlefile to declare the steps required for the project build.[11]Unlike Ant and Maven, which are XML-based, Gradle requires the use ofApache Groovy,which is a Java-based programming language.[11]Unlike Ant and Maven, Gradle does not require the use of XML.[11]Gradle still adheres to Maven's "convention over configuration" approach, and follows the same structure forsrc/main/javaandsrc/test/javadirectories.[11]Gradle can integrate with JUnit 5 by configuring a pluginjacocoalongside the junit-platform plug-in given by the JUnit 5 team in the build file.[13]

JUnit Extension Model

[edit]

JUnit follows the paradigm of preferring extension points over features.[14]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.[14]

In JUnit 4, there are two extension mechanisms: the Runner API and Rule API.[15]There were some disadvantages to both the Runner API and the Rule API.

A major limitation of the Runner API is that the developer has to implement the entire life cycle even if they only need a specific life cycle stage.[15]This is too complicated and heighweight for the majority of use cases.[15]Another major limitation is that only one runner class is used for each test case, and makes them uncomposable.[15]As an example, Mockito and Parameterized runners cannot exist within the same test class.[15]

A major limitation of the Rule API is that it cannot control the entire life cycle of the test, so they cannot be used for every single use case.[15]They are only appropriate when something needs to occur before or after test case execution.[15]Another major limitation is that rules for class-level and method-level callbacks must be made separately.[15]

In JUnit 5, the extension API is found within the JUnit Jupiter Engine.[16]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.[16]Upon reaching a certain life cycle phase, the Jupiter Engine will invoke all registered extensions for that phase.[16]The developer can hook into five major extension points:[16]

  1. Test life cycle callbacks - This allows the developer to hook to certain phases of a test life cycle[17]
  2. Test instance post-processing - this enables the developer to hook after test instance creation by implementing the TestInstancePostProcessor interface.[18]
  3. Conditional test execution - this enables the developer to execute the test case only after meeting certain criteria.[19]
  4. Parameter resolution - This enables the developer to resolve a parameter after receiving it from a test method or constructor.
  5. Exception handling - A use case for exception handling is to change the testing behavior instead of throwing an exception.[20]

Example of a JUnit test fixture

[edit]

A JUnittest fixtureis a Java object. Test methods must be annotated by the@Testannotation.If the situation requires it,[21]it is also possible to define a method to execute before (or after) each (or all) of the test methods with the@BeforeEach(or@AfterEach) and@BeforeAll(or@AfterAll) annotations.[22][23]

importorg.junit.jupiter.api.*;

classFoobarTests{
@BeforeAll
staticvoidsetUpClass()throwsException{
// Code executed before the first test method
}

@BeforeEach
voidsetUp()throwsException{
// Code executed before each test
}

@Test
voidoneThing(){
// Code that tests one thing
}

@Test
voidanotherThing(){
// Code that tests another thing
}

@Test
voidsomethingElse(){
// Code that tests something else
}

@AfterEach
voidtearDown()throwsException{
// Code executed after each test
}

@AfterAll
staticvoidtearDownClass()throwsException{
// Code executed after the last test method
}
}

Previous versions of JUnit

[edit]

According to Martin Fowler, one of the early adopters of JUnit:[24]

JUnit was born on a flight from Zurich to the 1997 OOPSLA in Atlanta. Kent was flying with Erich Gamma, and what else were two geeks to do on a long flight but program? The first version of JUnit was built there, pair programmed, and done test first (a pleasing form of meta-circular geekery).

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 theMavenCentral repository.[25]

In JUnit 4, the annotations for test execution callbacks were@BeforeClass,@Before,@After,and@AfterClass,as opposed to JUnit 5's@BeforeAll,@BeforeEach,@AfterEach,and@AfterAll.[22][23]

In JUnit 3, test fixtures had to inherit fromjunit.framework.TestCase.[26]Additionally, test methods had to be prefixed with 'test'.[27]

See also

[edit]
  • xUnit,the family name given to testing frameworks includingJUnit
  • SUnit,the original Smalltalk version written byKent Beckbased 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

Citations

[edit]
  1. ^"JUnit Releases".github.Retrieved2023-07-23.
  2. ^"Change license to EPL v2.0".github.7 September 2017.Retrieved2021-02-04.
  3. ^abGulati & Sharma 2017,p. 144, §Chapter 8 Dynamic Tests and Migration from Junit 4.
  4. ^"We Analyzed 30,000 GitHub Projects – Here Are The Top 100 Libraries in Java, JS and Ruby".Archived fromthe originalon 2014-07-09.Retrieved2014-02-09.
  5. ^abcdGulati & Sharma 2017,pp. 37–40, Chapter §2 JUnit LifeCycle API.
  6. ^abGulati & Sharma 2017,p. 99, Chapter §6 Integrating Tools.
  7. ^Gulati & Sharma 2017,pp. 99–117, Chapter §6 Build Tools.
  8. ^abcGulati & Sharma 2017,pp. 108–112, Chapter §6 Integrating Tools - Build Tools - Ant.
  9. ^Gulati & Sharma 2017,pp. 116–117, Chapter §6 Integrating Tools - Build Tools - Ant Extension.
  10. ^abcdeGulati & Sharma 2017,pp. 104–108, Chapter §6 Integrating Tools - Build Tools - Maven.
  11. ^abcdefgGulati & Sharma 2017,pp. 99–103, Chapter §6 Integrating Tools - Build Tools - Gradle.
  12. ^abGulati & Sharma 2017,p. 115, Chapter §6 Integrating Tools - Build Tools - Maven Extension.
  13. ^Gulati & Sharma 2017,pp. 113–114, Chapter §6 Integrating Tools - Build Tools - Gradle Extension.
  14. ^abGulati & Sharma 2017,p. 121, Chapter §7 JUnit 5 Extension Model.
  15. ^abcdefghGulati & Sharma 2017,pp. 121–122, Chapter §7 JUnit 4 Extension Model.
  16. ^abcdGulati & Sharma 2017,pp. 122–124, Chapter §7 JUnit 5 Extension Model - JUnit 5 Extension Model.
  17. ^Gulati & Sharma 2017,pp. 124–126, Chapter §7 JUnit 5 Extension Model - Test Life Cycle Callbacks.
  18. ^Gulati & Sharma 2017,pp. 126–127, Chapter §7 JUnit 5 Extension Model - Test Instance Post-Processing.
  19. ^Gulati & Sharma 2017,p. 127, Chapter §7 JUnit 5 Extension Model - Conditional Test Execution.
  20. ^Gulati & Sharma 2017,p. 129, Chapter §7 JUnit 5 Extension Model - Exception Handling.
  21. ^Kent Beck."Expensive Setup Smell".C2 Wiki.Retrieved2011-11-28.
  22. ^ab"Writing Tests".junit.org.Retrieved2021-02-04.
  23. ^abGulati & Sharma 2017,p. 37-40, Chapter §2 Understanding CoreJunit 5.
  24. ^"bliki: Xunit".martinfowler.Retrieved2022-03-07.
  25. ^"JUnit".mvnrepository.Retrieved29 October2021.
  26. ^Kent Beck;Erich Gamma."JUnit Cookbook".junit.sourceforge.net. Archived fromthe originalon 2020-06-15.Retrieved2011-05-21.
  27. ^Charles A. Sharp (August 2007)."Migrating from JUnit 3 to JUnit 4: Nothing But Good News".Object Computing, Inc.Retrieved2021-02-04.

References

[edit]
[edit]