【问题标题】:Unit Test case fails when whole Test Suite is executed执行整个测试套件时单元测试用例失败
【发布时间】:2017-04-11 21:08:06
【问题描述】:

我正在为我的 sqlite 数据库类编写单元测试用例。我在那个类中有五个公共 API。

我的测试用例如下所示:

+ (void)setUp {  // Note, this is class method and hence called only once during start of this test suite.
    // Code to delete the existing sqlite DB file.
}

- (void)testDBManagerSingletonInstance {
    DBManager *dbMgr = [DBManager getSharedInstance];
    DBManager *dbMgr1 = [[DBManager alloc] init];
    XCTAssertEqualObjects(dbMgr, dbMgr1);
}

- (void)testSaveAndDeleteNicknameAPI {
    // Multiple Assert statements in this test.
}

- (void)testAllAccountStatusAPIs {
    // Multiple Assert statements in this test.
}

每个单一的单元测试都在没有任何错误的情况下执行。但是在执行整个测试套件时它会失败。

我可能知道失败的根本原因。这是因为当执行整个测试套件时,所有测试都会并行运行,并且数据库中会同时发生更新-删除。因此,当所有单元测试运行时,它都会失败。

但我不知道如何解决这个问题,因为这不是异步的,因此我不能使用 XCExpectation 类。

需要帮助来解决和理解问题。

【问题讨论】:

  • 你已经给出了答案。如果测试都使用同一个数据库,那么它的内容就像你说的那样处于不断变化的状态......解决方案是让每个单元测试看看单独的数据库或单独的实例或单独的表......或强制顺序执行。测试时的规则是你必须知道数据库的内容。在这种情况下你永远不会知道,因为它同时被多个进程设置和测试。

标签: ios objective-c swift unit-testing xctestcase


【解决方案1】:

基于XCTests 的测试不会并行运行 - 它们是按顺序运行的。引用the docs

测试同步执行,因为每个测试一个接一个地独立调用。

由于您展示的代码很少,很难说真正的问题是什么。您很可能与您的假设很接近 - 您应该改进您的 setUp(可能从类版本切换到实例版本)和 tearDown 方法或引入模拟,并在可能的情况下在模拟数据库上执行测试。

【讨论】:

    【解决方案2】:

    您不应该在要测试的代码库中使用单例。我认为您的代码在内部使用了 DBManager 的 sharedSingleton 实例。每个单元测试都会更改该实例的内部状态,因此所有后续单元测试都已损坏。您需要在拆解每个测试用例后重置所有更改。

    但我的建议是通过依赖注入来避免基本代码中的单例。在创建类的实例时,注入 DBManager 的单例实例。这使得单元测试更容易。如果您注入协议而不是对象,您甚至可以使用协议假实现来测试您的代码。

    【讨论】:

      猜你喜欢
      • 2019-10-09
      • 2019-11-29
      • 2011-10-09
      • 1970-01-01
      • 2012-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-21
      相关资源
      最近更新 更多