简体   繁体   English

jUnit 忽略基类中的 @Test 方法

[英]jUnit ignore @Test methods from base class

Let's say I have a test class called testFixtureA with several methods testA , testB , testC , etc, each with @Test annotation.假设我有一个名为testFixtureA的测试类,它有几个方法testAtestBtestC等,每个方法都有@Test注释。

Let's now say I subclass testFixtureA into class called testFixtureAB and I don't overwrite anything.现在假设我将testFixtureA子类化到名为testFixtureAB的类中,并且我不覆盖任何内容。 testFixtureAB is empty as for now. testFixtureAB目前是空的。

When I run tests from testFixtureAB , methods testA , testB and testC are executed by test runner because test runner doesn't distinguish between test methods from class and baseclass.当我从testFixtureAB运行测试时,方法testAtestBtestC由测试运行器执行,因为测试运行器不区分来自类和基类的测试方法。

How can I force test runner to leave out tests from baseclass?如何强制测试运行器从基类中省略测试?

and I don't overwrite anything.我不会覆盖任何东西。 testFixtureAB is empty as for now testFixtureAB 目前为空

There's your answer.这就是你的答案。 If you want to not run testB from the main class, overrride it:如果您不想从主类运行 testB,请覆盖它:

public class testFixtureAB extends testFixtureA {
   @Override
   public void testB() {}
}

Restructure your test classes.重组你的测试类。

  • If you don't want to use the tests from the baseclass, then don't extend it如果您不想使用基类中的测试,请不要扩展它
  • If you need other functionality from the base class, split that class in two - the tests, and the other functionality如果您需要基类的其他功能,将该类分成两部分 - 测试和其他功能

ignoring the whole base class:忽略整个基类:

@Ignore
class BaseClass {
   // ...
}

check out this example 看看这个例子

It's quite easy to achieve implementing some few classes:实现一些类很容易实现:

  • Create your own TestRunner创建你自己的TestRunner
  • Create an annotation like @IgnoreInheritedTests创建一个像@IgnoreInheritedTests这样的注解
  • Create a class that extends org.junit.runner.manipulation.Filter创建一个扩展org.junit.runner.manipulation.Filter的类

On the filter class:在过滤器类上:

public class InheritedTestsFilter extends Filter {

    @Override
    public boolean shouldRun(Description description) {
        Class<?> clazz = description.getTestClass();
        String methodName = description.getMethodName();
        if (clazz.isAnnotationPresent(IgnoreInheritedTests.class)) {
            try {
                return clazz.getDeclaredMethod(methodName) != null;
            } catch (Exception e) {
                return false;
            }
        }
        return true;
    }

    @Override
    public String describe() {
        // TODO Auto-generated method stub
        return null;
    }

}

on your custom runner:在您的自定义跑步者上:

 /**
 * @param klass
 * @throws InitializationError
 * @since
 */
public CustomBaseRunner(Class<?> klass) throws InitializationError {
    super(klass);
    try {
        this.filter(new InheritedTestsFilter());
    } catch (NoTestsRemainException e) {
        throw new IllegalStateException("class should contain at least one runnable test", e);
    }
}

In Junit 5, you can make base class as abstract and extends it with a concrete class.在 Junit 5 中,您可以将基类作为抽象类并使用具体类对其进行扩展。

When you run the abstract in your IDE, your subclass will get executed instead.当您在 IDE 中运行抽象时,您的子类将被执行。

In the latest JUnit you can use the @Rule annotation on the subclass to inspect the test name and intercept the test run to ignore the test dynamically.在最新的 JUnit 中,您可以在子类上使用 @Rule 注释来检查测试名称并拦截测试运行以动态忽略测试。 But I would suggest that @Bozho's idea is the better one - the fact that you need to do this indicates a bigger problem that probably shows inheritance is not the right solution here.但我建议@Bozho 的想法更好——你需要这样做的事实表明一个更大的问题可能表明继承在这里不是正确的解决方案。

I know, it's not the answer...我知道,这不是答案...

Consider the reason why you extend concrete test classes.考虑扩展具体测试类的原因。 You do duplicate test methods that way.你这样做是重复的测试方法。

If you share code between tests then consider writing base test classes with helper and fixture setup methods or test helper class .如果您在测试之间共享代码,请考虑使用助手和夹具设置方法测试助手类编写基本测试类

If for running tests then try organizing tests with suites and categories .如果要运行测试,请尝试使用套件和类别组织测试。

What if you want to execute the same test for different configurations of the same test suite?如果您想为同一测试套件的不同配置执行相同的测试怎么办?

For example, let's say you have Class A with test1, test2 and test3 methods that hit an embedded database then you want to create separated "setUp" and "tearDown" for every embedded vendor (H2, HyperSQL, etc) but runs the same testing for each one.例如,假设您有一个带有 test1、test2 和 test3 方法的 A 类,它们命中嵌入式数据库,然后您想为每个嵌入式供应商(H2、HyperSQL 等)创建单独的“setUp”和“tearDown”,但运行相同的测试每一个人。

I would like to extend a class that contain those test methods and configure it in a subclass.我想扩展一个包含这些测试方法的类并在子类中配置它。 My problem is that the super class SHOULD NOT be considered as eligible for the test runner.我的问题是超类不应该被认为有资格成为测试运行者。 The problem arises when the test runner executes the super class and given that don't found the corresponding setup and teardown methods, it crashs :(当测试运行程序执行超类并且没有找到相应的设置和拆卸方法时,就会出现问题,它会崩溃:(

In the base test class' @Test methods:在基础测试类的@Test 方法中:

assumeTrue(getClass().equals(BaseClassTest.class));

It will ignore those in the subclass tests but not completely leave them out.它将忽略子类测试中的那些,但不会完全将它们排除在外。

If for any reason you need two JUnit classes for same functionality, the best approach for me is:如果出于某种原因您需要两个 JUnit 类来实现相同的功能,对我来说最好的方法是:

  • put the common code in a parent class TestFixture with only constants and mocked services.将公共代码放在只有常量和模拟服务的父类TestFixture中。
  • create two subclasses: TestFixtureA and TestFixtureB创建两个子类: TestFixtureATestFixtureB

This way you will not have duplicated code, nor double runs.这样你就不会有重复的代码,也不会重复运行。

I ran into a similar issue where I had a generic abstract base class TestBase and 2 subclasses TestA, TestB that extended the base class.我遇到了一个类似的问题,我有一个通用的抽象基类 TestBase 和 2 个扩展基类的子类 TestA、TestB。 I wanted all tests from TestBase to run for TestA but to skip some for TestB.我希望 TestBase 中的所有测试都为 TestA 运行,但为 TestB 跳过一些测试。 You can use the JUnit annotations Nested and Disabled to group tests in the base class into categories and then enable a full disable of that entire category of tests.您可以使用 JUnit 注释NestedDisabled将基类中的测试分组到类别中,然后启用对整个测试类别的完全禁用。

public class TestB extends TestBase {

  // disable entire suite of inherited tests
  // from the nested class declared on the parent
  @Nested
  @Disabled
  public class ComponentCTests {}

}

public abstract class TestBase {

  @Nested
  public class ComponentCTests {
     @Test
     public void testSomething() {
      // test something
      }
  }
}

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

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