Xcodeにユニットテストを指定された順序で実行するように指示する方法があるかどうか知りたいのですが。つまり、同じXCTestCaseクラスファイルではなく、すべてのクラスファイル間です。
たとえば、SitchozrSDKMessageTestを実行する前にSitchozrSDKSessionTestを実行したいと思います。
スタックまたはAppleドキュメントでいくつかのスレッドを調べましたが、役立つものは見つかりませんでした。
ご協力いただきありがとうございます。
すべてがアルファベット順にソートされています(クラスとメソッド)。したがって、最後に実行するテストが必要な場合は、クラスまたはメソッドの名前を変更します((厄介な)例の場合は、「z_」のプレフィックスを付けます)。
だから...あなたはクラス名を持っています:
MyAppTest1
-testMethodA
-testMethodB
MyAppTest2
-testMethodC
-testMethodD
そして、この順序で実行されます。 MyAppTest1を2番目として実行する必要がある場合は、名前を変更して、名前が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
のオーバーライドで、すべてのテストメソッドではなくsomeのテストメソッドのみを注文する必要がある場合は、superに呼び出し、手動で行ったメソッドを除外できます。注文してから、残りを配列の最後に貼り付けます。すべてのテストメソッドを注文する必要がある場合でも、superへの呼び出しの結果を取得し、自動的に取得されたすべてのメソッドが手動で作成された注文結果でカバーされていることを確認できます。そうでない場合は、アサートすることができ、メソッドの追加を忘れた場合は失敗します。
特定の順序で実行する必要のあるテストを作成することが「正しい」かどうかについては、議論を省きます。それが理にかなっているまれなシナリオはあると思いますが、他の人は反対するかもしれません。
関数名での順序は文字の順序であり、コード内での順序は関係ありません。例えば。:
-(void)testCFun(){};
-(void)testB2Fun(){};
-(void)testB1Fun(){};
実際の実行順序は次のとおりです。
andrew-madsen の回答に加えて:
「スマート」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:iOSまたはOSXアプリのビルドとテストを容易にするAppleのxcodebuildの代替品。 ; ; https://github.com/facebook/xctool