有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何在JUnit 4中动态创建测试套件?

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

在JUnit 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()方法来计算要运行的测试类

在JUnit4中,documentation表示使用注释:@SuiteClasses({TestClass1.class, TestClass2.class...})来构建我的测试套件。有numerous SO answers展示了如何做到这一点。不幸的是,我看到的示例似乎不允许传递动态生成的TestClass列表

这个SO answer建议我必须将BlockJUnit4ClassRunner子类化,我不想这样做

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


共 (4) 个答案

  1. # 1 楼答案

    下面是一个完整的示例如何实现这一点。它由两个测试用例类和一个套件组成

    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. 示例InstrumentedSuite:

      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;
          }
      }
      

    注意,在testCase类中应该使用@RunWith(JUnit4.class)而不是默认的@RunWith(AndroidJUnit4.class)

  2. # 2 楼答案

    我发现类路径套件与测试类的命名约定一起使用时非常有用

    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 {
    }
    
  3. # 3 楼答案

    要创建动态测试套件,需要使用@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. # 4 楼答案

    public class MyTestCase extends TestCase {
        @Override
        public void runTest() {
            // define assertion here  <===
            assertEquals("yes", "yes");
        }
    }
    
    @RunWith(AllTests.class)
    public class DynamicTestSuite {
        public static TestSuite suite() {
            TestSuite suite = new TestSuite();
    
            // dynamically create your test case here  <====
            suite.addTest(new MyTestCase());
    
            return suite;
        }
    }