Skip to content

Commit

Permalink
Merge pull request #18 from DutchCodingCompany/feature/rework_v2
Browse files Browse the repository at this point in the history
✨ Rework v2
  • Loading branch information
Guldem authored Apr 21, 2024
2 parents ce147e2 + b7680c0 commit 225c655
Show file tree
Hide file tree
Showing 36 changed files with 1,737 additions and 2,613 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2021 Dutch Coding Company B.V.
Copyright (c) 2024 Dutch Coding Company B.V.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
302 changes: 172 additions & 130 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,158 +16,91 @@ and the Flutter guide for
Supercharge your Dart testing with **parameterized_test**! Built on top of the [dart test package](https://pub.dev/packages/test), this [JUnit ParameterizedTest](https://junit.org/junit5/docs/current/user-guide/#writing-tests-parameterized-tests) inspired package wrap around `group` and `test` to take your testing to the next level!

## Table of contents
* [Features](#features-)
* [Installation](#installation)
* [Usage](#usage)
* [Examples](#examples)
* [How it works](#how-it-works)
* [Additional information](#additional-information)
- [Features](#features-)
- [Installation](#installation-)
- [Usage](#usage-)
- [Examples](#examples-)
- [Additional information](#additional-information-)

## Features ✨

- ✅ Run a test multiple times based on provide parameter list.
-Uses [dart test package](https://pub.dev/packages/test) under the hood.
-Built on top of [dart test package](https://pub.dev/packages/test).
- ✅ Type cast test parameters used in the tests.
- ✅ Include test options for parameter_test.
- ✅ Include test options per parameters.
- ✅ Include test options per parameter.

- ❌ No CSV parsing is supported. Its only possible to use Lists with actual values.

## Installation
## Installation 🛠

```yaml
dev_dependencies:
parameterized_test: [latest-version]
```
## Usage
Instead of using `groups` or `test` you can now use `parameterizedTest` and supply it list of test parameters to use in the same test.
To specify the test body use `TestParametersX` that matches the same amount of test parameters for 1 test. For example when the test has 2 parameters `actual` and `expected` use `TestParameters2` for supplying the test body.
The package offers `TestParameters` classes up to 10 parameters. Instead of writing `TestParameters` completely it also possible to use `typedef`'s `p1`..`p10`.

## Examples

Example parameterizedTest with 1 parameter:

```dart
parameterizedTest(
'Number are less than 4 tests',
[
1,
2,
3,
],
p1((int number) {
final result = number < 4;
expect(result, true);
}),
);
```
## Usage ⚡️
Example parameterizedTest with 2 parameters:
Instead of creating a `group` test with multiple of the same `test` and different parameters, you can now use `parameterizedTest` and supply it list of test parameters to run the same test with multiple times.
Specifying a parameterized test is almost the same as normal test. It has all the same parameters as a normal test like: `skip` or `testOn` etc.
The only difference is that you need to provide a list of test values and a function that takes the same amount of arguments as the test values.

For example:
```dart
parameterizedTest(
'Amount of letters tests',
[
['kiwi', 4],
['apple', 5],
['banana', 6],
],
p2((String word, int length) {
expect(word.length, length);
}),
);
```

or

```dart
parameterizedTest2(
'Amount of letters tests',
'Fruit name matches length',
// List of values to test
[
// parameters for the test
['kiwi', 4],
['apple', 5],
['banana', 6],
['pineapple', 9],
],
(String word, int length) {
expect(word.length, length);
// Test function accepting the provided parameters
(String fruit, int length) {
expect(fruit.length, length);
},
);
```

Example parameterizedTest with extra test options for a value:

```dart
parameterizedTest(
'Amount of letters',
[
['kiwi', 4],
['apple', 5],
['banana', 6].withTestOptions(skip: true),
],
p2((String word, int length) {
expect(word.length, length);
}),
);
This `parameterizedTest` will create a `group` with 4 `test` inside it. Each test will run the test function with the provided parameters.
```

Example parameterizedTest with test enum values:

```dart
enum AwesomeEnum { such, woow, much, skill}
parameterizedTest(
'Doge enum tests',
AwesomeEnum.values,
p1((AwesomeEnum doge) {
final result = doge.name.length >= 4;
expect(result, true);
}),
);
- Fruit name matches length (group)
- [ 'kiwi', 4 ] (test)
- [ 'apple', 5 ] (test)
- [ 'banana', 6 ] (test)
- [ 'pineapple', 9 ] (test)
```
## How it works
There is also a `parameterizedGroup` which is basically the same as `parameterizedTest` but instead of creating a `group` that runs a `test` multiple times, it creates a `group` that runs a `group` multiple times.
Here you still need to provide a `test`. This can be useful if you want to have nested groups of tests.
Besides accepting a list of test values, you can also provide a `setUp` and `tearDown` function to run before and after each test.
`parameterized_test` is basically a wrapper that executes a `group` test and loops over the provide `List` of test values. Each set of values is cast to the specified type inside the body. Which is wrapped inside a `test`.
### Add test options to parameter 🔩
If you want to add test options to a specific parameter you can do so by using the `options` extension on `List`. This will allow you to add test options like `skip` or `testOn` to a specific parameter.
For example:
```dart
parameterizedTest(
'Amount of letters',
'Fruit name matches length',
// List of values to test
[
// parameters for the test
['kiwi', 4],
['apple', 5],
['apple', 5].options(skip: 'Apple is not ripe yet'),
['banana', 6],
['pineapple', 9],
],
p2((String word, int length) {
expect(word.length, length);
}),
// Test function accepting the provided parameters
(String fruit, int length) {
expect(fruit.length, length);
},
);
```

The above example roughly translates to:
```dart
group('Amount of letter', () {
final testValues = [
['kiwi', 4],
['apple', 5],
['banana', 6],
];
for (final testValue in testValues) {
test(testValue.toString(), () {
final String word = testValue[0] as String;
final int length = testValue[1] as int;
expect(word.length, length);
});
}
});
```
This will create a `group` with 4 `test` inside it. The second test will receive the provided test options and will be skipped in this case.

## Changing test description output
By default the test description contains the test value used within the tests. This can be override by using `customDescriptionBuilder`.
### Changing test description output 📝
By default, the test description contains the test value used within the tests. you can override this by using `customDescriptionBuilder`.

When normally running parameterized tests with description 'My parameterized test' and the values `[['first', 'second', true], ['third', 'fourth', false]]` the test description output looks something like this:
```
Expand All @@ -190,31 +123,140 @@ My parameterized test 🚀[2] My parameterized test: <<third|fourth|false>>

>Note: the first 'My parameterized test' is because parameterized tests make use of a group test. Most IDE's will group this for you and only show the second part.
## Extending parameters
## Examples 📦
### Simple test containing a list of single values
```dart
parameterizedTest(
'Example of list of single values',
[
1,
2,
3,
],
(int value) {
final result = value < 4;
expect(result, true);
},
);
```

Currently the package supports `TestParameters` classes up to 10 arguments. If need to more arguments within a test than this is possible by implementing the `TestParameters` class.
### Simple test containing a list of multiple values
```dart
parameterizedTest('Example of list of multiple values', [
[0, 1, 1],
[1, 1, 2],
[1, 2, 3],
[2, 2, 4],
], (int value1, int value2, int sum) {
expect(value1 + value2, sum);
});
```
### Test containing a list with complex objects
```dart
parameterizedTest('Example of a list with complex object', [
[DateTime(2024, 4, 12), 5],
[DateTime(1969, 07, 20), 7],
], (DateTime dateTime, int expectedWeekday) {
expect(dateTime.weekday, expectedWeekday);
});
```

For example:
### Test containing a list of enums
```dart
class MyParameters<A1, A2> implements TestParameters {
const MyParameters(this.body);
enum TestEnum {
one(3),
two(3),
three(5);
@override
final dynamic Function(A1, A2) body;
const TestEnum(this.myLength);
@override
final int count = 2;
final int myLength;
}
@override
dynamic mapBody<R>(Iterable<R> values) {
final A1 a1 = values.elementAt(0) as A1;
final A2 a2 = values.elementAt(1) as A2;
return body(a1, a2);
}
parameterizedTest(
'Example using enum as value',
TestEnum.values,
(TestEnum testEnum) {
expect(testEnum.name.length, testEnum.myLength);
},
);
```
### Test retreiving the list of values from a function
```dart
List<dynamic> provideData() {
return [
[0, 1, 1],
[1, 1, 2],
[1, 2, 3],
[2, 2, 4],
];
}
parameterizedTest(
'Example of list of values from function',
provideData(),
(int value1, int value2, int sum) {
expect(value1 + value2, sum);
},
);
```

### Simple test with setup and teardown
```dart
parameterizedTest(
'Example with setup and teardown ',
[
['kiwi', 4],
['apple', 5],
['banana', 6],
],
(String word, int length) {
expect(word.length, length);
},
setUp: () {
print('Setup everything I need for testing');
},
tearDown: () {
print('tear it down again');
},
);
```

### Test which is an async test
```dart
parameterizedTest(
'Example using a async test',
[
100,
200,
300,
],
(int value) async {
final millis = DateTime.now().millisecondsSinceEpoch;
await Future<void>.delayed(Duration(milliseconds: value));
final passed = DateTime.now().millisecondsSinceEpoch - millis;
expect(passed >= value, true);
},
);
```
> Note: This is a example test to showcase async tests are also possible.
> But this is not a good practice to use a delay like
> this in a test. Running this test will take longer. This could be
> fixed by using a package like [fake_async](https://pub.dev/packages/fake_async).
### Test with CSV data
Its also possible to combine parameterizedTest for example with the [csv](https://pub.dev/packages/csv) package.

```dart
parameterizedTest('Example of CSV data',
const CsvToListConverter().convert('kiwi,4\r\napple,5\r\nbanana,6'),
(String fruit, int length) {
expect(fruit.length, length);
});
```

## Additional information
## Additional information 💡

Its just a simple wrapper to easily execute tests multiple times with different values. Feel free to
leave some feedback or open an pull request :)
It's just a simple wrapper to easily execute tests multiple times with different values. Feel free to
leave some feedback or open a pull request :)
Loading

0 comments on commit 225c655

Please sign in to comment.