2011-07-27 8 views
4

단일 스레드에서 다중 스레드로 응용 프로그램을 전송할 때 ObjC 멀티 스레딩 구현이 적절한 지 확인하려고합니다.멀티 스레딩 테스트

지금은 단일 스레드 환경에서 모든 것이 제대로 작동하는지 단위 테스트를 설정했습니다.

이것을 멀티 스레드로 유지하려면 어떻게해야합니까? 단위 테스트에서 멀티 스레딩을 테스트하는 방법에 대해서는 확실하지 않지만 단위 테스트를 계속하고 싶습니다.

설명 : NSBlockOperation/NSOperationQueue를 사용하여 멀티 스레딩을 구현하고 있습니다.

답변

2

간단히 말해서, 당신은 할 수 없습니다. 적어도, 당신은 100 % 테스트 커버리지에 가깝지 않습니다. 스레드를 사용하면 동시 I/O에서 코어 수, 메모리 압 력, 다른 프로세스 (또는 동일한 프로세스)의 활동에 이르기까지 스레드 스케줄링에 영향을 미칩니다.

단위 테스트의 경우 일반적으로 단위 테스트는 스레드 된 하위 시스템이 수행해야 할 때까지 차단해야합니다. 유닛 테스트 스레드는 수행해야 할 작업을 비동기 적으로 생성 한 다음 신호가 발생할 때까지 차단합니다 (signal()이 아닌 thread 유형의 신호). 이 작업을 수행하는 데는 여러 가지 방법이 있으며 분명히 세부 정보 대부분이 앱에만 적용됩니다. 루프를 실행해야합니까? GCD 사용 (잘하면)? ...

+0

NSBlockOperation/NSOperationQueue를 사용하여 멀티 스레딩을 구현하고 있습니다. – David

+0

좋습니다. 스레드를 수동으로 생성하는 것은 최근에는 최적이 아닙니다. 그러나 코멘트는 여전히 유효하지만 동시 시스템에 대한 완전한 적용 범위를 얻는 것은 불가능하지만 전혀 테스트하지 않는 것보다 확실한 테스트를하는 것이 좋습니다! – bbum

3

이와 같이 테스트하려면 NSOperationQueue을 테스트하고 싶을 것입니다.

테스트 할 클래스가 MySubject이라고 가정합니다. 먼저, 리팩토링하여 NSOperationQueue을 삽입하여 테스트 용으로 대체 할 수 있도록해야합니다. 따라서 [NSOperationQueue mainQueue]의 모든 항목을 제거하고 클래스 변수로 바꾸십시오. MySubject의 생성자에있는 매개 변수에서 해당 클래스 변수를 초기화하십시오. 따라서 MySubject의 인스턴스를 모두 [NSOperationQueue mainQueue]으로 변경해야합니다.

@interface MySubject: NSObject { 
    NSOperationQueue* operationQueue; 
} 
@end 

@implementation MySubject 
-(MySubject*)initWithOperationQueue:(NSOperationQueue*)queue { 
    if (self = [super init]) { 
    self.operationQueue = [queue retain]; 
    } 
    return self; 
} 

-(void)dealloc { 
    [operationQueue release]; 
} 

-(void)startOperations { 
    [operationQueue addOperation:...]; 
    [operationQueue addOperation:...]; 
} 
@end 

그리고 클라이언트는 이제 다음과 같이 :

subject = [[MySubject alloc] initWithOperationQueue:[NSOperationQueue mainQueue]]; 
[subject startOperations]; 

이제 테스트를 위해, 당신은 테스트를위한 간단한 큐를 만들 수 있습니다 ... 그것은 당신의 주제에서 사용하는 어떤 방법을 구현해야합니다 .

물론
testQueue = [[MyTestOperationQueue alloc] init]; 
subject = [[MySubject alloc] initWithOperationQueue:testQueue]; 
[subject startOperations]; 

// You may want to have other tests that execute the queue operations 
// in a different order 
[[testQueue objectAtIndex:0] start]; 
[[testQueue objectAtIndex:0] waitUntilFinished]; 
[[testQueue objectAtIndex:1] start]; 
[[testQueue objectAtIndex:1] waitUntilFinished]; 

// Verify results 

, 시험의 종류는 동시 작업을 동시에 수행 할 안전하다는 것을 확인할 수는 없지만이 :

@interface MyTestOperationQueue: NSMutableArray { 
} 
@end 

@implementation MySubject 

-(void)addOperation:(NSOperation*)operation { 
    [self addObject:operation]; 
} 
@end 

그리고 이제 테스트 캔은 다음과 같습니다 수업을 디자인 할 때 관심을 가질만한 많은 사례를 다룰 수 있습니다.

+0

아. 작업이 동시에 수행되는 것이 안전한지 여부를 테스트하는 것이 더 재미있었습니다. 메모리 오류 등은 없습니다. 이것은 좋은 생각입니다. 그러나 MySubject의 작업을 직접 호출하는 것이 더 간단 해 보입니다. 가능하게 그것들을'init'에서 블록 변수에 할당함으로써 가능할 것입니다. 이것은 불편한 것 같습니다. 어쨌든 좋은 정보. – David