junit4 icon indicating copy to clipboard operation
junit4 copied to clipboard

RunWith(Enclosed.class) should run tests in outer class

Open christophsturm opened this issue 11 years ago • 15 comments

in this example:

@RunWith(Enclosed.class)
public class OuterClassTest  {
    @Before
    public void startStore() throws Exception {
...
    }

    @Test
    public void outerTest1() {
...
    }

    public static class PoolTest extends JedisPoolTestBase {
        private StatisticsStore storer;

        @Before
        public void setupStorer() {
        }


         @Test
         public void innerTest1() {
          ...  
         }
    }
}

only innerTest1 runs. It would be more useful if outerTest1 was also run. also @Before classes in the outer class should run for tests in the inner class. thats how nested tests work in other languages. is this easily possible?

christophsturm avatar Mar 25 '13 22:03 christophsturm

It's possible, but complicates the meaning of the runner for what feels like little benefit.

dsaff avatar Mar 26 '13 17:03 dsaff

I agree that running tests in the enclosing class is a bit out-of-scope for the intention of the enclosed runner, but I do feel that the enclosed runner should be enhanced to run other fixtures from the enclosing class. For example, I have a set of test classes that all rely on applications deployed to a remote system. I use a @BeforeClass in the enclosing class to deploy the applications, and a @AfterClass to undeploy the applications, but I would like for these fixtures to be run only once for the duration of the enclosed test classes.

brandonheck avatar Apr 12 '13 14:04 brandonheck

@brandonheck, that should already work. Have you tried?

dsaff avatar Apr 12 '13 22:04 dsaff

I'm not sure what I am doing wrong in my actual tests, but I distilled my case into a simple case and it seems to work for everything except @Before and @After, though based on the comment to the OP I would guess that it is not intended to work with the @Before and @After fixtures.

Just in case it is, here's a test case for those (Junit 4.11, ran with the Eclipse Junit Runner and Maven/Surefire):

@RunWith(Enclosed.class) public final class EnclosedTest { public static String sharedStringBefore; public static String sharedStringAfter;

@Before
public void before() {
    sharedStringBefore = "abcdef";
}

@After
public void after() {
    sharedStringAfter = "ghijk";
}

public static class EnclosedClass1 {
    @Test
    public void testEnclosed() {
        assertNotNull("The string is null.", sharedStringBefore);
    }
}

public static class EnclosedClass2 {
    @Test
    public void testEnclosed() {
        assertNotNull("The string is null.", sharedStringAfter);
    }
}

}

brandonheck avatar Apr 15 '13 14:04 brandonheck

Sorry to be confusing. Did you try it with @BeforeClass and @AfterClass?

dsaff avatar Apr 15 '13 18:04 dsaff

Yeah, sorry I'm also kind of jumping around. @BeforeClass and @AfterClass work, but it would be nice to have @Before and @After work as well.

brandonheck avatar Apr 15 '13 21:04 brandonheck

@brandonheck, what would you expect @Before and @After to do?

dsaff avatar Apr 16 '13 14:04 dsaff

I would expect a @Before or @After method in the enclosing class to function as if it were in every enclosed class, the would be run before/after each test in all of the enclosed classes.

brandonheck avatar Apr 16 '13 19:04 brandonheck

@brandonheck,

In general, I hope that developers can use Rules to share before/after behavior between multiple classes, whether they're bound together by Enclosed, or not.

dsaff avatar Apr 16 '13 20:04 dsaff

@brandonheck did you get to run testcases that are defined in enclosing class ( in @christophsturm's example outerTest1)? Actually I am also searching for the same but didn't find any help. If something worked for you then can you tell me what you did?

VishvendraRana avatar Feb 18 '15 05:02 VishvendraRana

Have you tried using HierarchicalContextRunner by @bechte?

marcphilipp avatar Feb 18 '15 06:02 marcphilipp

Thanks @marcphilipp. It works good. But as this is a third party runner. So we have to add patch for this. Is there not any other solution?

VishvendraRana avatar Feb 19 '15 06:02 VishvendraRana

@VishvendraRana There is a hack that works. Basically you need to make your "outer" @Before and @After part of a inner class with a dummy test. Then your other contexts need to extends that class. The only place I've seen this explained is in Uncle Bob's clean coders episode #20 (https://cleancoders.com/episode/clean-code-episode-20/view). Pay the couple of bucks and check out the video at about 1:02.

I had a lot of hope for HierarchicalContextRunner, but in my limited testing I found that it didn't play well with categories.

Citizen-T avatar Aug 06 '15 02:08 Citizen-T

@Citizen-T: If you experience issues with the use of Categories and the HierarchicalContextRunner, please file an issue on GitHub and I will fix it. It really should not be an unsolvable issue. Please provide some more information so I can solve the limitations. Thanks. :-)

@VishvendraRana: The HierarchicalContextRunner serves your needs. You can simply add the runners jar to your test-classpath. In order to add tests, you also modify code, so there should be a need for a patch either way, shouldn't it? There are no limitations in use of this library, just like JUnit itself.

bechte avatar Aug 06 '15 05:08 bechte

I had the same issue and circumvented it by using net.avh4.test.junit.Nested instead of org.junit.experimental.runners.Enclosed. Just consider that, unlike Nested may suggest, "nested" classes are actually to be declared as "inner", i.e. not static.

AndreaBaroncelli avatar Mar 09 '17 10:03 AndreaBaroncelli