Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在调用@Before setup()之后,如何以反射方式访问要运行的测试方法?_Java_Junit - Fatal编程技术网

Java 在调用@Before setup()之后,如何以反射方式访问要运行的测试方法?

Java 在调用@Before setup()之后,如何以反射方式访问要运行的测试方法?,java,junit,Java,Junit,我们有很多selenium测试通过junit运行,它们都有一些步骤需要在实际测试之前运行。为此,我们有一个父TestCase类,其中有一些@Before和@After方法 现在,由于我们网站的一个新功能,我想对这个设置的一部分进行参数化,我想创建一个新的注释来进行一些测试,以向setup()方法表明设置略有不同,同时允许其他人使用默认设置。那么,是否有可能以反射方式访问将在@Before方法中运行的测试方法 例如 我建议对这两种方法使用不同的测试类 class MyTestCase {

我们有很多selenium测试通过junit运行,它们都有一些步骤需要在实际测试之前运行。为此,我们有一个父TestCase类,其中有一些@Before和@After方法

现在,由于我们网站的一个新功能,我想对这个设置的一部分进行参数化,我想创建一个新的注释来进行一些测试,以向setup()方法表明设置略有不同,同时允许其他人使用默认设置。那么,是否有可能以反射方式访问将在@Before方法中运行的测试方法

例如


我建议对这两种方法使用不同的测试类

class MyTestCase {

    @Before
    public void setUp() {
        /* Default setup */
    }

    public void testHomepage() {
        // test some stuff
    }

}

class MyRedTestCase extends MyTestCase {

    @Before
    public void setUp() {
        super.setUp();
        /* Red setup */
    }

}
然后您可以将您的测试放在两个不同的类中,分别从MyTestCase和MyRedTestCase扩展而来

class BlueTest extends MyTestCase {

    @Test
    public void testBlueFlavouredHomepage() {  // assuming Blue is my default flavour
        testHomepage();
    } 

}

class RedTest extends MyRedTestCase {

    @Test
    public void testRedFlavouredHomepage() {
        testHomepage();
    }

}
您也可以用另一种方式来实现,而不需要引入新类。在父类中声明absract(或具有默认值的concrete)方法

class MyTestCase {

    protected abstract Flour getFlour();

}
你的孩子班会是这样的

class SomeTest extends MyTestCase {

    private Flour flour;

    @Test
    public void testRedFlavouredHomepage() {
        flour = Flour.RED;
        testHomepage();
    }

    @Test
    public void testBlueFlavouredHomepage() {  // assuming Blue is my default flavour
        flour = Flour.BLUE;
        testHomepage();
    } 

    public void testHomepage() {
        // test some stuff
    }

    protected abstract Flour getFlour() {
        return flour;
    }

}
我认为第一种解决方案是“更清洁”;即使必须创建其他类,也不能在一个类中包含不同类型的逻辑(如反模式)。

您可以使用(JUnit>=4.9的更高版本)来实现这一点。如果您有一个实现的类,特别是apply(),那么您可以在运行测试之前做额外的事情。将传递给apply方法,该方法包含方法上的注释:

@Deprecated
为例:

public class ExtraSetupTest {
  @Rule
  public TestRule moreSetup = new TestRule() {
    public Statement apply(Statement base, Description description) {
      return statement(base, description);
    }

    private Statement statement(final Statement base,
        final Description description) {
      return new Statement() {
        @Override
        public void evaluate() throws Throwable {
          if (description.getAnnotation(Deprecated.class) != null) {
            System.out.println("more setup here");
          }
          base.evaluate();
        }
      };
    }
  };

  @Test
  public void noExtraSetup() {
    System.out.println("noExtraSetup");
  }

  @Test
  @Deprecated
  public void withExtraSetup() {
    System.out.println("withExtraSetup");
  }
}
这将产生以下输出:

noExtraSetup
more setup here
withExtraSetup

我使用的是JUnit的4.9版本之前的版本,但无论如何这都适用于MethodRule,谢谢。@MikeB提供信息,MethodRule已被弃用,因此如果您升级,您将收到警告。这是我考虑过的一个有效解决方案,但我已经有大约80个测试用例,应该保留默认值,因此我需要将实现排除在外。这意味着我将把默认设置放在MyTestCase中(它们都进行了扩展)。一些添加了新风格的测试已经扩展到两个类中,以测试稍微不同的场景。我认为在测试用例中有5个以上的类会变得很混乱,我认为这是测试1特性。
noExtraSetup
more setup here
withExtraSetup