XCTestCase的setUp方法的目的是什么?

根据XCTestCase有关setUp的默认模板中的XCTestCase

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); } 

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

我想使用setUp方法创build一次testing/模拟对象(例如,设置一个核心数据testing栈)。 一遍又一遍地创build这些将是处理器密集型,可能非常缓慢。

所以,

1)实际上打算使用的setUp是什么? 开发人员不是一遍又一遍地创build对象吗?

2)如何在XCTestCase只创build一次这些对象?

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

实际上有两个 setUp方法:

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

类方法( + (void)setUp )仅在整个testing运行期间运行一次。

实例方法( - (void)setUp )是默认模板中的一个, 它在每个testing之前运行。 希望在Xcode的假设未来版本中,这个注释将被改为// Put setup code here. This method is called before the invocation of each test method in the class. // Put setup code here. This method is called before the invocation of each test method in the class. 眨眼眨眼

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

关于你的评论:

“开发人员肯定不会一遍又一遍地创build对象?

我的答案是“是的,他们通常是”。 “良好”unit testing的首字母缩写是FIRST:

  • 快速
  • 孤立
  • 重复
  • 自我validation
  • 及时

隔离是这个讨论的关键:你的testing不应该依赖于其他testing留下的任何以前的状态。 理想情况下,您应该拆除并重新创build您的内存核心数据堆栈,以便进行每项testing,所以您知道您是从一个干净的石板开始的。 格雷厄姆·李在这篇文章中是一个很好的例子。 你想使用内存栈,因为a)你可以很容易地把它扔掉,b)它应该是非常快的,因为它只是在内存中,而不是你的磁盘。

如果你发现你的testing运行缓慢(不要过早地优化),那么我认为合理的下一步就是在你的+ (void)setUp方法中创build栈,但是创build一个全新的上下文每次都在你的- (void)setUp方法中。

我来到这里几乎有同样的问题:如何在Swift中执行一次 setUp 。 这是解决scheme:

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

现在我仍然在寻找asynchronous setUp的解决scheme!