BreadcrumbHomeResourcesBlog How To Use Java Integration Testing June 7, 2023 How to Use Java Integration TestingJava TestingJava Application DevelopmentBy Bleston WrightUnit testing can be used to mock all the dependencies of a single Java class in order to isolate it from the rest of the system. This way the class under test is in a controlled environment where you can test its own business logic with nothing else in the way. There are times, however, when you should not use mocking during testing. For these cases, you need Java integration testing. Read on to learn: Table of ContentsWhat is a Java Integration Test?Java Integration Testing Best PracticesJava Integration Testing FrameworksFinal ThoughtsTable of Contents1 - What is a Java Integration Test?2 - Java Integration Testing Best Practices3 - Java Integration Testing Frameworks4 - Final ThoughtsBack to topWhat is a Java Integration Test?While there is no hard and fast definition, a Java integration test generally:Uses the databaseUses the networkUses an external system (e.g., a queue or a mail server)Reads/writes files or performs other I/OSometimes, there isn’t a clear distinction between an integration test and a unit test. A basic rule of thumb is that a Java integration test meets the following criteria:A test uses the databaseA test uses the networkUses an external system (e.g. a queue or a mail server)Reads/writes files or performs other I/OUnit Test vs. Integration TestThe chart below breaks down the differences between Java unit tests versus Java integration tests.Java Unit TestJava Integration TestResults depends only on Java codeResults also depends on external systemsEasy to write and verifySetup of integration test might be complicatedA single class/unit is tested in isolationOne or more components are testedAll dependencies are mocked if neededNo mocking is used (or only unrelated components are mocked)Test verifies only implementation of codeTest verifies implementation of individual components and their interconnection behaviour when they are used togetherA unit test uses only JUnit/TestNG and a mocking frameworkAn integration test can use real containers and real DBs as well as special java integration testing frameworks (e.g. Arquillian or DbUnit)Mostly used by developersIntegration tests are also useful to QA, DevOps, Help DeskA failed unit test is always a regression (if the business has not changed)A failed integration test can also mean that the code is still correct but the environment has changedUnit tests in an Enterprise application should last about 5 minutesIntegration tests in an Enterprise application can last for hoursWhen to Use Java Integration TestingJava integration testing should be used when you are interested in the interface of this class with its dependencies. By doing so, you zoom out from a single class to testing a component of the system. This is appropriate if the system is built on multiple classes or uses other systems, e.g., a database or a queue.Back to topJava Integration Testing Best PracticesWhile there may not be a hard-and-fast definition for what comprises a Java integration test, there are best practices for implementing them and what to do if and when they fail. 1. Use Detailed LoggingThe use of detailed logging must be accounted for when conducting Java integration tests. When a unit test fails it is very easy to understand why since the scope is very narrow. When an integration test fails it’s often not so simple. Because an integration test by definition is based on many components and a specific data flow, identifying the failure cause is not always straightforward. Using detailed logging statements can help alleviate this problem. They’re always needed in an Enterprise application regardless of unit tests. This way, when an integration test fails you can examine the logs and understand if the issue is in the code or in an external resource used by the test.2. Don't Use Java Integration Testing and Java Unit Testing ConcurrentlyThis is the most important aspect of unit tests. In a large enterprise application, integration and unit tests must be handled differently. Here’s an all-too-common scenario: New developers simply declare that “writing unit tests is a waste of time.” They’re right from their point of view, since nobody wants to work with a broken test suite, but this is a situation that needs to be avoided. 3. Split Unit and Integration TestsThere are many ways to split unit and integration tests, including using the Maven failsafe plugin. Unit tests should follow the naming convention introduced in the first part of this series. Unit test classes are named with “name of class + Test”. Then they are placed in the test directory of the Maven project structure. The unit tests are executed automatically when the test goal is run. Next you should add the failsafe plugin in your pom.xml file. … … org.apache.maven.plugins maven-failsafe-plugin 2.13 integration-test integration-test verify verify Your integration tests have a different naming convention, however. They are named as “name of class + IT”. IT stands for Integration Test. Now the test goal will ignore them. Instead these tests will be executed by the integration-test goal which is a built-in goal into Maven. Below is a table that summarizes this split. Unit testsIntegration TestsLocated inMaven test directoryMaven test directoryNaming conventionname of class + Testname of class + ITExample class nameBasketWeightTest.javaInvoicingProcessorIT.javaManaged byMaven surefire pluginMaven failsafe pluginExecuted in test goalYesNoExecuted in integration-test goalNoYesHow to Run Java Integration Tests in Your Build ProcessNow that all these changes are done, you have great flexibility on how you run unit tests. Most importantly, your build server (e.g. Jenkins) should contain a mixture of jobs that deal with both kinds of tests. Here is a overview of suggested jobs.Job typeScheduleDescriptionTestsMain buildEvery 15 minutes or half hour.Only compiles and runs unit tests. Should finish in 15-20 minutes maxOnly unit testsIntegration buildEvery 24 hours (usually at night)Runs integrations tests. Can run for 2-3 hoursAll testsQA buildManuallyDeploys to a QA environmentAll testsThe suggested workflow is the following:Developers run the test goal during developmentDevelopers run the test goal before any commitDevelopers run the integration-test goal before a major commit with many side effectsBuild server compiles code and runs the test goal every 15-30 minutes (main build)Build server compiles code and runs the integration-test goal every day (integration build)Build server compiles code and runs the integration-test goal before a release to QAWith this workflow it is clear that developers get fast feedback from the unit tests so anything that breaks can be fixed immediately. The boring process of running integration tests is left to the build server which runs them automatically in a well defined schedule.Back to topJava Integration Testing FrameworksAs we mentioned at the beginning of the article, developers often utilize a Java integration testing framework. A few of the more popular Java integration testing frameworks include Arquillian, DbUnit, and JUnitArquillian - a Java integration testing framework specific to Java EEDbUnit - as the name implies, DbUnit can run both unit and integration testsJUnit - while most use JUnit for unit testing, many use JUnit for integration testingCurious about what your Java development peers are using in their Java development environments? Find out in the 2024 Java Developer Productivity Report. Download NowBack to topFinal ThoughtsImplementing Java integration testing can save your organization development time. Compound those time efficiency savings by eliminating rebuilds and redeploys with JRebel and save upwards of a month of development time annually. Discover how much Java development time you could save during your 14-day free trial of JRebel. Try FreeThis blog post was originally published in April 2013 and has been edited for clarity and relevancy. Back to top
Bleston Wright Senior Sales Engineer, Perforce Software Bleston Wright is a Sales Engineer at Perforce, and is passionate about helping software development teams to increase output while working more efficiently.