| 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
>
>