什么是「;“正确”;如何编写这组JUnit测试?

什么是「;“正确”;如何编写这组JUnit测试?,junit,Junit,我正在为一个服务编写JUnit测试,该服务以多种方式创建实体并对其进行操作。我希望我的测试能尝试很多不同的活动组合。我有这样的想法: test1() { /** create entity **/ /** assert **/ } test2() { /** do X to entity **/ /** assert **/ } test3() { /** do X again to entity, expect failure **/ /** assert **/ } test4() {

我正在为一个服务编写JUnit测试,该服务以多种方式创建实体并对其进行操作。我希望我的测试能尝试很多不同的活动组合。我有这样的想法:

test1() {
/** create entity **/
/** assert **/
}

test2() {
/** do X to entity **/
/** assert **/
}

test3() {
/** do X again to entity, expect failure **/
/** assert **/
}

test4() {
/** do Y to entity, expect success **/
/** assert **/
}
但是,我的理解是,我不能期望JUnit以正确的顺序运行测试,并且每个测试都应该是完全自包含的

但是如果我让每个测试都是自包含的,那么会有很多重复的代码,运行时间会很长,而且维护起来会更困难。。。例如:

test1() {
/** create entity **/
/** assert **/
}

test2() {
/** create entity **/
/** do X to entity **/
/** assert **/
}

test3() {
/** create entity **/
/** do X to entity **/
/** do X again to entity, expect failure **/
/** assert **/
}

test4() {
/** create entity **/
/** do X to entity **/
/** do X again to entity, expect failure **/
/** do Y to entity, expect success **/
/** assert **/
}
。。。如果你跟我来

所以我的问题是,编写这些测试的“正确”方法是什么,以使代码干净优雅


谢谢,Rob

您可以使用
@Before
带注释的方法初始化要在测试中使用的实体。 然后,使用
@After
注释方法清除/释放测试使用的任何资源

你可以:

private Entity entity;

@Before
public void init() {
  entity = ...
}

@Test
public void test1() {
  // do things to entity
  ...
}

您可以在每个测试方法中调用setup方法来处理重复的代码

i、 e


哪个对你来说更容易阅读

@OrderRunner
public class EntityTest {
  Entity e;

  shouldBeCreatedInValidState() {
    e = new Entity();
    assert(e.isValid());
  }

  shouldBeWigglable() {
    e.wiggle();
    assert(e.hasBeenWiggled());
  }

  shouldNotBeWigglableTwice() {
    try {
       e.wiggle();
       fail("Wiggled too many times")
    } catch(OverWiggledException e) {}
  }
}

我更喜欢后者。该属性很容易被忽略,因此第二个“摆动”看起来就像是在测试中偶然的一瞥中的一个摆动

如果设置/测试方法更复杂,则创建方法

  shouldNotBeWigglableTwice() {
    givenAnEntity();
    andIWiggleIt();
    try {
       whenIWiggleIt();
       thenItShouldThrowAnException();
    } catch(OverWiggledException e) {}
  }

我可以建议选项#3,其中您只有test4(){…}和更多断言,以记录失败的位置。@sam您肯定不是在一个JUnit测试中建议多个断言吗?对的甚至每个测试都推荐一个断言(我建议,是的。)考虑到罗伯特·休谟正在测试的东西,我认为这个建议没有帮助。您可以说,应该使用另一个测试框架来测试事件序列或特定的使用场景。您还可以构建一个测试运行程序来维护测试用例中的顺序,但这会破坏另一个常见问题。虽然想法不错,但我想如果只对实体执行X操作在第二次调用时失败,这可能是保证良好结果的唯一方法。我想缺点是,给定一个带有n个AssertsB的测试用例,您可能需要n次迭代来发现所有bug,但如果一系列测试应该从检查连接开始,您不能将此检查放在“before”子句中。
public class EnttityTest {
  shouldBeCreatedInValidState() {
    Entity e = new Entity();
    assert(e.isValid());
  }

  shouldBeWigglable() {
    Entity e = new Entity();
    e.wiggle();
    assert(e.hasBeenWiggled());
  }

  shouldNotBeWigglableTwice() {
    Entity e = new Entity();
    e.wiggle();
    try {
       e.wiggle();
       fail("Wiggled too many times")
    } catch(OverWiggledException e) {}
  }
}
  shouldNotBeWigglableTwice() {
    givenAnEntity();
    andIWiggleIt();
    try {
       whenIWiggleIt();
       thenItShouldThrowAnException();
    } catch(OverWiggledException e) {}
  }