Junit 外部资源@Rule 顺序

Posted

技术标签:

【中文标题】Junit 外部资源@Rule 顺序【英文标题】:Junit External Resource @Rule Order 【发布时间】:2013-10-04 07:11:09 【问题描述】:

我想在我的测试类中使用多个外部资源,但外部资源的排序有问题。

这里是代码 sn-p :

public class TestPigExternalResource 

     // hadoop external resource, this should start first
     @Rule
     public HadoopSingleNodeCluster cluster = new HadoopSingleNodeCluster();

     // pig external resourcem, this should wait until hadoop external resource starts
     @Rule
     public  PigExternalResource pigExternalResource = new PigExternalResource(); 

     ...  

问题是它试图在 hadoop 启动之前启动 pig,因此我无法连接本地 hadoop 单节点集群。

有没有办法排序junit的规则?

谢谢

【问题讨论】:

HadoopSingleNodeCluster 类是否公开可用?因为我使用org.apache.hadoop.mapred.ClusterMapReduceTestCase,但它不是那么稳定。 @nefo_x HadoopSingleNodeCluster 是我自己的类,在 hadoop 发行版中不可用。 它是基于一些现有的代码库吗?我尝试使用集群 mapreduce 测试用例,但它会启动外部 JVM,在某些情况下调试起来有点困难。 【参考方案1】:

您可以使用RuleChain。

@Rule
public TestRule chain= RuleChain.outerRule(new HadoopSingleNodeCluster())
                           .around(new PigExternalResource());

【讨论】:

【参考方案2】:

您为什么不将这两个ExternalResources 包装在您自己的ExternalResource 中,该beforeafter 方法按照您在新资源的beforeafter 方法中所需的顺序调用。

例子:

public class MyResource extends ExternalResource
     private final List<ExternalResource> beforeResources;
     private final List<ExternalResource> afterResources;

     public MyResource(List<ExternalResource> beforeResources,
          List<ExternalResource> beforeResources)
     

      public void before()
          for (ExternalResource er : beforeResources)
               er.before();
      

      public void after()
          for (ExternalResource er : afterResources)
               er.after();
      



public class TestPigExternalResource 

 // hadoop external resource, this should start first
 public HadoopSingleNodeCluster cluster = new HadoopSingleNodeCluster();

 // pig external resourcem, this should wait until hadoop external resource starts
 public  PigExternalResource pigExternalResource = new PigExternalResource(); 

  @Rule
  public MyResource myResource = new MyResource(
          newArrayList(cluster, pigExternalResource),
          newArrayList(cluster, pigExternalResource));
 ...  

【讨论】:

谢谢,但我想在 before 和 after 方法中使用 @Rule 注释是不允许的。 查看添加到帖子的示例。其他资源将不再被标记为规则,因为它们将包含在包装规则中。【参考方案3】:

从 JUnit 4.13-beta-1 开始,@Rule@ClassRule 中有一个新的 order 属性。

@Rule代码:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD, ElementType.METHOD)
public @interface Rule 

    int DEFAULT_ORDER = -1;

    /**
     * Specifies the order in which rules are applied. The rules with a higher value are inner.
     *
     * @since 4.13
     */
    int order() default DEFAULT_ORDER;


另请参阅此 PR 以供参考:PR-1445。

【讨论】:

以上是关于Junit 外部资源@Rule 顺序的主要内容,如果未能解决你的问题,请参考以下文章

junit用法,before,beforeClass,after, afterClass的执行顺序

Junit测试@FixMethodOrder调整测试顺序

Junit4按顺序执行test方法

为啥 JUnit 中的 @Rule 注释字段必须是公开的?

Junit @Rule 和 @ClassRule

Selenium + JUnit:测试顺序/流程?