テストコードの良い書き方。
テストコードで得られる情報は非常に重要であり、テストコードを書くことにより、そのシステムの品質が上がります。
しかしテストコードの書き方を複雑に書き過ぎると、良いテストコードとは言えません。
下記に記したものは、 ユニークでランダムな数値の配列を作成する関数と、そのランダムな配列がユニークかつ、ランダムになってるかのテストである、
/*
* 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");
}
}
}
こちらのテストコードはわかりやすくかかれてるといえる、
配列内の数値を全て走査しユニークかのテストを行なっている。
この書き方だと、拡張性が高く、管理がしやすく、何が書いてあるのか一目瞭然である。
今回の記事で使ったコードは下記に記しておきました。
以上