Conditionally ignoring tests in JUnit 4

后端 未结 5 1060
醉酒成梦
醉酒成梦 2020-11-22 13:38

OK, so the @Ignore annotation is good for marking that a test case shouldn\'t be run.

However, sometimes I want to ignore a test based on runtime inform

相关标签:
5条回答
  • 2020-11-22 14:17

    Additionally to the answer of @tkruse and @Yishai:
    I do this way to conditionally skip test methods especially for Parameterized tests, if a test method should only run for some test data records.

    public class MyTest {
        // get current test method
        @Rule public TestName testName = new TestName();
        
        @Before
        public void setUp() {
            org.junit.Assume.assumeTrue(new Function<String, Boolean>() {
              @Override
              public Boolean apply(String testMethod) {
                if (testMethod.startsWith("testMyMethod")) {
                  return <some condition>;
                }
                return true;
              }
            }.apply(testName.getMethodName()));
            
            ... continue setup ...
        }
    }
    
    0 讨论(0)
  • 2020-11-22 14:24

    A quick note: Assume.assumeTrue(condition) ignores rest of the steps but passes the test. To fail the test, use org.junit.Assert.fail() inside the conditional statement. Works same like Assume.assumeTrue() but fails the test.

    0 讨论(0)
  • 2020-11-22 14:33

    The JUnit way is to do this at run-time is org.junit.Assume.

     @Before
     public void beforeMethod() {
         org.junit.Assume.assumeTrue(someCondition());
         // rest of setup.
     }
    

    You can do it in a @Before method or in the test itself, but not in an @After method. If you do it in the test itself, your @Before method will get run. You can also do it within @BeforeClass to prevent class initialization.

    An assumption failure causes the test to be ignored.

    Edit: To compare with the @RunIf annotation from junit-ext, their sample code would look like this:

    @Test
    public void calculateTotalSalary() {
        assumeThat(Database.connect(), is(notNull()));
        //test code below.
    }
    

    Not to mention that it is much easier to capture and use the connection from the Database.connect() method this way.

    0 讨论(0)
  • 2020-11-22 14:38

    You should checkout Junit-ext project. They have RunIf annotation that performs conditional tests, like:

    @Test
    @RunIf(DatabaseIsConnected.class)
    public void calculateTotalSalary() {
        //your code there
    }
    
    class DatabaseIsConnected implements Checker {
       public boolean satisify() {
            return Database.connect() != null;
       }
    }
    

    [Code sample taken from their tutorial]

    0 讨论(0)
  • 2020-11-22 14:42

    In JUnit 4, another option for you may be to create an annotation to denote that the test needs to meet your custom criteria, then extend the default runner with your own and using reflection, base your decision on the custom criteria. It may look something like this:

    public class CustomRunner extends BlockJUnit4ClassRunner {
        public CTRunner(Class<?> klass) throws initializationError {
            super(klass);
        }
    
        @Override
        protected boolean isIgnored(FrameworkMethod child) {
            if(shouldIgnore()) {
                return true;
            }
            return super.isIgnored(child);
        }
    
        private boolean shouldIgnore(class) {
            /* some custom criteria */
        }
    }
    
    0 讨论(0)
提交回复
热议问题