【问题标题】:JUnit tests succeed individually, but when executed together fail and cause errors?JUnit 测试单独成功,但一起执行时会失败并导致错误?
【发布时间】:2018-07-06 18:52:35
【问题描述】:

我有三个 JUnit 测试,如下所示。如果单独执行这些测试,即注释掉另外两个测试并只执行一个,这些测试都会成功。

但是,如果我执行所有三个未注释的测试,则“testOrderDatabaseReturnsOrdersCorrectly”会产生错误,并且“testOrderDatabaseRemovesOrdersCorrectly”会失败。

我真的不明白为什么会这样。我在每次测试之前都使用@Before 进行设置,所以所有三个测试的条件应该相同吗?为什么其中一些在单独工作时会失败?

@Before
public void setup()
{
    sys = new OrderSystem();
    sys.getDb().clearDb();
}


@Test
public void testOrderDatabaseAddsOrders()
{
    sys.getDb().clearDb();
    sys.createOrder(25);
    assertEquals(sys.getDb().getDbArrayList().size(), 1);

    sys.createOrder(30);
    assertEquals(sys.getDb().getDbArrayList().size(), 2);

    sys.createOrder(35);
    assertEquals(sys.getDb().getDbArrayList().size(), 3);
}


@Test
public void testOrderDatabaseRemovesOrdersCorrectly()
{
    sys.createOrder(25);
    assertEquals(sys.getDb().getDbArrayList().size(), 1);
    sys.removeOrder("BRICK1");
    assertEquals(sys.getDb().getDbArrayList().size(), 0);
}

@Test
public void testOrderDatabaseReturnsOrdersCorrectly()
{
    System.out.println("Size of db: " + sys.getDb().getDbArrayList().size());
    sys.createOrder(25);
    System.out.println("Size of db: " + sys.getDb().getDbArrayList().size());
    BrickOrder o = sys.getOrder("BRICK1");
    assertEquals(o.getNumberOfBricks(), 25);
}

【问题讨论】:

  • sys 是否声明为static
  • 声明的静态在哪里? @rgettman
  • 如果你的意思是在测试类中,不,它只是声明private OrderSystem sys
  • 发布足够的代码来重现问题。
  • 错误是什么?

标签: java junit


【解决方案1】:

但是,如果我在未注释的情况下执行所有三个测试,则“testOrderDatabaseReturnsOrdersCorrectly”会产生错误并且“testOrderDatabaseRemovesOrdersCorrectly”会失败。

您的问题很可能是在运行下一个测试方法时没有清除其中一种测试方法的结果并且它们发生冲突。也许您正在使用像 H2 这样的内存数据库,即使您正在调用 sys.getDb().clearDb();,它也没有被完全清除?

您可以通过多种方式验证这一点:

  • 首先将System.out.println() 消息放入setup() 以确保在每个方法之前调用它。
  • 在您的测试方法开始时,在您的数据库中查找是否有结果来验证clearDb() 做了什么。我怀疑你会发现它没有完全工作。
  • 更改测试方法以使用非重叠表或使用非重叠数据来查看是否有效。例如,创建一个int orderNumber 字段并在每个测试方法中对其执行++ 以确保您使用的是新订单。这当然是一种解决方法。最好理解为什么 clear 没有做你想做的事。

如何解决这个问题是一个更复杂的问题,这取决于实际支持您的db 的内容。也许您的clearDb() 方法中存在一些错误。我之所以提到 H2,是因为即使您设置了一个全新的数据库连接,旧的连接也不会被破坏并且会被重用。如果它是一个 SQL 数据库,那么完全删除表并重新创建它们是一件事,它甚至会迫使像 H2 这样的持久内存数据库清除其内容。

希望这会有所帮助。

【讨论】:

  • db 只是一个 ArrayList,出于语义原因,我称它为 db。 clear 方法实际上就是AL.clear();
  • 每次测试前都会调用设置。我只是不明白当测试以与它们自己执行的完全相同的条件开始时会发生这种情况。
  • @Jakemangan1 的失败究竟是什么?您的arraylist 是否有错误的条目数?它有几个?你试过调试吗?
【解决方案2】:

我已经弄清楚是什么导致了错误和奇怪的测试行为。

我有一个声明为静态的字段变量。由于某种原因,即使每次都重置 sys 变量,但在每次测试之前都没有重置它。当我删除这个变量的静态声明时,所有的测试都成功了。

【讨论】:

  • 啊哈。因此,您的订单柜台或自动生成名称的东西是静态的。说得通。当您稍后依赖它时,订单的名称会自动创建为"BRICK1",这当然很奇怪。也许您应该将名称传递给您的createOrder()
猜你喜欢
  • 2023-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-18
  • 1970-01-01
  • 2013-11-08
  • 1970-01-01
相关资源
最近更新 更多