Objective-C 和 Swift 的基于属性的测试。软件测试的自动生成。
您可能通过各种测试框架和/或库的各个流派听说过这个或类似的技术
Fox 是测试.check 对 Objective-C 的移植。与某些 QuickCheck 的移植不同,Fox 实现了缩小(test.check 同样实现这一点)。
测试生成可以提供比基于示例测试更好的覆盖率。您无需手动编写测试用例,Fox 可以为您生成测试。
测试生成的最简单方法是提供随机数据。如果您可以定义规范(测试对象的已知属性),Fox 可以生成这些数据供使用。
FOXAssert(FOXForAll(FOXTuple(FOXInteger(), FOXInteger()), ^BOOL(NSArray *values){
NSInteger x = [tuple[0] integerValue];
NSInteger y = [tuple[1] integerValue];
return x + y > x;
});
一旦产生失败的示例,Fox 将尝试找到最小的示例,它也表现出相同的失败
Property failed with: @[@0, @0].
如何测试有状态的 API?将有状态变化表示为数据!使用状态机,定义您的 API 应如何工作的模式。这是一个队列的示例
// define a state machine. Model state is the state of your application and
// can be represented with any object you want -- Fox does not interpret it.
FOXFiniteStateMachine *stateMachine = [[FOXFiniteStateMachine alloc] initWithInitialModelState:@[]];
// Adds a transition to the state machine:
// - The API to test is -[addObject:]
// - The generator for the argument is a random integer in an NSNumber
// - A block indicating how to update the model state. This should not mutate the original model state.
[stateMachine addTransition:[FOXTransition byCallingSelector:@selector(addObject:)
withGenerator:FOXInteger()
nextModelState:^id(NSArray *modelState, id generatedValue) {
return [modelState arrayByAddingObject:generatedValue];
}]];
// Add a custom transition (see FOXStateTransition protocol)
[stateMachine addTransition:[[QueueRemoveTransition alloc] init]];
现在,您可以生成测试,以测试 API
// Generate a sequence of commands executed on the given subject. Since
// this will generate multiple tests, you also give a block of a subject.
id<FOXGenerator> executedCommands = FOXExecuteCommands(stateMachine, ^id {
return [FOXQueue new];
});
// Verify if the executed commands validated the API conformed to the state machine.
FOXRunnerResult *result = [FOXSpecHelper resultForAll:executedCommands
then:^BOOL(NSArray *commands) {
return FOXExecutedSuccessfully(commands);
}];
// result will shrinking to the small sequence of API calls to trigger the
// failure if there is one
有关更多信息,请参阅 文档。
Fox 可以以多种方式安装。如果没有偏好的话,建议使用 git submodule 安装。
Fox 尽可能地遵守 语义版本控制。如果您不确定给定更新是否与您的使用向后不兼容,请查看 发布。
将 Fox 添加到您的项目作为子模块
$ git submodule add https://github.com/jeffh/Fox.git Externals/Fox
如果您不想使用最新版本,请检出特定版本的标签
$ cd Externals/Fox
$ git checkout v1.0.1
将 Fox.xcodeproj
添加到您的 Xcode 项目(不是 Fox.xcworkspace
)。然后将 Fox-iOS 或 Fox-OSX 链接到您的测试目标。
现在,您已经设置完毕!通过遵循 教程 直接开始。
如需查看用法示例,请参阅完整参考。
提供了许多数据生成器用于生成数据。大多数这些生成器将数据量缩减到零
函数 | 生成 | 描述 |
---|---|---|
FOXInteger | NSNumber * | 生成随机整数 |
FOXPositiveInteger | NSNumber * | 生成随机零或正整数 |
FOXNegativeInteger | NSNumber * | 生成随机零或负整数 |
FOXStrictPositiveInteger | NSNumber * | 生成随机正整数(非零) |
FOXStrictNegativeInteger | NSNumber * | 生成随机负整数(非零) |
FOXChoose | NSNumber * | 生成给定范围内的随机整数(包括端点) |
FOXFloat | NSNumber * | 生成符合IEEE标准的随机浮点数。 |
FOXDouble | NSNumber * | 生成符合IEEE标准的随机双精度浮点数。 |
FOXDecimalNumber | NSNumber * | 生成随机小数。 |
FOXReturn | id | 总是返回给定的值。不会缩减 |
FOXTuple | NSArray * | 生成由生成值组成的随机固定大小的数组。生成的值顺序与提供的生成器顺序相同。 |
FOXTupleOfGenerators | NSArray * | 生成由生成值组成的随机固定大小的数组。生成的值顺序与提供的生成器顺序相同。 |
FOXArray | NSArray * | 生成由生成值组成的随机可变大小的数组。 |
FOXArrayOfSize | NSArray * | 生成由生成值组成的随机固定大小的数组。生成的值顺序与提供的生成器顺序相同。 |
FOXArrayOfSizeRange | NSArray * | 生成由生成值组成的随机可变大小的数组。数组大小在给定的范围内(包括端点)。 |
FOXDictionary | NSDictionary * | 生成由生成值组成的随机字典。键是提前已知的值。指定形式为@{<key>: <generator>} 。 |
FOXSet | NSSet * | 生成给定生成值组成的随机集合。 |
FOXCharacter | NSString * | 生成随机1个长度的字符串。可能包含不可打印的字符。 |
FOXAlphabetCharacter | NSString * | 生成随机1个长度的字符串。只生成字母。 |
FOXNumericCharacter | NSString * | 生成随机1个长度的字符串。只生成数字。 |
FOXAlphanumericCharacter | NSString * | 生成随机1个长度的字符串。只生成字母数字。 |
FOXAsciiCharacter | NSString * | 生成随机1个长度的字符串。只生成ascii字符。 |
FOXString | NSString * | 生成随机可变长度的字符串。可能包含不可打印的字符串。 |
FOXStringOfLength | NSString * | 生成随机固定长度的字符串。可能包含不可打印的字符串。 |
FOXStringOfLengthRange | NSString * | 在给定范围内生成随机长度的字符串(包括端点)。可能包含不可打印的字符串。 |
FOXAsciiString | NSString * | 生成随机可变长度的字符串。只生成ascii字符。 |
FOXAsciiStringOfLength | NSString * | 生成随机固定长度的字符串。只生成ascii字符。 |
FOXAsciiStringOfLengthRange | NSString * | 在给定范围内生成随机长度的字符串(包括端点)。只生成ascii字符。 |
FOXAlphabeticalString | NSString * | 生成随机可变长度的字符串。只生成字母。 |
FOXAlphabeticalStringOfLength | NSString * | 生成随机固定长度的字符串。只生成字母。 |
FOXAlphabeticalStringOfLengthRange | NSString * | 在给定范围内生成随机长度的字符串(包括端点)。只生成字母。 |
FOXAlphanumericalString | NSString * | 生成随机可变长度的字符串。只生成字母。 |
FOXAlphanumericalStringOfLength | NSString * | 生成随机固定长度的字符串。只生成字母数字。 |
FOXAlphanumericalStringOfLengthRange | NSString * | 在给定范围内生成随机长度的字符串(包括端点)。只生成字母数字。 |
FOXNumericalString | NSString * | 生成随机可变长度的字符串。只生成数字。 |
FOXNumericalStringOfLength | NSString * | 生成随机固定长度的字符串。只生成数字。 |
FOXNumericalStringOfLengthRange | NSString * | 在指定范围内(包含端点)生成随机长度字符串。仅生成数字字符。 |
FOXSimpleType | id | 生成随机简单类型。简单类型不与其他类型组合。可能不可打印。 |
FOXPrintableSimpleType | id | 生成随机简单类型。简单类型不与其他类型组合。确保可打印。 |
FOXCompositeType | id | 生成随机组合类型。组合类型与给定的生成器组合。 |
FOXAnyObject | id | 生成随机简单或组合类型。 |
FOXAnyPrintableObject | id | 生成随机可打印简单或组合类型。 |
您还可以在数据生成器之上组合一些计算工作。生成的生成器采用与原始生成器相同的收缩属性。
函数 | 描述 |
---|---|
FOXMap | 对每个生成的值应用一个块。 |
FOXBind | 对原始生成器生成的值应用一个块。 |
FOXResize | 用指定的大小覆盖给定生成器的size参数。防止收缩。 |
FOXOptional | 创建一个新的生成器,有25%的概率返回nil 而不是提供的生成值。 |
FOXFrequency | 根据概率分发到多个生成器之一。接受一个元组数组(长度为2的数组)- @[@[@probability_uint, generator]] 。收缩跟随所返回的生成器。 |
FOXSized | 将给定的块封装起来以创建生成器,它依赖于生成值时接收到的size提示。 |
FOXSuchThat | 如果生成的值满足给定的块,则返回每个生成的值。如果过滤器连续过滤超过10个值,则生成的生成器假定它已达到最大收缩。 |
FOXSuchThatWithMaxTries | 如果生成的值满足给定的块,则返回每个生成的值。如果在连续过滤超过给定最大尝试次数后,生成的生成器假定它已达到最大收缩。 |
FOXOneOf | 通过随机从生成器数组中选取来返回生成的值。收缩取决于选择的生成器。 |
FOXForAll | 使用块和生成器进行断言,并生成测试断言结果(FOXPropertyResult)。收缩测试给定生成器的较小值。 |
FOXForSome | 类似于FOXForAll,但允许断言块“跳过”可能无效的测试用例。 |
FOXCommands | 生成满足给定状态机的FOXCommands数组。 |
FOXExecuteCommands | 生成满足给定状态机的FOXExecutedCommands数组,并对主体执行。可以传递给FOXExecutedSuccessfully以验证主体是否符合状态机。 |