【问题标题】:SenTestingKit in Xcode 4: Asynchronous testing?Xcode 4 中的 SenTestingKit:异步测试?
【发布时间】:2011-05-31 16:15:22
【问题描述】:

我一直在寻找一种方法来使用 SenTestingKit 在我的客户端代码和我们的服务器之间进行一些集成测试。我没有运气。似乎一旦代码在方法中运行,对象就会被销毁。这意味着任何异步响应都不会调用选择器。

问题:

  1. 有没有办法让对象保持实例化,直到我认为合适的时候销毁它 - 即。测试完成后?
  2. 如果不是,我如何创建一个在测试完成之前阻塞(即同步执行)的类?

仅供参考,我正在运行一个我知道预期结果的测试服务器。

我已经在 Google 上进行了相当多的搜索,但还没有看到关于这一点的任何证据。我相信其他人也会感兴趣。

【问题讨论】:

  • 接受的答案可以被视为“过时”。有几个很好的新答案。可能要重新考虑?

标签: objective-c unit-testing ocunit


【解决方案1】:

您可以使用信号量等待异步方法完成。

- (void)testBlockMethod {
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);

    // Your block method eg. AFNetworking
    NSURL *url = [NSURL URLWithString:@"http://httpbin.org/ip"];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
        NSLog(@"IP Address: %@", [JSON valueForKeyPath:@"origin"]);
        STAssertNotNil(JSON, @"JSON not loaded");
        // Signal that block has completed
        dispatch_semaphore_signal(semaphore);
    } failure:nil];
    [operation start];

    // Run loop
    while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_NOW))
        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
                                 beforeDate:[NSDate dateWithTimeIntervalSinceNow:10]];
    dispatch_release(semaphore);

}

http://samwize.com/2012/10/03/sentestingkit-does-not-support-wait-for-blocks/

【讨论】:

  • 我完全按照你的代码做,但它从来没有在成功块内打印日志。
  • 在您考虑到您正在调用的代码可能不会在完成时发送信号量信号之前非常棒。
  • 对我来说也很完美。我在另一个 SO 线程上看到了 NSCondionalLocking 的使用,它不能很好地工作,因为它会锁定主线程并阻止 AFNetworking 调度成功/错误回调。
  • 如果你的循环和你的回调在同一个(主)线程上运行,那么像 __block BOOL finished = NO 这样的标志,然后在回调中将完成设置为 true 将起作用。回调和测试在主线程上序列化,因此信号量不需要 /need/,如下所示:mattconnolly.wordpress.com/2012/05/29/…
  • 实际上并不那么出色。有几个问题,这里是一个:运行循环仅在有事件或超时触发时返回。这意味着在最坏的情况下,即使委托发出信号量,但在该运行循环和模式上没有排队的事件 - while 循环仍将等待长达 10 秒,直到它再次检查信号量。另一个是,你不能有超时。不太适合测试...
【解决方案2】:

两种选择:

  • 切换到GHUnit,实际上包含了对等待异步事件的支持
  • 缩小测试的设计范围,以便您可以按原样测试事物。例如。测试您的控制器代码是否导致选择器被分离并运行,并(单独)测试该选择器是否完成了它应该做的事情。如果这两件事都有效,那么您可以确信您的控制器分离了正确的工作。

【讨论】:

  • 不幸的是,我正在测试的是 connect-encrypt-authenticate-getsomedata 过程,如果没有持久性来处理回调,它就无法分解。 SenTestingKit 似乎没有给我我需要的持久性。但我会看看 GHUnit。
  • GHUnit 似乎是最好的选择。 gabriel.github.com/gh-unit/_examples.html 的示例页面准确地显示了我需要测试的情况......是时候学习一个新工具了!
【解决方案3】:

【讨论】:

  • 猕猴桃看起来很有趣。它是否处理异步回调?
【解决方案4】:

这个项目https://github.com/hfossli/AGAsyncTestHelper有一个很方便的宏

WAIT_WHILE(<expression_to_evaluate>, <max_duration>);

哪个能让你这样写测试

- (void)testDoSomething {

    __block BOOL somethingIsDone = NO;

    [MyObject doSomethingAsyncThenRunCompletionBlockOnMainQueue:^{
        somethingIsDone = YES;
    }];

    WAIT_WHILE(!somethingIsDone, 1.0); 
    NSLog(@"This won't be reached until async job is done");
}

【讨论】:

    【解决方案5】:

    检查 SenTestingKitAsync 项目 - https://github.com/nxtbgthng/SenTestingKitAsync。相关博客在这里-http://www.objc.io/issue-2/async-testing.html

    【讨论】:

      猜你喜欢
      • 2014-09-02
      • 1970-01-01
      • 2011-03-22
      • 2011-05-22
      • 2012-06-13
      • 2018-08-02
      • 2011-10-24
      • 2014-12-16
      • 1970-01-01
      相关资源
      最近更新 更多