5

I'm writing to try and initiate a bit of a discussion regarding Spring Unit testing and in particular Transactional unit tests.

We currently have around 441 tests in a variety of classes annotated like so:

@RunWith(SpringJUnit4ClassRunner.class)
@TransactionConfiguration
@ContextConfiguration(locations={"/context/ServiceTest-context.xml"}, inheritLocations=false)
public class ServiceTests extends AbstractTransactionalJUnit4SpringContextTests {

    @Test
    public void testSomething() {}

    @Test
    public void testSomethingElse() {}
}

Each of our tests classes have their own test context.

We're facing an issue in which when we run individual test classes or individual packages the tests run fine.

However when we want to scale that up to run ALL our tests (currently > 400) by using maven or something similar such as Hudson integration.

mvn test

We get to a point and then start to experience Java GC Limit exceeded errors.

Now I get the feeling that this is down to our test plan design rather than the need for us to up any memory limits or turn off the warnings.

Can anyone share their experiences and the way they solved a similar problem?

Eggsy

skaffman
  • 398,947
  • 96
  • 818
  • 769
eggsy84
  • 1,059
  • 1
  • 14
  • 26
  • Do you share the test context between the individual tests and use a specific forkmode configuration ? see http://maven.apache.org/plugins/maven-surefire-plugin/test-mojo.html#forkMode – Michael Pralow Jul 09 '11 at 21:40
  • The test contexts are shared between individual tests however they're aren't shared between individual test classes/suites. We generally have a test class that uses one context and then there a multiple tests within that class which use the same context. Does that make sense? We don't use a specific forkmode config - what does that do? (Having never used that Maven option) – eggsy84 Jul 11 '11 at 10:51
  • Useful link for anyone looking for forkMode info (http://maven.apache.org/plugins/maven-surefire-plugin/examples/class-loading.html) – eggsy84 Jul 11 '11 at 10:54
  • did you check some existing questions for "Java GC Limit exceeded" like http://stackoverflow.com/questions/1393486/what-does-the-error-message-java-lang-outofmemoryerror-gc-overhead-limit-exceed ? basically it boils down to too much (temporary) objects – Michael Pralow Jul 12 '11 at 22:31
  • Hi there, I did but my question was more intended as a general design discussion in the context of Spring unit testing rather than specifics. I have a hunch it is the different contexts we use holding onto beans which is consuming all the memory hence the nature of the question. – eggsy84 Jul 12 '11 at 23:11
  • i am still not sure if it is a spring only problem, you talk about 441 tests, how much spring beans has a context ? 100 ? 500 ? are we talking about singletons (500 would be a lot) ? do you create 1000s of prototype beans ? - could be one cause for the gc limit error, do you have 1000s of jpa objects - maybe with many 1:n relations, and huge lists for each object ? – Michael Pralow Jul 13 '11 at 07:15
  • Did you take a look at this thread: http://stackoverflow.com/questions/3655944/is-it-really-necessary-to-nullify-objects-in-junit-teardown-methods? That thread notes a distinct difference in object lifecycles between Junit versions 3 and 4. – atrain Aug 14 '11 at 14:32
  • No but I shall take a look at it now and see if any of the difference affect our memory usage. Thank you. – eggsy84 Aug 15 '11 at 08:11
  • In my opinion this can be a super interesting question, especially if its focused on **discussing guidelines about unit testing design for Spring applications**. – Vladimir Tsvetkov Sep 12 '11 at 11:53
  • Have you considered forking Java for each test in the Maven config? – Behrang Sep 25 '11 at 03:05
  • Hi there, can you explain by what you mean by forking java? Yes this question was more intended as a discussion about the best way to design tests rather than my specific problem. – eggsy84 Oct 04 '11 at 11:41

1 Answers1

1

I'm pretty sure that the container will hold on to all the contexts for the duration of the its lifecycle unless you explicitly call appCtx.close()

Is there some particular reason that every test has its own context? Because unless you have a special reason for doing that....I'd say, don't do that. As long as you have appropriate setup and teardown methods, you should be able to share. Even if you group similar tests together and have just those share contexts. More info please!

nont
  • 9,322
  • 7
  • 62
  • 82