在Xcode 6中使用XCTest进行sortingunit testing

我想知道是否有任何方式告诉Xcode以指定的顺序运行unit testing。 我的意思是不在同一个XCTestCase类文件中,而是在所有的类文件之间。

在这里输入图像说明

例如,我想在运行SitchozrSDKMessageTest之前运行SitchozrSDKSessionTest。

我查看了堆栈或Apple文档上的几个线程,但是我没有find有用的东西。

谢谢你的帮助。

它都按字母顺序排列(类和方法)。 所以当你需要一些最后运行的testing时,只需改变Class或Method的名字(对于(讨厌的)例子来说,前缀'z_')。

所以…你有类名:

 MyAppTest1 -testMethodA -testMethodB MyAppTest2 -testMethodC -testMethodD 

他们按这个顺序运行。 如果您需要运行MyAppTest1作为第二,只需重命名,以便它的名称是在MyAppTest2(z_MyAppTest1)后按字母顺序,它将运行(方法相同):

 MyAppTest2 -a_testMethodD -testMethodC z_MyAppTest1 -testMethodA -testMethodB 

也请以命名为例:)

的确,目前(从Xcode 7开始),XCTestCase方法按字母顺序运行,所以您可以通过巧妙命名来强制执行命令。 但是,这是一个实现细节,似乎可以改变。

(希望)不太脆弱的方法是重写+[XCTestCase testInvocations]并按照您想要testing的顺序返回自己的NSInvocation对象。

就像是:

 + (NSArray *)testInvocations { NSArray *selectorStrings = @[@"testFirstThing", @"testSecondThing", @"testAnotherThing", @"testLastThing"]; NSMutableArray *result = [NSMutableArray array]; for (NSString *selectorString in selectorStrings) { SEL selector = NSSelectorFromString(selectorString); NSMethodSignature *methodSignature = [self instanceMethodSignatureForSelector:selector]; NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature]; invocation.selector = selector; [result addObject:invocation]; } return result; } 

当然,这里的缺点是你必须手动添加每个testing方法,而不是自动拾取。 有几种方法可以改善这种情况。 如果你只需要定义一些你的testing方法,而不是所有的testing方法,那么你可以通过调用super来过滤掉你手动定义的那些方法,然后把剩下的方法加到最后你返回的数组 如果您需要订购所有的testing方法,您仍然可以调用super的结果,并validation所有自动提取的方法是由您手动创build的有序结果覆盖的。 如果没有,你可以断言,如果你忘记添加任何方法导致失败。

我不考虑写testing是否“正确”,而testing必须按照一定的顺序进行。 我认为有一些罕见的情况是有道理的,但也有人可能不同意。

其按函数名字顺序排列,无论您如何在代码中sorting都无关紧要。 例如:

 -(void)testCFun(){}; -(void)testB2Fun(){}; -(void)testB1Fun(){}; 

实际的执行顺序是:

  1. 调用testB1Fun
  2. testB2Fun调用
  3. 调用testCFun

除了安德鲁 – 马德森的回答:
我创build了一个“智能” testInvocations类方法,它search以“test”开头的select器并按字母顺序sorting。
所以你不必分别维护一个NSArray的select器名称。

 #import <objc/runtime.h> + (NSArray <NSInvocation *> *)testInvocations { // Get the selectors of this class unsigned int mc = 0; Method *mlist = class_copyMethodList(self.class, &mc); NSMutableArray *selectorNames = [NSMutableArray array]; for (int i = 0; i < mc; i++) { NSString *name = [NSString stringWithFormat:@"%s", sel_getName(method_getName(mlist[i]))]; if (name.length > 4 && [[name substringToIndex:4] isEqualToString:@"test"]) { [selectorNames addObject:name]; } } // Sort them alphabetically [selectorNames sortUsingComparator:^NSComparisonResult(NSString * _Nonnull sel1, NSString * _Nonnull sel2) { return [sel1 compare:sel2]; }]; // Build the NSArray with NSInvocations NSMutableArray *result = [NSMutableArray array]; for (NSString *selectorString in selectorNames) { SEL selector = NSSelectorFromString(selectorString); NSMethodSignature *methodSignature = [self instanceMethodSignatureForSelector:selector]; NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature]; invocation.selector = selector; [result addObject:invocation]; } return result; } 

脚注:这是不好的做法,使你的unit testing依赖于彼此

举个例子,你可以像这样重命名项目中的testing文件:

 SitchozrSDKSessionTest -> t001_SitchozrSDKSessionTest SitchozrSDKMessageTest -> t002_SitchozrSDKMessageTest 

Xcode使用字母顺序处理文件。

OP没有提到CI是否可用或命令行答案是否足够。 在这些情况下,我喜欢使用xctool [1]。 它具有运行testing的语法,只需要一个testing方法:

 path/to/xctool.sh \ -workspace YourWorkspace.xcworkspace \ -scheme YourScheme \ test -only SomeTestTarget:SomeTestClass/testSomeMethod 

我会这样做,以确保我们testing我们认为最容易的项目。

1. [] facebook / xctool:取代Apple的xcodebuild,可以更轻松地构build和testingiOS或OSX应用程序。 ; ; https://github.com/facebook/xctool

由于Xcode 7,XCTestCase子类按字母顺序排列。 如果要确保testing方法本身也按字母顺序运行,则必须重写testInvocations类方法并返回按select器sorting的调用。

 @interface MyTestCase : XCTestCase @end @implementation MyTestCase + (NSArray<NSInvocation *> *) testInvocations { return [[super testInvocations] sortedArrayUsingComparator:^NSComparisonResult(NSInvocation *invocation1, NSInvocation *invocation2) { return [NSStringFromSelector(invocation1.selector) compare:NSStringFromSelector(invocation2.selector)]; }]; } - (void) test_01 { } - (void) test_02 { } @end