有没有办法在JUnit中对测试进行分组,这样我才能只运行一些组?
或者可以注释一些测试,然后全局禁用它们吗?
我正在使用 JUnit 4 ,我无法使用TestNG。
编辑:@ RunWith和@SuiteClasses效果很好。但是,是否可以在测试类中仅注释一些测试?或者我是否需要注释整个测试类?
答案 0 :(得分:73)
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
答案 1 :(得分:9)
为了处理全局禁用它们,JUnit(4.5+)有两种方法,一种是使用新方法。如果将它放在测试类的@BeforeClass(或@Before)中,如果条件失败,它将忽略测试。在这种情况下,您可以将系统属性或其他可以全局设置为开启或关闭的内容。
另一种方法是创建一个自定义运行器,它可以了解全局属性并委托给相应的运行器。这种方法更加脆弱(因为JUnit4内部运行程序不稳定并且可以从发行版更改为发行版),但它具有能够在类层次结构中继承并在子类中重写的优点。如果您必须支持传统的JUnit38类,这也是唯一可行的方法。
以下是一些用于执行自定义Runner的代码。关于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标记都无济于事,您将不得不在内部类中重新创建它们。它可以调用外部类的方法,但它必须有自己的方法作为钩子。
答案 2 :(得分:8)
您想在测试类中对测试进行分组,还是要对测试类进行分组?我将假设后者。
这取决于您运行测试的方式。如果您通过Maven运行它们,则可以准确指定要包含的测试。请参阅the Maven surefire documentation。
更一般地说,我做的是我有一个测试套件树。 JUnit 4中的测试套件类似于:
@RunWith(Suite.class)
@SuiteClasses(SomeUnitTest1.class, SomeUnitTest2.class)
public class UnitTestsSuite {
}
所以,也许我有一个FunctionTestsSuite和一个UnitTestsSuite,然后是一个包含另外两个的AllTestsSuite。如果您在Eclipse中运行它们,您将获得一个非常好的分层视图。
这种方法的问题在于,如果你想以多种不同的方式对测试进行切片,那就太乏味了。但它仍然可能(例如,您可以根据模块切换一组套件,然后对测试类型进行另一次切片)。
答案 3 :(得分:3)
试试JUnit Test Groups。来自文档:
@TestGroup("integration")
public class MyIntegrationTest {
@ClassRule
public static TestGroupRule rule = new TestGroupRule();
...
}
答案 4 :(得分:3)
在JUnit 5中,您可以在类或方法级别上声明Eager
用于过滤测试。类似于TestNG中的测试组或JUnit 4中的类别
来自javadoc:
标签用于过滤为给定测试执行的测试 计划。例如,开发团队可以使用以下值标记测试: 例如“ fast”,“ slow”,“ ci-server”等,然后提供标签列表 用于当前的测试计划,可能取决于 当前环境。
例如,您可以使用apoc.periodic.iterate
call apoc.periodic.iterate("
LOAD CSV WITH HEADERS FROM 'file:///LoanStats3bEDITED.csv' AS line RETURN line
","
//member node
CREATE (member:Person{member_id:TOINT(line.member_id)})
//Personal information node
CREATE (personalInformation:PersonalInformation{addr_state:line.addr_state})
//recordHistory node
CREATE (recordHistory:RecordHistory{delinq_2yrs:TOFLOAT(line.delinq_2yrs),earliest_cr_line:line.earliest_cr_line,inq_last_6mths:TOFLOAT(line.inq_last_6mths),collections_12_mths_ex_med:TOFLOAT(line.collections_12_mths_ex_med),delinq_amnt:TOFLOAT(line.delinq_amnt),percent_bc_gt_75:TOFLOAT(line.percent_bc_gt_75), pub_rec_bankruptcies:TOFLOAT(line.pub_rec_bankruptcies), tax_liens:TOFLOAT(line.tax_liens)})
//Loan node
CREATE (loan:Loan{funded_amnt:TOFLOAT(line.funded_amnt),term:line.term, int_rate:line.int_rate, installment:TOFLOAT(line.installment),purpose:line.purpose})
//Customer Finances node
CREATE (customerFinances:CustomerFinances{emp_length:line.emp_length,verification_status_joint:line.verification_status_joint,home_ownership:line.home_ownership, annual_inc:TOFLOAT(line.annual_inc), verification_status:line.verification_status,dti:TOFLOAT(line.dti), annual_inc_joint:TOFLOAT(line.annual_inc_joint),dti_joint:TOFLOAT(line.dti_joint)})
//Accounts node
CREATE (accounts:Accounts{revol_util:line.revol_util,tot_cur_bal:TOFLOAT(line.tot_cur_bal)})
//creating the relationships
MERGE (member)-[:FINANCIAL{issue_d:line.issue_d,loan_status:line.loan_status, application_type:line.application_type}]->(loan)
MERGE (customerFinances)<-[:FINANCIAL]-(member)
MERGE (accounts)<-[:FINANCIAL{open_acc:TOINT(line.open_acc),total_acc:TOFLOAT(line.total_acc)}]-(member)
MERGE (personalInformation)<-[:PERSONAL]-(member)
MERGE (recordHistory)<-[:HISTORY]-(member)
", {batchSize:1000, iterateList:true})
声明一个测试类,该类将为所有方法继承,并在需要时对某些方法覆盖:
@Tag
您可以对其他测试类应用相同的逻辑。
这样,测试类(以及方法)也属于特定标签。
作为一种好的做法,您可以创建自定义的组合注释,而不是在整个测试类中复制和粘贴"slow"
和@Tag
。
例如:
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
@Tag("slow")
public class FooTest{
//
@Test
void loadManyThings(){
...
}
@Test
void loadManyManyThings(){
...
}
@Test
@Tag("fast")
void loadFewThings(){
...
}
}
并将其用作:
@Tag("fast")
要在文本执行期间启用或禁用标有特定标签的测试,您可以依靠maven-surefire-plugin documentation:
要包含标签或标签表达式,请使用
@Tag("slow")
。要排除标签或标签表达式,请使用
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.junit.jupiter.api.Tag; @Target({ ElementType.TYPE, ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) @Tag("slow") public @interface Slow { }
。
只需根据需要(在文档示例中)在pom.xml中配置插件即可:
@Test
@Slow
void slowProcessing(){
...
}
有关信息,test goal documentation未更新。
答案 5 :(得分:1)
您可以创建包含测试组的测试Suite对象。或者,您的IDE(如Eclipse)可能支持运行给定包中包含的所有测试。
答案 6 :(得分:0)
您可以使用测试套件(http://qaautomated.blogspot.in/2016/09/junit-test-suits-and-test-execution.html),也可以使用Junit类别(http://qaautomated.blogspot.in/2016/09/junit-categories.html)有效地对测试用例进行分组。