XCTestCase的意外行为 - 创建不同的实例来运行测试方法

时间:2014-02-08 03:30:05

标签: unit-testing xunit xctest

我用XCTestCase编写单元测试用例,并在-setUp中初始化变量如下:

- (void)setUp {
    [super setUp];
    // Put setup code here. This method is called before the invocation of each test method in the class.
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _myPath = @"Path";
    });
}

但是当我尝试在测试用例中使用myPath时,它只适用于第一个,并且“myPath”在后续情况下将为nil。

所以我在-setUp中设置了断点,看看发生了什么。我发现它为每种方法创建了新实例!!

要仔细检查,我创建一个新项目和测试目标,以记录测试用例地址,如下所示:

@implementation fooTestTests
- (void)setUp
{
    [super setUp];
    // Put setup code here. This method is called before the invocation of each test method in the class.
    NSLog(@"<fooTestTests: %p>", self);
}

- (void)tearDown
{
    // Put teardown code here. This method is called after the invocation of each test method in the class.
    [super tearDown];
}

- (void)testExample
{
    XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__);
}

- (void)testExample2
{
    XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__);
}
@end

结果是:

fooTest[846:303] <fooTestTests: 0x1005ab750>
fooTest[846:303] <fooTestTests: 0x1005ab7f0>

由于XCTestCase被设计为具有一个或多个测试方法的对象,因此不应为每个方法创建不同的实例。

在这种情况下,我不知道在哪里设置我的测试环境。即使在-init中编写设置代码,它仍然会创建新实例并多次调用-init。目前,我只进行了一些单元测试,但是当测试数量增加,并且设置过程变得更加复杂时,这将是一个问题。有人能给我一个建议吗?

添加问题摘要:

如果我在一个测试用例类中有2个测试方法,则行为为:

  1. 将新测试用例实例化为对象1
  2. -SETUP
  3. test 1
  4. -tearDown
  5. 将新测试用例设为对象2
  6. -SETUP
  7. test 2
  8. -tearDown
  9. 为什么需要第5步?

    答案

    Jon Reid

    提供的答案

    更多信息:

1 个答案:

答案 0 :(得分:3)

要运行单个测试,这是xUnit测试框架的常规模式,包括XCTest:

  1. 实例化新测试对象
  2. 调用-setUp
  3. 调用测试方法
  4. 调用-tearDown
  5. 结束一次测试。测试对象本身将在我们控制之外的某个时间被销毁。

    因此,请勿将-init-dealloc与测试对象一起使用。而是使用保证在每次测试之前和之后调用的-setUp-tearDown。但是每个测试都在一个全新的对象实例上运行。这有助于保持测试的隔离。

    所以摆脱你的dispatch_once