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

nlejzf6q  于 2022-12-04  发布在  其他
关注(0)|答案(7)|浏览(188)

我想使用JUnit 4创建一个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()方法处理要运行的测试类。
在JUnit 4中,documentation要求使用注解:@SuiteClasses({TestClass1.class, TestClass2.class...})来构建我的测试套件。有许多SO答案显示了如何做到这一点。不幸的是,我看到的示例似乎不允许传递动态生成的TestClasses列表。
这个SO answer建议我必须子类化BlockJUnit4ClassRunner,而我不想这样做。
动态指定的测试套件看起来一定在JUnit 4的某个地方。有人知道在哪里吗?

nkhmeac6

nkhmeac61#

要创建一个动态测试套件,你需要使用@RunWith注解。有两种常用的方法来使用它:

一个月一个月

这允许您指定哪些类组成所讨论的测试套件。这相当于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;
  }
}
ycl3bljg

ycl3bljg2#

我已经在使用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;
     }
}
h6my8fg2

h6my8fg23#

我发现在测试类上使用命名约定时,Classpath suite非常有用。
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 {
}
lqfhib0f

lqfhib0f4#

我不知道gatherTestClasses()的作用是什么,但是假设它在Linux操作系统上返回一些测试,在Windows操作系统上返回不同的测试。

@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的实现是您的自定义代码。

luaexgnf

luaexgnf5#

下面是一个完整的例子,它结合了两个testCase类和一个suite。
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 {

    }
}

1.示例仪器测试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 {

    }
}

1.示例插入指令的套件:

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),而不是testCase类中的默认@RunWith(AndroidJUnit4.class)

vh0rcniy

vh0rcniy6#

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

juzqafwq7#

扩展@kissLife的答案,这里有一个你可以粘贴和运行的东西,它可以在运行中创建多个测试:

import junit.framework.TestCase;
import junit.framework.TestSuite;

public final class TestJunit4DynamicConstruction {
    public static TestSuite suite() {
        TestSuite suite = new TestSuite();
        suite.addTest(new CompareInts(1, 1));
        suite.addTest(new CompareInts(2, 2));
        suite.addTest(new CompareInts(2, 1)); // huh, for some reason, 2 != 1
        suite.addTest(new CompareInts(1, 1));
        return suite;
    }

    static public class CompareInts extends TestCase {
        private final int got;
        private final int expected;

        CompareInts(int got, int expected) {
            super(Integer.toString(got) + ":" + Integer.toString(expected));
            this.got = got;
            this.expected = expected;
        }
        @Override
        public void runTest() {
            assertEquals(got, expected);
        }
    }
}

您将运行以下测试:

TestJunit4DynamicConstruction$CompareInts.1:1
TestJunit4DynamicConstruction$CompareInts.2:2
TestJunit4DynamicConstruction$CompareInts.2:1
TestJunit4DynamicConstruction$CompareInts.1:1
TestJunit4DynamicConstruction$CompareInts

并得到以下错误:

junit.framework.AssertionFailedError: 
Expected :2
Actual   :1

    ...
TestJunit4DynamicConstruction$CompareInts.runTest(TestJunit4DynamicConstruction.java:26)
   ...

Process finished with exit code 255

相关问题