test method
- @isTest
Executes the given body with a bunch of parameters, trying to break it.
Implementation
@isTest
void test(
String description,
Tester<T> body, {
String? testOn,
test_package.Timeout? timeout,
dynamic skip,
dynamic tags,
Map<String, dynamic>? onPlatform,
int? retry,
}) {
final stats = Statistics();
/// Explores the input space for inputs that break the property. This works
/// by gradually increasing the size. Returns the first value where the
/// property is broken or null if no value was found.
Future<Shrinkable<T>?> explorePhase() async {
var count = 0;
var size = explore.initialSize;
while (count < explore.numRuns) {
stats.exploreCounter++;
final input = generator(explore.random, size.ceil());
if (!await succeeds(body, input.value)) {
return input;
}
count++;
size += explore.speed;
}
return null;
}
/// Shrinks the given value repeatedly. Returns the shrunk input.
Future<T> shrinkPhase(Shrinkable<T> initialErrorInducingInput) async {
var input = initialErrorInducingInput;
outer:
while (true) {
for (final shrunkInput in input.shrink()) {
stats.shrinkCounter++;
if (!await succeeds(body, shrunkInput.value)) {
input = shrunkInput;
continue outer;
}
}
break;
}
return input.value;
}
test_package.test(
'$description (testing ${explore.numRuns} '
'${explore.numRuns == 1 ? 'input' : 'inputs'})',
() async {
final errorInducingInput = await explorePhase();
if (errorInducingInput == null) return;
final shrunkInput = await shrinkPhase(errorInducingInput);
print('Tested ${stats.exploreCounter} '
'${stats.exploreCounter == 1 ? 'input' : 'inputs'}, shrunk '
'${stats.shrinkCounter} ${stats.shrinkCounter == 1 ? 'time' : 'times'}.'
'\nFailing for input: $shrunkInput');
final output = body(shrunkInput); // This should fail the test again.
throw PropertyTestNotDeterministic(shrunkInput, output);
},
testOn: testOn,
timeout: timeout,
skip: skip,
tags: tags,
onPlatform: onPlatform,
retry: retry,
);
}