【问题标题】:Conditional unit testing based on iOS version基于iOS版本的条件单元测试
【发布时间】:2013-10-23 03:16:00
【问题描述】:

我的单元测试套件包含一些仅适用于最新 iOS 版本的测试用例。预计这些测试会在旧 iOS 版本上运行该套件时失败。

是否有标准的方式表明这些测试用例应该只在特定的 iOS 版本上运行?

我想到的一个选项:

- (void) testSomethingThatOnlyWorksOniOS7
{
    const BOOL iOS7OrHigher = floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1;
    if (!iOS7OrHigher) return;

    // Actual test goes here
}

或者,我可以告诉SenTestCase 动态跳过某些测试吗?

【问题讨论】:

    标签: ios objective-c unit-testing ocunit sentestingkit


    【解决方案1】:

    我尝试按照@sergio 的建议使用 OCUnit,但我走不远。到目前为止,我正在使用宏注释特定于版本的测试。它看起来像这样:

    #define SKIP_IF_VERSION(v) if (floor(NSFoundationVersionNumber) <= v) return;
    
    - (void)testSomethingThatOnlyWorksOniOS7
    { SKIP_IF_VERSION(NSFoundationVersionNumber_iOS_6_1)
    // Test goes here
    }
    

    我不喜欢这种方法的一点是,测试无论如何都会运行(并且什么都不做)。我希望完全跳过测试。

    【讨论】:

      【解决方案2】:

      我觉得你的方法很好。

      一般来说,我不认为有一种“标准方式”可以根据 iOS 版本选择性地执行单元测试。

      一方面,您的方法是相同的,可用于根据 iOS 版本有选择地或以不同方式实现一项功能。可能您已经知道关于 CocoaWithLove 的讨论:Tips and Tricks from conditional...。它已经很老了,但这里描述的方法仍然存在。

      您没有指定执行单元测试的方式,但处理此问题的真正酷方法是,IMO,能够指定在实现之外执行哪些测试,以便您说明哪些测试适用于仅限 iOS7,不会污染您的测试实现。

      这可以做到,例如,通过与每个测试关联的版本号;在调用单元测试实现之前,您检查函数调用中的版本号,例如,testSomethingThatOnlyWorksOniOS7

      编辑:

      实际上,事情可能比我最初想的要容易。现在我有点 hacky...

      您可以修改 OCUnit 中实际测试方法调用完成的位置(不知道这一点,抱歉,但我认为这应该不难找到...),以便它检查选择器名称:您将选择器名称转换为字符串 (NSStringFromSelector),如果它与某个正则表达式匹配,您将采用一些特定的分支(在您的情况下,忽略该测试)。

      If you are worried by modifying OCUnit, which might not be sensible, what I said above could be done through method swizzling: only if the selector name does not match your expression, you call the original implementation, otherwise do nothing.

      【讨论】:

      • "以便您声明哪些仅适用于 iOS7,并且不会污染您的测试实现。"是的,我希望能找到一些晦涩难懂的 OCUnit 功能,让我能够做到这一点。 :)
      • 我不知道任何...但我刚刚在我的答案中添加了一些想法...看起来并不难做到...
      • 也许覆盖 defaultTestSuite 可以工作。值得一试。
      【解决方案3】:

      没有标准的方法来做这件事,一般来说测试不是 iOS 社区谈论太多的事情。 我解决这个问题的方法是将特定的 iOS7 测试单独放在测试目标上,然后基本上决定相应地运行该套件

      【讨论】:

      • “一般来说,iOS 社区不会过多谈论测试”:这就是为什么值得在 SO 上提出这些问题。 ;)
      • 对不起,我不是故意的。是为了强调一个事实,即没有“行业标准”,或者至少是我所知道的。
      • 不用说对不起。我不知道谁对你投了反对票,但我只是为了补偿而投了赞成票。 :) 另外,我认为目标方法是一个可行的解决方案,尽管有点麻烦。
      • +1 我认为目标也是我这样做的方式:为每个必要的 iOS 版本设置一个目标,并使用 聚合目标 来允许运行测试一个动作。使用 Xcode 5 机器人,您可以让 iOS 6 测试目标在 iOS 6 设备等上运行。
      【解决方案4】:

      最好的方法是在您知道仅在 iOS 7 上可用的方法上运行 respondsToSelector:。例如

      [view respondsToSelector:@selector(snapshotViewAfterScreenUpdates:)]
      

      [UIView instancesRespondToSelector:@selector(snapshotViewAfterScreenUpdates:)]
      

      【讨论】:

      • 使用 respondsToSelector: 是最好的解决方案,因为它是未来的证明。 Apple 可以在以后随时删除方法,在这种情况下版本号检查失败。
      • 在这种情况下不是。我想明确标记测试不应该在 iOS 7 上运行。这不是应用程序代码。这是测试代码。
      • 您仍然可以在测试中运行该代码并在测试方法开始时返回。
      猜你喜欢
      • 1970-01-01
      • 2014-08-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多