代码之家  ›  专栏  ›  技术社区  ›  Tom Tresansky

如何在JUnit4中动态创建测试套件?

  •  50
  • Tom Tresansky  · 技术社区  · 14 年前

    我想使用JUnit4创建一个JUnit测试套件,其中要包含的测试类的名称在运行测试套件之前是未知的。

    在6月3日,我可以这样做:

    public final class MasterTester extends TestCase
    {
      /**
       * Used by junit to specify what TestCases to run.
       * 
       * @return a suite containing what TestCases to run
       */
      public static TestSuite suite() {
        TestSuite suite = new TestSuite();
    
        for(Class<?> klass : gatherTestClasses()) {
          suite.addTestSuite(klass);
        }
    
        return suite;
      }
    }
    

    gatherTestClasses() 方法处理要运行的测试类。

    在JUnit 4中, documentation 说要使用注释: @SuiteClasses({TestClass1.class, TestClass2.class...}) 建立我的测试套件。有 numerous SO answers 演示如何执行此操作。不幸的是,我看到的示例似乎不允许传递动态生成的测试类列表。

    这个 SO answer 建议我将不得不子类 BlockJUnit4ClassRunner 我不想这样做。

    动态指定的测试套件似乎必须在JUnit4中的某个地方。有人知道在哪里吗?

    5 回复  |  直到 8 年前
        1
  •  26
  •   Alex Kevin Panko    9 年前

    当在我的测试类上使用命名约定时,我发现类路径套件非常有用。

    https://github.com/takari/takari-cpsuite

    下面是一个例子:

    import org.junit.extensions.cpsuite.ClasspathSuite;
    import org.junit.runner.RunWith;
    
    @RunWith(ClasspathSuite.class)
    @ClassnameFilters({".*UnitTest"})
    public class MySuite {
    }
    
        2
  •  36
  •   Andrejs    12 年前

    我用JUnit 4.8尝试过这个方法,它很有效:

    @RunWith(AllTests.class)
    public class SomeTests
    {
        public static TestSuite suite()
        {
            TestSuite suite = new TestSuite();
    
            suite.addTest(new JUnit4TestAdapter(Test1.class));
            suite.addTest(new JUnit4TestAdapter(Test2.class));
    
            return suite;
         }
    }
    
        3
  •  34
  •   Don Kirkby    11 年前

    要创建动态测试套件,需要使用 @RunWith 注释。使用它有两种常见方法:

    @RunWith(Suite.class)

    这允许您指定哪些类组成了有问题的测试套件。这相当于JUnit 3样式:

    import junit.framework.TestSuite;
    import junit.framework.TestCase;
    
    public final class MasterTester extends TestCase {
    
      public static TestSuite suite() {
        TestSuite suite = new TestSuite();
        suite.addTestSuite(TestClass1.class);        
        suite.addTestSuite(TestClass2.class);
        // etc...
        return suite;
      }
    }
    

    等效的JUnit 4类将是:

    import org.junit.runners.Suite;
    
    @RunWith(Suite.class)
    @SuiteClasses({TestClass1.class, TestClass2.class})
    public final class MasterTester {
    
    }
    

    @RunWith(AllTests.class)

    这允许您动态地指定组成测试套件的测试。如果测试直到运行时才知道,则不能在注释中指定它们。你可以用这个结构代替。因此,如果JUnit 3代码是:

    import junit.framework.TestCase;
    import junit.framework.TestSuite;
    import junit.framework.Test;
    
    public final class MasterTester extends TestCase {
    
      public static TestSuite suite() {
        TestSuite suite = new TestSuite();
        for (Test test : findAllTestCasesRuntime()) {
          suite.addTest(test);
        }
        return suite;
      }
    }
    

    等效的JUnit 4代码为:

    import org.junit.runners.AllTests;
    import junit.framework.TestSuite;
    import junit.framework.Test;
    
    @RunWith(AllTests.class)
    public final class MasterTester {
    
      public static TestSuite suite() {
        TestSuite suite = new TestSuite();
        for (Test test : findAllTestCasesRuntime()) {
          suite.addTest(test);
        }
        return suite;
      }
    }
    
        4
  •  6
  •   Brad Cupit Regan    12 年前

    我不确定GatherTestClasses()的功能,但假设它在操作系统是Linux时返回一些测试,在操作系统是Windows时返回不同的测试。您可以在Junit 4.4中使用 assumptions :

    @Test
    public void onlyOnLinux() {
        assumeThat(getOS(), is(OperatingSystem.LINUX));
        // rest of test
    }
    
    @Test
    public void onlyOnWindows() {
        assumeThat(getOS(), is(OperatingSystem.WINDOWS));
        // rest of test
    }
    
    @Test
    public void anyOperatingSystem() {
        // just don't call assumeThat(..)
    }
    

    实施 getOS() OperatingSystem 作为您的自定义代码。

        5
  •  0
  •   Maher Abuthraa    8 年前

    下面是一个完整的例子,如何实现它。它结合了两个测试用例类和一个套件。

    1. 仪器测试示例:

      import android.support.test.rule.ActivityTestRule;
      
      import org.junit.Rule;
      import org.junit.Test;
      import org.junit.runner.RunWith;
      import org.junit.runners.JUnit4;
      
      @RunWith(JUnit4.class)
      public class ExampleInstrumentedTest {
      
      
          @Rule
          public ActivityTestRule<MainActivity> mActivityTestRule = new ActivityTestRule<>(MainActivity.class);
      
          @Test
          public void checkInputs() throws Exception {
      
          }
      }
      
    2. 示例仪器测试2:

      import android.support.test.rule.ActivityTestRule;
      
      import org.junit.Rule;
      import org.junit.Test;
      import org.junit.runner.RunWith;
      import org.junit.runners.JUnit4;
      
      @RunWith(JUnit4.class)
      public class ExampleInstrumentedTest2 {
      
      
          @Rule
          public ActivityTestRule<MainActivity> mActivityTestRule = new ActivityTestRule<>(MainActivity.class);
      
          @Test
          public void checkInputs() throws Exception {
      
          }
      }
      
    3. 仪器套件示例:

      import junit.framework.TestSuite;
      
      import org.junit.runner.RunWith;
      import org.junit.runners.AllTests;
      
      @RunWith(AllTests.class)
      public class ExampleInstrumentedSuite {
      
          public static TestSuite suite() {
              TestSuite suite = new TestSuite();
              suite.addTest(new junit.framework.JUnit4TestAdapter(ExampleInstrumentedTest.class));
              suite.addTest(new junit.framework.JUnit4TestAdapter(ExampleInstrumentedTest2.class));
              return suite;
          }
      }
      

    注意你应该使用 @RunWith(JUnit4.class) 而不是违约 @RunWith(AndroidJUnit4.class) 在测试用例类中