Junit: splitting integration test and Unit tests

后端 未结 6 2242
谎友^
谎友^ 2020-12-22 16:05

I\'ve inherited a load of Junit test, but these tests (apart from most not working) are a mixture of actual unit test and integration tests (requiring external systems, db e

6条回答
  •  死守一世寂寞
    2020-12-22 16:47

    You can split them very easily using JUnit categories and Maven.

    This is shown very, very briefly below by splitting unit and integration tests.

    Define A Marker Interface

    The first step in grouping a test using categories is to create a marker interface.

    This interface will be used to mark all of the tests that you want to be run as integration tests.

    public interface IntegrationTest {}
    

    Mark your test classes

    Add the category annotation to the top of your test class. It takes the name of your new interface.

    import org.junit.experimental.categories.Category;
    @Category(IntegrationTest.class)
    public class ExampleIntegrationTest{
      @Test
      public void longRunningServiceTest() throws Exception {
      }
    }
    

    Configure Maven Unit Tests

    The beauty of this solution is that nothing really changes for the unit test side of things.

    We simply add some configuration to the maven surefire plugin to make it to ignore any integration tests.

    
      org.apache.maven.plugins
      maven-surefire-plugin
      2.11
      
       
         org.apache.maven.surefire
         surefire-junit47
         2.12
       
      
      
        
          **/*.class
        
        com.test.annotation.type.IntegrationTest
      
    
    

    When you do a mvn clean test only your unmarked unit tests will run.

    Configure Maven Integration Tests

    Again the configuration for this is very simple.

    To run only the integration tests, use this:

    
      org.apache.maven.plugins
      maven-surefire-plugin
      2.11
      
       
         org.apache.maven.surefire
         surefire-junit47
         2.12
       
      
      
        com.test.annotation.type.IntegrationTest
      
    
    

    If you wrap this in a profile with id IT, you can run only the fast tests using mvn clean install. To run just the integration/slow tests, use mvn clean install -P IT.

    But most often, you will want to run the fast tests by default and all tests with -P IT. If that's the case, then you have to use a trick:

    
        
            IT
            
                
                    
                        org.apache.maven.plugins
                        maven-surefire-plugin
                        
                            java.io.Serializable 
                        
                    
                
            
        
    
    

    As you can see, I'm excluding tests that are annotated with java.io.Serializable. This is necessary because the profile will inherit the default config of the Surefire plugin, so even if you say or , the value com.test.annotation.type.IntegrationTest will be used.

    You also can't use none since it has to be an interface on the classpath (Maven will check this).

    Notes:

    • The dependency to surefire-junit47 is only necessary when Maven doesn't switch to the JUnit 4 runner automatically. Using the groups or excludedGroups element should trigger the switch. See here.
    • Most of the code above was taken from the documentation for the Maven Failsafe plugin. See the section "Using JUnit Categories" on this page.
    • During my tests, I found that this even works when you use @RunWith() annotations to run suites or Spring-based tests.

提交回复
热议问题