简体   繁体   English

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

[英]How can I reflectively access the test method to run after a call to @Before setup()?

We have lots of selenium tests running through junit, and they all have a few steps which need to run before the actual tests. 我们有很多通过junit运行的硒测试,并且它们都有一些实际测试之前需要运行的步骤。 For this we have a parent TestCase class which has some @Before and @After methods in it. 为此,我们有一个父TestCase类,其中包含一些@Before和@After方法。

Now, due to a new feature of our site I would like to parameterise part of this set up, I'd like to create a new annotation to put on some tests to indicate to the setup() method that the setup is slightly different, whilst allowing the others to use the default. 现在,由于我们网站的一项新功能,我想参数化此设置的一部分,我想创建一个新的批注以进行一些测试,以向setup()方法表明设置略有不同,同时允许其他人使用默认值。 So, is it possible to reflectively access the test method about to be run in an @Before method? 因此,是否有可能以反射方式访问即将在@Before方法中运行的测试方法?

eg. 例如。

class SomeTest extends MyTestCase {

  @Test
  @Flavour(Red.class)
  public void testRedFlavouredHomepage() {
    testHomepage();
  }

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

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

I'd rather suggest to use different test classes for those 2 methods. 我宁愿建议对这两种方法使用不同的测试类。

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 */
    }

}

And then you can put your tests into 2 different classes extending from MyTestCase and MyRedTestCase respectively. 然后,您可以将测试放入分别从MyTestCase和MyRedTestCase扩展的2个不同的类中。

class BlueTest extends MyTestCase {

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

}

class RedTest extends MyRedTestCase {

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

}

You can do it another way as well, without introducing new classes. 您也可以采用另一种方式来做,而无需引入新的类。 Declare an absract (or concrete with the default value) method in your parent class. 在父类中声明一个抽象方法(或带有默认值的具体方法)。

class MyTestCase {

    protected abstract Flour getFlour();

}

And your child class will look like this 您的孩子班级将如下所示

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

}

I'd say the 1st solution is "cleaner"; 我会说第一种解决方案是“更清洁”。 even though you have to create additional classes, you don't include logic of different types in one class (like in the anti-pattern God object ). 即使您需要创建额外的类,你不包括不同类型的一个类(如在反模式的逻辑神的对象 )。

You can do this using @Rule (with the later versions of JUnit >= 4.9). 您可以使用@Rule (对于更高版本的JUnit> = 4.9)来执行此操作。 If you have a class which implements TestRule , specifically apply(), you can do extra things before your test gets run. 如果您有一个实现TestRule的类,特别是apply(),则可以在运行测试之前做一些额外的事情。 The Description is passed to the apply method, which contains the annotations on your method: Description传递给apply方法,该方法包含方法上的注释:

Using @Deprecated as an example: @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");
  }
}

This produces as output: 这产生作为输出:

noExtraSetup
more setup here
withExtraSetup

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM