Edited at

テストコードの書き方、

More than 1 year has passed since last update.


テストコードの良い書き方。

テストコードで得られる情報は非常に重要であり、テストコードを書くことにより、そのシステムの品質が上がります。

しかしテストコードの書き方を複雑に書き過ぎると、良いテストコードとは言えません。

下記に記したものは、 ユニークでランダムな数値の配列を作成する関数と、そのランダムな配列がユニークかつ、ランダムになってるかのテストである、

/*

* Create ordered array
*
*/
-(NSMutableArray*)insertNumber:(NSInteger)number{
NSMutableArray* array = [NSMutableArray array];
for(NSInteger i = 0; i<number;i++){
[array addObject:[NSNumber numberWithInteger:i]];
}
return array;
}

/*
* create Random Array
*/
-(NSArray *)randomArray:(NSArray *)array{
NSMutableArray* ary = array.mutableCopy;
for(NSInteger n = 0; n < array.count;n++){
NSInteger random = arc4random() % array.count;
[ary exchangeObjectAtIndex:n withObjectAtIndex:random];
}
return ary.mutableCopy;
}

/*
*
* TEST CODE
*
*/
-(void)TEST{

__block NSInteger num = 0;
__block BOOL isBUSTED = NO;

for(;num<TEST_COUNT_NUMBER;){

__block NSArray* random = [self randomArray:[self insertNumber:3]];

[self TESTCODE:random TESTVal:^(NSInteger i, NSInteger n,NSInteger same) {

if([random[i]integerValue] == [random[n]integerValue]){
same++;
if(same==2){
isBUSTED = YES;

}
}

if(isBUSTED)
printf("\n BUSTED Failuer \n");

if(i>=(random.count-1) && n>=(random.count-1)){
num++;
printf("COMPLETION %ld TIME TEST\n",num);
}
}];

}
printf("\nCompletion\n\n");
}

/*
* TEST CODE
*
*/
-(void)TESTCODE:(NSArray*)ary
TESTVal:(void (^)(NSInteger i,NSInteger n,NSInteger same))handler{

NSInteger count = 0;

for(NSInteger i=0;i<ary.count;i++){
count = 0;
for(NSInteger n = 0;n<ary.count;n++){
handler(i,n,count);
}
}
}

main.m

#import <Foundation/Foundation.h>

#import "Random.h"

int main(int argc, const char * argv[]) {
@autoreleasepool {
[[Random new]TEST];
}
return 0;
}

このテストコードは最悪である、まずわかりづらい、複雑であり解析が容易ではなく、そしてバグの温床になるコードで拡張性が低いと言えると思われる。

このようなテストコードは書くべきでない、

こちらのコードをリファクタリングしたものが下記である。


/*
*
* TEST CODE
*
*/
-(BOOL) TEST_RANDOM:(NSArray*)ary {
BOOL isUnique = NO;
for(NSInteger base = 0; base < ary.count; base++){
int count = 0;
for(NSInteger locate = 0; locate < ary.count; locate++ ){
if([ary[base]integerValue]==[ary[locate]integerValue]){
count++;
if(count==2){
isUnique = YES;
}
}
}
}
return isUnique;
}

/*
* New TEST CODE
*
*/
-(void) TEST_RANDOM {

for ( NSInteger num = 0; num < TEST_COUNT_NUMBER; num++ ){

NSArray* numbers = [self insertNumber:30];

NSArray* randoms = [self randomArray:numbers];

if( [self TEST_RANDOM:randoms] == YES ){

NSLog(@"Failuer Not unique and Random");

}
}
}

こちらのテストコードはわかりやすくかかれてるといえる、

配列内の数値を全て走査しユニークかのテストを行なっている。

この書き方だと、拡張性が高く、管理がしやすく、何が書いてあるのか一目瞭然である。

今回の記事で使ったコードは下記に記しておきました。

https://gist.github.com/keisukeYamagishi/331ae9f09d4ea5314bdc12ea3125f2b8

以上