繁体   English   中英

在Xcode 6中使用XCTest进行订购单元测试

[英]Ordering unit test using XCTest in Xcode 6

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

在此输入图像描述

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

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

谢谢你的帮助。

它按字母顺序排序(类和方法)。 因此,当您需要最后运行的某些测试时,只需更改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]并按照您希望测试运行的顺序返回您自己的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;
}

当然,这里的缺点是你必须手动添加每个测试方法,而不是自动拾取它们。 有几种方法可以改善这种情况。 如果你只需要在你的+testInvocations覆盖中订购一些测试方法,而不是所有测试方法,你可以调用super,过滤掉你手动订购的那些方法,然后将其余部分添加到最后你返回的数组。 如果您需要订购所有测试方法,您仍然可以获得调用super的结果,并验证手动创建的有序结果是否涵盖了所有自动拾取的方法。 如果没有,您可以断言,如果您忘记添加任何方法,则会导致失败。

我不讨论编写必须以特定顺序运行的测试是否“正确”的讨论。 我认为很少有这种情况有意义,但其他人可能不同意。

按函数名称字母顺序排序,无论你如何在代码中订购它。 例如:

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

实际的执行顺序是:

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

除了安德鲁 - 马德森的回答:
我创建了一个'智能' testInvocations类方法,该方法搜索以“test”开头的选择器并按字母顺序对它们进行排序。
因此,您不必单独维护选择器名称的NSArray

#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;
}

脚注:认为单元测试依赖于彼此是不好的做法

例如,您可以像这样重命名项目中的测试文件:

SitchozrSDKSessionTest -> t001_SitchozrSDKSessionTest
SitchozrSDKMessageTest -> t002_SitchozrSDKMessageTest

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

从Xcode 7开始,XCTestCase子类按字母顺序排列。 如果要确保测试方法本身也按字母顺序运行,则必须覆盖testInvocations类方法并返回按选择器排序的调用。

@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

OP未提及CI是否可用或命令行答案是否足够。 在那些情况下,我很喜欢使用xctool [1]。 它具有将测试运行到一个测试方法的语法:

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

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

1. [] facebook / xctool:Apple xcodebuild的替代品,可以更轻松地构建和测试iOS或OSX应用程序。 ; ; https://github.com/facebook/xctool

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM