VOOZH about

URL: https://www.javacodegeeks.com/2017/05/boosting-test-performance-testcontainers.html

⇱ Boosting test performance with TestContainers - Java Code Geeks


In my previous post on testing, I described how to use TestContainers to provide realistic test environments for database tests. This comment revealed the downside:

…as noted above, there always seems to be some drawback. In this case, the overhead of starting the Docker image and everything it contains will increase your overall build time.

As a reminder, here’s the TestContainer-specific code. Note the instance member postgres, and the JUnit Rule that re-initializes it on a per-method basis.

package be.objectify.tcexample.db;

import be.objectify.tcexample.AbstractUserDaoTest;
import be.objectify.tcexample.UserDao;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.testcontainers.containers.PostgreSQLContainer;
import play.db.Database;

public class JooqUserDaoTest extends AbstractUserDaoTest implements DbTestSupport,
 TestData {

 @Rule
 public PostgreSQLContainer postgres = new PostgreSQLContainer();
 
 private Database database;
 
 @Before
 public void setup() throws Exception {
 // the database has all evolutions applied
 database = create(postgres); 
 // load some test data
 loadTestData(database); 
 }

 @After
 public void tearDown() {
 destroy(database);
 }

 @Override
 public UserDao dao() {
 return new JooqUserDao(database);
 }
}

Given that the huge increase in test duration results from Docker container start-up times, we can instead use a JUnit ClassRule to start up one container and re-use it for every test in the class. This means you should no longer run these tests in parallel, but the performance gains massively outweigh test parallelization.

package be.objectify.tcexample.db;

import be.objectify.tcexample.AbstractUserDaoTest;
import be.objectify.tcexample.UserDao;
import org.junit.After;
import org.junit.Before;
import org.junit.ClassRule;
import org.testcontainers.containers.PostgreSQLContainer;
import play.db.Database;

public class FasterJooqUserDaoTest extends AbstractUserDaoTest implements DbTestSupport,
 TestData {

 @ClassRule
 public static PostgreSQLContainer postgres = new PostgreSQLContainer();
 
 private Database database;
 
 @Before
 public void setup() throws Exception {
 database = create(postgres); 
 loadTestData(database); 
 }

 @After
 public void tearDown() {
 destroy(database);
 }

 @Override
 public UserDao dao() {
 return new JooqUserDao(database);
 }
}

The amount of time saved depends on the number of test methods in a class. I have some test classes that have upwards of 30 tests each, and in these cases the execution time drops from minutes to seconds. Not bad for changing a couple of lines of code.

Reference: Boosting test performance with TestContainers from our JCG partner Steve Chaloner at the Objectify blog.
Do you want to know how to develop your skillset to become a Java Rockstar?
Subscribe to our newsletter to start Rocking right now!
To get you started we give you our best selling eBooks for FREE!
1. JPA Mini Book
2. JVM Troubleshooting Guide
3. JUnit Tutorial for Unit Testing
4. Java Annotations Tutorial
5. Java Interview Questions
6. Spring Interview Questions
7. Android UI Design
and many more ....
I agree to the Terms and Privacy Policy

Thank you!

We will contact you soon.

Tags
Testing
πŸ‘ Photo of Steve Chaloner
Steve Chaloner
May 18th, 2017Last Updated: May 18th, 2017
0 137 1 minute read
Subscribe

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Back to top button
Close
wpDiscuz