【问题标题】:Hierarchy of JUnit testsJUnit 测试的层次结构
【发布时间】:2013-09-19 12:44:15
【问题描述】:

我需要以下测试

@runwith(cache, memory)
class CollectionA is -- this is a suite (aka folder)
  class Cache {   -- this is a sub-suite (aka folder)
    @test testCache1()  -- this is a method (aka file)
    @test testCache2()
    @test testCache3()
  }
  class RAM {  -- this is a sub-suite (aka folder)
    @test testRAM1()
    @test testRAM2()
  }
  @test testIO()
  @test testKeyboard()
  @test testMouse()
  @test testMonitor()
  @test testPower()
  @test testBoot()

请注意,只有 Cache 和 RAM 需要分组。层次结构有助于对抗复杂性并运行相关测试,例如必要时单独缓存子系统。问题是我使用@runwith 进行分组时,JUnit 会忽略除 RAM 和 Cache 集合之外的所有单个测试方法。在 JUnit 设计中似乎不能有兄弟文件和文件夹。 the official example of grouping 中的 cmets 也暗示了

@RunWith(Suite.class)
@Suite.SuiteClasses({
  TestA.class,
  TestA.class
})

public class FeatureTestSuite {
  // the class remains empty,
  // used only as a holder for the above annotations
  // HEY!!! WHAT ABOUT MY @Tests HERE?
}

答案表明我是否需要包装每一个测试,例如testPower 进入他们的单调套装或扁平套装 - 如果完全摆脱层次结构。

那么,JUnit 被设计成不允许将单个文件(@test 方法)与文件夹(@runwith 套件)混合是正确的吗?为什么?如何解决这个问题? @runwith.Suite 可能有替代品吗?

【问题讨论】:

  • 我不明白你在说什么 WRT 文件和文件夹。您不能在套件中进行测试。因此,但是测试类中的测试并包含套件中的测试。只要测试是公开的,就可以将测试包含在套件中,对测试所在的文件夹没有任何限制。您可以添加与套件位于同一文件夹(包)中的测试以及位于不同文件夹(包)中的测试。
  • 我看到你说我不能在套件中进行测试。你能不能给出一个答案,并解释一下设计,这样我就不会在这个陷阱上浪费时间。
  • 问题是所有的类都应该是它们自己的文件。不要使用子/内部类。
  • 我不明白。如果您说不可能在套件中进行测试,而套件类可以在任何地方找到,那么为什么嵌套会产生任何问题? IMO,在语法上嵌套逻辑嵌套的东西是件好事。
  • 要使用内部类,您将使用 Enclosed 运行器,而不是 Suite 运行器。使用 Suite 的单独类允许您 1:拥有更小的文件 2:运行单独的测试

标签: junit grouping hierarchy folding


【解决方案1】:

你喜欢创建的是 mixin 类型,JUnit runner 不支持。所以是的,你是对的,开箱即用是不可能的。

为此,我创建了一个插件,可用于为您的测试创建分层上下文。在我看来,这是 JUnit 中缺少的一个功能,我也会保持联系以将其包含到 JUnit 核心中。

插件提供了一个 HierarchicalContextRunner,它允许使用内部类将您的测试分组到上下文中。每个上下文都可以包含测试或其他上下文。它还允许拥有@Before、@After、@Rule 方法和字段,以及标准 Runner 的 @Ignore 等其他功能。 :-)

例子:

@RunWith(HierarchicalContextRunner.class)
public class CollectionA {
    public class Cache {
        @Test testCache1() {...}
        @Test testCache2() {...}
        @Test testCache3() {...}
    }
    public class RAM {
        @Test testRAM1() {...}
        @Test testRAM2() {...}
    }
    @Test testIO() {...}
    @Test testKeyboard() {...}
    @Test Mouse() {...}
    @Test testMonitor() {...}
    @Test testPower() {...}
    @Test testBoot() {...}
}

试一试: https://github.com/bechte/junit-hierarchicalcontextrunner/wiki

非常感谢投票和反馈。 :)

【讨论】:

【解决方案2】:

你的设计应该是这样的:

// folder com.myco.project
SuiteX.java
TestA.java
TestB.java


// contents of TestA.java
public class TestA{
   @Test
   public void someTestInA(){...}
}

// contents of TestB.java
public class TestB{
   @Test
   public void someTestInB(){...}
}

// contents of SuiteX.java
@RunWith(Suite.class)
@Suite.SuiteClasses({
  TestA.class,
  TestB.class
})
public class FeatureTestSuite {
  // the class remains empty,
  // used only as a holder for the above annotations
}

正如我在评论中所说,为每个测试类使用单独的 java 文件。不要使用内部类。

【讨论】:

  • 取消嵌套子集合如何启用 FeatureTestSuite 中的单元测试?我在你的例子中没有看到。
  • Suite 运行器导致TestA 和TestB 中的测试在运行FeatureTestSuite 时执行。这就是Suite runner 的意义所在。
  • 你明白TestA和TestB 被执行(但是FeatureTestSuite里面的@test方法不是)所以执行方法是个问题 同时执行TestA 和TestB 不是吗?
  • 我相信我已经说过,FeatureTestSuite 不应该有任何测试。 Suite 不包含测试,它链接其他测试类。不要试图让它做一些它不打算做的事情。
  • 我相信我要求将其作为答案。你回答的不一样。其次,你可以解释为什么它是这样设计的,并提出除了Suite之外的任何东西,它允许将测试集合与方法混合。在大多数情况下,每个(子)套件只有一个测试。当单个方法足够时,为每个测试创建一个类和方法是愚蠢的。
猜你喜欢
  • 2012-02-11
  • 2012-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多