【问题标题】:What is the purpose of XCTestCase's setUp method?XCTestCase 的 setUp 方法的目的是什么?
【发布时间】:2014-01-29 01:48:40
【问题描述】:

根据XCTestCase 默认模板中关于setUp 的评论:

Put setup code here; it will be run once, before the first test case.

但是,在XCTestCase.h 中,setUp 上方的评论表述不同:

Setup method called before the invocation of each test method in the class.

为了确认实际行为,我在setUp 中放了一个NSLog 来计算它被调用了多少次:

static int count = 0;

- (void)setUp
{
    [super setUp];
    count++;

    NSLog(@"Call Count = %d", count);
}

这导致在每个测试方法之前调用setUp 方法(确认XCTestCase.h 上的评论)。

我想使用setUp 方法一次创建测试/模拟对象(例如设置Core Data 测试堆栈)。一遍又一遍地创建这些将是处理器密集型的,并且可能非常慢。

所以,

1) setUp 的实际用途是什么?开发人员肯定不会一遍又一遍地在其中创建对象吗?

2) 我怎样才能在XCTestCase 中仅一次创建这些对象?

【问题讨论】:

    标签: ios ios7 xctest


    【解决方案1】:

    我来到这里几乎遇到了同样的问题:如何在 Swift 中只执行一次setUp。这是解决方案:

    override class func setUp() {
        super.setUp()    
        // ...
    }
    
    override class func tearDown() {    
        // ...
        super.tearDown()
    }
    

    现在我仍在寻找 异步 setUp!

    的解决方案

    【讨论】:

    • 异步设置似乎没有用,因为根据定义,您希望在运行该类中的任何测试之前完成设置。
    • 我认为他的意思是他希望在 setUp 方法中的异步调用完成之前不调用他的测试用例中的测试函数。您可以为此使用 DispatchSemaphore。
    【解决方案2】:

    这里有几点需要讨论:setUp 方法的行为,以及一般的最佳测试实践。

    其实有两个setUp方法:

    + (void)setUp;
    - (void)setUp;
    

    类方法(+ (void)setUp)在整个测试运行期间只运行一次。

    实例方法(- (void)setUp)是默认模板中的那个;它在每次测试之前运行。希望在假设的 Xcode 未来版本中,此注释已更改为 // Put setup code here. This method is called before the invocation of each test method in the class.WINK WINK

    所以通过这两种方法,你描述的两种行为都是可能的。

    关于您的评论:

    “开发人员肯定不会一遍又一遍地在其中创建对象吗?”

    我的回答是“是的,他们通常是”。 “好”单元测试的流行首字母缩写词是 FIRST:

    • 快速
    • 隔离
    • 可重复
    • 自我验证
    • 及时

    隔离是本次讨论的关键:您的测试不应依赖于其他测试留下的任何先前状态。理想情况下,您应该为每个测试拆除并重新创建内存中的核心数据堆栈,这样您就知道您是从一个干净的状态开始的。一个很好的例子是this post by Graham Lee。您想使用内存中的堆栈,因为 a) 您可以轻松地将其丢弃,并且 b) 它应该非常快,因为它只是在内存中并且不会影响您的磁盘。

    如果您发现您的测试因此而运行缓慢(不要过早优化),那么我认为合理的下一步是在您的 + (void)setUp 中创建堆栈方法,但每次都在您的 - (void)setUp 方法中创建一个全新的上下文。

    【讨论】:

    • +1:精彩的回答!是的,考虑一下,1) 测试顺序并不能保证(但是对于好的测试,什么时候发生并不重要)并且 2) 测试不应该受到什么影响其他测试正在做(正如你提到的,他们shouldn't rely on any previous test state)。 in-memory 堆栈也是个好主意。这正是我要做的。
    • 阅读完这个答案后,我立即删除了我的 +1 ;) 请注意:XCTest 或多或少是 SenTest 的副本,继承了其所有限制。有更好的测试框架,其中包含可以任意嵌套的组,其中 setupteardown 过程很明显。不幸的是,Xcode 和 XCTest 远远落后,将非常酷的第三方测试框架集成到令人兴奋的 Xcode 测试框架中相当困难。
    • @JRG-Developer 完全正确 - 无法保证测试订单。 @CouchDeveloper 例如,spectabeforeEachbeforeAllafterEachafterAll 方法。
    • 只是对使用类方法而不是实例方法的评论:我有一个描述大型数据结构的 plist 文件和一个在运行时解析该文件以生成对象集合的类.这些对象彼此独立有用,因此不是编写一个方法来公开对 plist 中单个项目的解析,或者专门公开处理解析的方法,而是为测试用例解析整个结构一次,并在每个测试用例中重用其对象测试。重复解析这个文件对测试没有意义。
    • 请注意现在就是未来 - Xcode 的测试模板现在逐字包含// Put setup code here. This method is called before the invocation of each test method in the class.。那是一个编辑,还是你预测了未来? :)
    猜你喜欢
    • 2017-08-23
    • 2011-09-05
    • 2023-03-06
    • 2010-09-07
    • 2020-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多