How do you speed up java unit tests?

17,089

Solution 1

The same way you'd speed up any other code. Find out which tests take the most time, and see how they can be optimized.

There are plenty of operations that can be slow, and if you do them 3000 times, it adds up. Sometimes, reusing data between tests is worthwhile (even if you're not supposed to do that in unit tests, it may be necessary if that's what it takes to get your tests to run at an acceptable speed).

Time your tests. Usually, 90% of them will execute almost instantly, and the last 10% will take almost all the time. Find those 10% and see what they're doing.

Run the code through a profiler, and note where the time is being spent. Guessing is a waste of time. What you think the test runner is doing is meaningless. Instead of guessing, find out what it is doing. Then you'll know how to speed it up.

Solution 2

Some ideas:

  • Use a mocking framework to avoid hitting databases (or making web service calls, etc).
  • If you're doing the same or similar set up for lots of individual tests, try doing it in a test fixture setup (i.e. something that gets done once per fixture rather than once per test).
  • I believe some test frameworks allow you to run tests in parallel

Solution 3

You may want to split your unit tests into suites. Is your application modularized? How often do you really need to run all the tests? Would it be acceptable if your developers only ran the unit tests relevant to their own module, and you had the array of tests run nightly and/or on a CI?

Are there any particular unit tests which are very complex (I know, I'm slipping into functional and integration testing here, but the line is sometimes fuzzy), but can any of them be run on a sanity-level during development and then be run full out on the CI?

Edit: Just for kicks, I'll briefly describe the test routines at one of my previous projects

First of all, the growth of the test system was organic, meaning that it was not originally planned out but was modified and changed as it grew. Hence it wasn't perfect, and there were some naming conventions that had become apocryphal with time.

  • At a developer level we used a simple two minute test suite called CheckIn, which verified that the code was healthy enough to join the trunk.
  • On top of that we ran sanity tests continuously on a CI machine. These were simplified versions of the more complex integration and functional tests, all unit tests and all regression tests.
  • Complex test suites (in the number of hours) were run during day and night remotely and the results compiled the next morning.

Automatic testing - it's the mutt's nuts.

Solution 4

To Start with :
a) Get the stats about running time of your Junit Tests.You may already be caputring that informaion in your test reports.
b) Take out top 10 test classes (in time taken) and try to reduce the time .This you need to do on ongoing basis.
c) Try to reduce the running time by refactoring or even changing the approach of testing.
One such case i came across is in one Test class for CRUD test cases.Update test case was first creating the funtionlaity and then updateing .But we were already tested create in seprate test case.So in these cases you can chain your test cases like

@Test()
    public void testCreate() throws Exception
    {}
    @Test(dependsOnMethods = "testCreate")
    public void testAmend() throws Exception
    {}
    @Test(dependsOnMethods = "testAmend")
    public void testDelete() throws Exception
    {} 

So you save on doing dupicate testing.

d)One more instance where i was able to reduce time significalntly was. We had a system (inherietd )where each test case was calling SetUp(Strating Spring Server etc) and after running shut down system resources.This was very time consuming ,so i refactored it to start coomon resources before test suit and after entire suite is done then close those.

e) Depending on your project their can be other bottlenecks you may need to iron out.

How to manage Build time in TDD

Solution 5

Are you using fork="yes" in your junit call? If so, make sure you set forkMode="once", otherwise the junit task will start a new VM for each TestCase class. With 3000 unit tests, that will make a dramatic difference.

http://ant.apache.org/manual/Tasks/junit.html

Share:
17,089
James Geng
Author by

James Geng

Updated on June 13, 2022

Comments

  • James Geng
    James Geng almost 2 years

    Currently our project has over 3000 unit tests, and "ant testAll" takes well over 20 minutes. besides getting better hardware, are there ways to speed things up?