2009-05-03 130 views
32

有没有任何方法可以在JUnit中对测试进行分组,以便我只能运行一些组?分组JUnit测试

还是有可能注释一些测试,然后全局禁用它们?

我正在使用JUnit 4,我不能使用TestNG。

编辑: @RunWith和@SuiteClasses非常棒。但是是否有可能在测试类中仅注释一些测试?还是我必须注释整个测试课程?

+0

相关:http://stackoverflow.com/questions/457276/junit4-test-suites/4952225#4952225 – cmcginty 2011-02-10 00:43:45

+0

`@ RunWith`和`@ SuiteClasses`根本不好,看看http:// stackoverflow。 com/questions/18894951 – Val 2013-09-19 12:52:30

回答

9

您是否想将测试分组到测试类中,或者是否想将测试类分组?我将假设后者。

这取决于你如何运行你的测试。如果你通过Maven运行它们,可以准确地指定你想要包含哪些测试。请参阅the Maven surefire documentation

但是,更普遍的是,我所做的是我有一套测试套件。测试套件JUnit 4中看起来像:

@RunWith(Suite.class) 
@SuiteClasses(SomeUnitTest1.class, SomeUnitTest2.class) 
public class UnitTestsSuite { 
} 

所以,也许我有一个FunctionTestsSuite和UnitTestsSuite,然后一个AllTestsSuite包括其他两个。如果你在Eclipse中运行它们,你会得到一个很好的分层视图。

这种方法的问题在于,如果你想以多种不同的方式切片测试,那就很乏味。但它仍然是可能的(例如,你可以有一套套件根据模块进行切片,然后对测试类型进行另一种切片)。

1

您可以创建测试Suite包含测试组的对象。或者,您的IDE(如Eclipse)可能支持运行给定包中包含的所有测试。

8

要处理全局禁用它们,JUnit(4.5+)有两种方法一种是使用新方法assumeThat。如果将它放在测试类的@BeforeClass(或@Before)中,并且条件失败,它将忽略测试。在这种情况下,您可以将系统属性或其他可以全局设置为开或关的其他内容。

另一种选择是创建一个自定义运行程序,该运行程序可以理解全局属性并委派给适当的运行人员。这种方法更加脆弱(因为JUnit4内部运行器不稳定,可以从发布版本更改为发布版本),但它的优点是可以沿类继承并在子类中重写。如果您必须支持传统的JUnit38类,那么这也是唯一现实的方法。

这里是一些代码来做自定义亚军。关于getAppropriateRunnerForClass可能做什么,我实现它的方式是有一个单独的注释,告诉自定义运行器要运行什么。唯一的选择是来自JUnit代码的一些非常脆弱的复制粘贴。

private class CustomRunner implements Runner 
private Runner runner; 

    public CustomRunner(Class<?> klass, RunnerBuilder builder) throws Throwable { 
     if (!isRunCustomTests()) { 
      runner = new IgnoredClassRunner(klass); 
     } else { 
      runner = getAppropriateRunnerForClass(klass, builder); 
    } 

    public Description getDescription() { 
     return runner.getDescription(); 
    } 

    public void run(RunNotifier notifier) { 
     runner.run(notifier); 
    } 
} 

编辑:@RunWith标记只适用于整个类。解决这个限制的一个方法是将测试方法移动到静态内部类中并对其进行注释。这样你就可以在类的组织中获得注释的优势。但是,这样做不会对任何@Before或@BeforeClass标记有帮助,您将不得不在内部类中重新创建这些标记。它可以调用外部类的方法,但它必须有自己的方法作为钩子。

71

的JUnit 4.8支持分组:

public interface SlowTests {} 
public interface IntegrationTests extends SlowTests {} 
public interface PerformanceTests extends SlowTests {} 

然后......

public class AccountTest { 

    @Test 
    @Category(IntegrationTests.class) 
    public void thisTestWillTakeSomeTime() { 
     ... 
    } 

    @Test 
    @Category(IntegrationTests.class) 
    public void thisTestWillTakeEvenLonger() { 
     ... 
    } 

    @Test 
    public void thisOneIsRealFast() { 
     ... 
    } 
} 

最后,

@RunWith(Categories.class) 
@ExcludeCategory(SlowTests.class) 
@SuiteClasses({ AccountTest.class, ClientTest.class }) 
public class UnitTestSuite {} 

从这里摘自:http://weblogs.java.net/blog/johnsmart/archive/2010/04/25/grouping-tests-using-junit-categories-0

另外,的Arquillian它自我支持分组: https://github.com/weld/core/blob/master/tests-arquillian/src/test/java/org/jboss/weld/tests/Categories.java

3

尝试JUnit Test Groups。从文档:

@TestGroup("integration") 
public class MyIntegrationTest { 
    @ClassRule 
    public static TestGroupRule rule = new TestGroupRule(); 

    ... 
} 
  • 执行一个简单的测试组:-Dtestgroup =积分
  • 执行多个测试组:-Dtestgroup =组1,组2
  • 执行所有测试组:-Dtestgroup =所有