15

I'm looking for some validation as to how Assume.assumeTrue() works in JUnit. I'd like to use it in a @BeforeClass method so that I can avoid running my test suite if a condition isn't met.

However, I was wondering as to the nature of the method. If assumeTrue receives a parameter with a false value, does it skip the rest of the method (that's annotated with @BeforeClass) or does it execute the rest of the remaining instructions.

I'm also curious of any other implications it might have for methods annotated with:

@After

@Before

@AfterClass

Edit:

After running it through a pretty basic test, if assumeTrue(false) is ever run, then the rest of the method will be ignored as well as any methods annotated with @Test @After or @Before.

To me it was a little surprising that the rest of the method was skipped as well as the fact that it also ignored @Before and @After in addition to @Test if assumeTrue is placed in the @BeforeClass method. The documentation doesn't specify that sort of behavior (which I checked before asking the question).

Edit2: Using assumeTrue() in a @BeforeClass method is very plausible, as there may be environmental variables (i.e. your build/test machine is stressed for resources) that you may want to check before running your test suite. This can help avoid getting test failures (like timeouts) caused by a slow system.

The test I ran it through looked like this

@BeforeClass
public static void beforeClassMethod()
{
  System.out.println("BeforeClass assume");
  Assume.assumeTrue(false);
  System.out.println("AfterClass assume");
}
@Before
public void beforeMethod()
{
  System.out.println("Before");
}
@Test
public void testMethod()
{
  System.out.println("Test");
}
@After
public void afterMethod()
{
  System.out.println("After");
}
@AfterClass
public static void afterClassMethod()
{
  System.out.println("AfterClass");
}


Output:

BeforeClass assume
AfterClass
E_net4
  • 27,810
  • 13
  • 101
  • 139

1 Answers1

2

@Before, @BeforeClass annotated methods are setUp methods i.e methods you use to configure mock behaviour that will be used by your test methods. This is not used for running any test cases. Same is the case with @After and @AfterClass, it should be used to annotate tear down methods and should not contain any tests.

Now, you should use Assume.assumeTrue() in your test methods(@Test annotation). Yes, assumeTrue(), if called with an expression evaluating to false, the test will halt and be ignored. Check docs for more info.

P.S - This might not be the answer, but it is to help her go in the right direction.

EDIT -

    To me it was a little surprising that the rest of the method was skipped as 
well as the fact that it also ignored @Before and @After in addition to @Test if
 assumeTrue is placed in the @BeforeClass method. The documentation doesn't 
specify that sort of behavior (which I checked before asking the question).

To answer this question, its not at all surprising. @BeforeClass is the first method to run while setting up your test case. Its a static setUp method thats called once to perform setUp for all your test cases. So if you use assumeTrue() here and it returns false, it throws an assumptionViolationException and halts everything else that's gonna happen. Thus nothing works for you. Makes sense?

Pratik
  • 1,122
  • 8
  • 26
  • It's not used for running test cases. `AssumeTrue` is being used in the `@BeforeClass` method to check a condition _before_ running the test suite. There are times when you don't want to run your test cases if some condition isn't met –  May 07 '15 at 22:36
  • @sreya so you mean to say all your test cases are not run if your condition fails ? I'm not sure if thats what assumeTrue was intended for. – Pratik May 07 '15 at 22:48
  • Precisely. It seems to me that is would be a good use for it. If I have a suite of tests that are timing-dependent and thus would fail under a slow machine (i.e. one that is strained on CPU/memory) then it would make sense not to run the suite. This seems to be in line with the documentation: `A set of methods useful for stating assumptions about the conditions in which a test is meaningful. A failed assumption does not mean the code is broken, but that the test provides no useful information` –  May 07 '15 at 23:30
  • in response to your Edit, perhaps it's not surprising, it makes sense, but it's not obvious (having never used it before) that `@AfterClass` still gets run if `assumeTrue(false)` is executed. It makes sense, but the whole point of the question was to validate it's behavior –  May 07 '15 at 23:33
  • A set of methods useful for stating assumptions about the conditions in which a test is meaningful. A failed assumption does not mean the code is broken, but that the test provides no useful information. TEST IS MEANINGFUL(Not intended for setUps and TearDowns). – Pratik May 08 '15 at 08:16
  • But this can be used as you are using it and the behavior is valid. I actually never thought of it. So it was great having this discussion :) – Pratik May 08 '15 at 08:17