为啥在同一个 XCTestCase 中的单元测试之间会有一个新的对象实例?

Posted

技术标签:

【中文标题】为啥在同一个 XCTestCase 中的单元测试之间会有一个新的对象实例?【英文标题】:Why there is a new instance of object between unit tests in the same XCTestCase?为什么在同一个 XCTestCase 中的单元测试之间会有一个新的对象实例? 【发布时间】:2021-08-04 14:36:27 【问题描述】:

我已经创建了这样的测试类:

import XCTest

class ExampleTests: XCTestCase 
    private let context = NSManagedObjectContext.mr_()
    func testA() 
        print(#function)
        print(context)
        XCTAssertTrue(true)
    

    func testB() 
        print(#function)
        print(context)
        XCTAssertTrue(true)
    

控制台输出如下:

测试套件“ExampleTests”开始于 2021-08-04 16:33:42.426 测试用例“-[PLZ_Tests.ExampleTests testA]”已启动。 测试A() NSManagedObjectContext: 0x28210a630> //不同的实例 测试用例“-[PLZ_Tests.ExampleTests testA]”通过(0.004 秒)。 测试用例“-[PLZ_Tests.ExampleTests testB]”已启动。 测试B() NSManagedObjectContext: 0x282109c70> //不同的实例 测试用例“-[PLZ_Tests.ExampleTests testB]”通过(0.000 秒)。 测试套件“ExampleTests”于 2021-08-04 16:33:42.431 通过。

它是否为该类中的每个单元测试再次实例化整个类?

【问题讨论】:

是的。你应该阅读developer.apple.com/documentation/xctest/xctestcase/…,这样你就可以为每个方法或整个测试用例设置东西 【参考方案1】:

它是否为该类中的每个单元测试再次实例化整个类?

迂腐,但不是。没有类被实例化。新的instances(对象)被实例化,来自类。

为什么在同一个 XCTestCase 的单元测试之间会有一个新的对象实例?

因为它不是同一个 XCTestCase。 XCTest 框架将为每个测试方法实例化一个ExampleTests 对象。就像任何其他 Swift 类型一样,具有默认值的实例属性将在新实例上调用初始化程序之前评估和设置这些属性。

总共将有 2 个 NSManagedObjectContext 对象,每个对象由 2 个 XCTestCase 对象之一拥有。 testA 将在其中一个上调用,testB 在另一个上调用。

这是一个国际设计决策,可能受到其他 xUnit testing frameworks 的启发。

它有几个好处/方便。

最重要的是它允许测试方法使用实例变量而不会互相践踏(如果它们要并行运行,那将是一笔巨大的交易)。

另一个好处是它不鼓励测试用例之间的“通信”,以防止它们依赖于顺序(其中一个测试用例设置了另一个测试用例通过所必需的某种状态)。当然,您仍然可以通过将状态存储在其他地方(类变量、全局变量、文件系统等)来实现这一点,但这样做会以更明显/引人注目的方式“错误”。

【讨论】:

以上是关于为啥在同一个 XCTestCase 中的单元测试之间会有一个新的对象实例?的主要内容,如果未能解决你的问题,请参考以下文章

单元测试视图在 XCTestCase 中被驳回

单元测试用例:XCTestCase vs Sentestcase

如何在 ios XCTestCase 中对两个对象不相等进行单元测试

XCTestCase 崩溃的 WKInterfaceController 子类上的“alloc init”

UIButton 点击​​的 XCTestCase

ios的单元測试OCUnit以及更新了之后的XCTestCase