Re: Side effects between test cases

"Stefan Penndorf [email protected] [junit]" <[email protected]> Fri, 25 Jul 2014 22:56:38 +0200
Newsgroups gmane.comp.java.junit.user
Message-ID <[email protected]>
Hi Tobi,

I think it's really hard to address those things. I agree with Esko that 
those concerns are rare in "every-day" projects.

If you're using timeouts in tests those might not be _unit_ tests but 
_integration_ tests. That said you should consider separating them from 
the "real" unit tests. If you're a maven user you could use failsafe to 
run those. With failsafe you could use multiple JVMs or a JVM per 
test(class) if memory is an issue. I always configure a larger heap for 
integration tests than for unit tests which will reduce the likelyhood 
of OutOfMemoryErrors. I would avoid that but you could trigger garbage 
collection in @Before or @BeforeClass or @After methods.

If you're having long running code you should check 
Thread.isInterrupted() and exit the computation or throw an 
InterruptedException(). This applies to long running test code and will 
also be good practice for long running production code. For example you 
could insert the check between line 40 and 41 of your example [1] and 
throw InterruptedException or return "silently". See also [2] for more 
details.
Nevertheless if I experienced long running production code in the wild 
there was always I/O involved - most I/O operations do throw 
InterruptedExceptions themselfes. And - additionally - if I/O is 
involved those tests are no longer unit tests.

------
But that won't safe you from infinite loops in production code tested by 
real unit tests. If your team executes all unit tests before checking 
in, those infinite loops will only occur once on developer machines and 
should be fixed before checking code in. If there's an infinite loop and 
no timeout configured the developer will see the test causing the 
infinite loop and fix it.


Maybe you could explain further why timing is an issue for you. And 
maybe you can also describe the code and project that causes the issue.

Stefan

[2] Java Concurrency in Practice by Brian Goetz et al.

Am 24.07.2014 22:49, schrieb Tobias Werth [email protected] [junit]:
>
> Hi,
>
> I wanted to discuss two side effects between multiple JUnit test
> methods:
>
> a) timing issues
> If a test method runs into a timeout, the executing thread is
> interrupted (but not stopped). Hence, if it executes an infinite loop,
> it will still occupy some of your resources after this test failed.
>
> For an example, see [1]. The helper method is executed either once or
> infinite often in a loop. If executed once, it runs approx. 100ms on my
> machine. If executed in a loop, JUnit's runtime is approx. 600ms times
> for a single parameterized run.
> Executing 10 infinite loops first and then 10 single helper calls
> results in more than 10 timeouts (which is set to 500ms). You may have
> to increase NUM_RUNS on your machine to reproduce.
>
> b) memory issues
> It's easy to construct cases from the above insight (threads may keep
> running in case of a timeout) with side effects on memory which lead to
> an OutOfMemoryError.
> Even when threads do not keep running, and one test allocates many
> objects, the garbage collector may kick in during the execution of the
> next test method. This may result in an timeout that is not caused by
> the code under test but by the previous massive object allocation.
>
> I know that's almost impossible to stop Java threads. I also assume that
> both side effects are well known.
>
> So what's the best practice to reduce or even avoid these side effects
> when writing JUnit test methods?
>
> Cheers,
> Tobi
>
> --
> 1: https://gist.github.com/meisterT/97db378abea366036f36
>
>