当我将应用程序从单线程转移到多线程时,我正在努力确保我的ObjC多线程实现是正确的。
现在,我已经设置了单元测试,以确保一切都能在单线程环境中正常工作。
我能做些什么来确保这在多线程中有效?我想继续使用单元测试,但不确定如何在单元测试中测试多线程。
澄清:我正在使用NSBlockOperation / NSOperationQueue实现多线程。
发布于 2011-07-28 06:55:45
简而言之,你不能。至少,你不能得到接近100%的测试覆盖率。对于线程,从并发I/O到内核计数,从内存压力到其他进程(或同一进程)中的活动,任何事情都会影响线程调度。
对于单元测试,您通常希望单元测试阻塞,直到线程化子系统完成它需要做的任何事情。通常,单元测试线程将异步产生需要完成的任何工作,然后阻塞,直到出现信号(线程类型的信号,而不是signal())。显然,有许多不同的方法可以做到这一点,并且许多细节将特定于您的应用程序;需要运行循环吗?使用GCD (希望如此)?等等……
发布于 2011-07-28 08:26:30
要测试这样的东西,您需要在测试中控制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];现在,对于测试,您可以创建一个简单的测试队列...它需要实现你的主题所使用的任何方法。
@interface MyTestOperationQueue: NSMutableArray {
}
@end
@implementation MySubject
-(void)addOperation:(NSOperation*)operation {
[self addObject:operation];
}
@end现在你的测试看起来是这样的:
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当然,这种测试不能验证并发操作是否可以安全地同时执行,但这可以涵盖许多您在尝试设计类时会感兴趣的情况。
https://stackoverflow.com/questions/6851629
复制相似问题