2013-10-15 35 views
6

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

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

一种选择我想过:

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

    // Actual test goes here 
} 

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

回答

4

你的做法似乎没什么问题。

一般来说,我认为没有像“标准方式”那样有选择地执行基于iOS版本的单元测试。

一方面,您的方法是相同的,可以根据iOS版本选择性地或以不同方式实现一个功能。可能你已经知道关于CocoaWithLove的讨论:Tips and Tricks from conditional...。这很旧,但这里描述的方法仍然保持不变。

你没有指定你的单元测试的执行方式,但是真正的很酷的方式来处理这个IMO,将能够指定在执行之外执行哪些测试,以便声明哪些测试是仅适用于iOS7,并且不会污染您的测试实施。

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

编辑:

事实上,事情可能会更容易的是什么,我首先想到。现在我要去修改一下...

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

如果您担心修改OCUnit(这可能不明智),我上面所说的可以通过方法调整完成:只有当选择器名称与您的表达式不匹配时,才会调用原始实现,否则什么也不做。

+0

“,以便您声明哪些仅适用于iOS7,并且不会污染您的测试实施。”是的,我希望找到一些令人尴尬的OCUnit功能,使我能够做到这一点。 :) – hpique

+0

我不知道任何...但我刚刚给我的答案添加了一些想法...看起来并不难... – sergio

+0

也许重写'defaultTestSuite'可以工作。值得检查。 – hpique

3

最好的方法是运行respondsToSelector:上的方法,你知道只有iOS 7上可用。

[view respondsToSelector:@selector(snapshotViewAfterScreenUpdates:)] 

[UIView instancesRespondToSelector:@selector(snapshotViewAfterScreenUpdates:)] 
+1

使用respondsToSelector:是最好的解决方案,因为它是未来的证明。 Apple可以在将来随时删除一个方法,并且在这种情况下版本号检查失败。 –

+0

不是这种情况。我想明确指出测试不应该在iOS 7上运行。这不是应用程序代码。这是测试代码。 – hpique

+0

您仍然可以在测试中运行该代码,并在测试方法开始时返回。 –

1

这样做并没有一个标准的方式,一般来说测试不是iOS社区谈论得太多。 我会这样做的方式是将特定的iOS7测试自己放在测试目标上,然后基本上决定相应地运行该套件

+2

“,并且一般来说测试不是iOS社区谈论得太多”:这就是为什么值得在SO上提出这些问题的原因。 ;) – hpique

+0

对不起,我不是故意抱怨。应该强调一个事实,即没有“行业标准”,或者至少有一个我知道。 – cescofry

+0

不需要说抱歉。我不知道谁低估了你,但我只是提出了补偿。 :)另外,我认为目标方法是一个可行的解决方案,尽管有点麻烦。 – hpique

0

我试着用@sergio建议玩OCUnit,但是我无法走远远。到目前为止,我正在用一个宏注释特定于版本的测试。它看起来像这样:

#define SKIP_IF_VERSION(v) if (floor(NSFoundationVersionNumber) <= v) return; 

- (void)testSomethingThatOnlyWorksOniOS7 
{ SKIP_IF_VERSION(NSFoundationVersionNumber_iOS_6_1) 
// Test goes here 
} 

我不喜欢这种方法是测试无论如何运行(并且什么都不做)。我宁愿将测试完全跳过。