Raystorm
Raystorm

Reputation: 6538

Can I Skip Junit Tests if other tests fail?

I'm using Junit to run tests with Seleniun WebDriver. I'm trying to split up my tests into function area for better error reporting. I've created tests to test Page load/moving documents to other workflows. If a page load test fails, or a workflow move fails I want to skip the subsequent page/workflow tests.

if a Test A fails how can I skip either the rest of the tests in the class or running tests in Class B?

NOTE: I realize what I'm asking is "bad Practice* for UNIT TESTS. However, I'm actually using Junit for Integration and/or Automation Testing. (Depending on your definition.) I've already found @Suite.SuiteClasses, and @FixMethodOrder to order my test classes and test methods. I'm trying to order them to run logically, testing the page load, first, then each feature of the page as a seperate test. Some of the features, move the information to other pages, meanining other classes. 1 of my classes can take over 1/2 hour to finish. If the pre-req tests fail, I'd like to short circuite the "Dependent" tests, in order to get my results/report sooner.

Upvotes: 3

Views: 5565

Answers (3)

Code Eyez
Code Eyez

Reputation: 425

By using Junit's Assumewithin the @Before or @Test methods, you can skip the current test by using either

  1. Assume#assumeTrue(boolean) for any depended tests that failed. You can skip the current test by calling Assume.assumeTrue(false)
  2. Assume#assumeNoException(Throwable) for skippable tests and skip the current test by passing the AssumptionVoilated exception when the other test was skipped.

Here's an example:

public class Tests{
    @Test
    public void test1(){
        ...
    }

    @Test
    public void test2(){
        try{
            test1();
        }catch(AssertionError failExcep){
            //test1 failed, skip this test
            Assume.assumeTrue(false);
        }catch(AssumptionVoilationException skipExcep){
            //test1 was skipped, skip this test
            Assume.assumeNoException(skipExcep);
        }
        ...
    }
}

This particular example would run test1() twice, but by adding @FixMethodOrder and catching the any error thrown during test1 to be referenced in test2; we could circumvent that issue.

Also this example does not cover any other exception type that test1() could throw, e.g. NullPointerException. Editing the AssumptionVoilationException catch clause to Exception will allow test2 to be skipped on any exception. If you also want to catch Error or Throwable just add a catch clause and put in Assume.assumeTrue(false) like AssertionError. Or you could just throw AssumptionViolatedException

Here's the dummy proof version

@FixMethodOrder
public class Tests{

    private Optional<Throwable> testOneThrown;

    @Test
    public void test1(){
        try{
            ...
        }catch(Throwable t){
            // test1 throw something, catching it for test2() reference
            testOneThrown = Optional.of(t);
            /*
             * still throwing it for junit normal functions and
             * in case test2 ran independently
             */
            throw t;
        }
        //Ran successfully, making reference non-null but empty
        testOneThrown = Optional.empty();
    }

    @Test
    public void test2(){
        try{
            if(testOneThrown == null){
                // test1 did not run, thus needs to run
                test1();
            }else if(testOneThrown.isPresent()){
                // test1 ran and threw something
                throw testOneThrown.get();
            }
            //test1 ran and throw nothing
        }catch(Throwable thrown){
            /*
             * something was throw in test1, test1 could have
             * failed, could have been skipped, etc. thus skip 
             * this test.
             */
            throw new AssumptionViolatedException("Dependency on test1 failed.", thrown);
        }
        ...
    }
}

Upvotes: 3

Gavin
Gavin

Reputation: 1767

You could try manipulating the tests via the Rules interface, they have an example here: http://www.codeaffine.com/2013/11/18/a-junit-rule-to-conditionally-ignore-tests/

That might be a good starting point.

Upvotes: 0

Bart Wojtala
Bart Wojtala

Reputation: 1320

I suggest you switching to TestNG. Check this out.

Btw:When I used to work with Java - almost one year ago - I didn't find such a solution for JUnit.

Upvotes: 0

Related Questions