Skip to content

Commit 225c655

Browse files
authored
Merge pull request #18 from DutchCodingCompany/feature/rework_v2
✨ Rework v2
2 parents ce147e2 + b7680c0 commit 225c655

36 files changed

+1737
-2613
lines changed

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2021 Dutch Coding Company B.V.
3+
Copyright (c) 2024 Dutch Coding Company B.V.
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.md

Lines changed: 172 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -16,158 +16,91 @@ and the Flutter guide for
1616
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!
1717

1818
## Table of contents
19-
* [Features](#features-)
20-
* [Installation](#installation)
21-
* [Usage](#usage)
22-
* [Examples](#examples)
23-
* [How it works](#how-it-works)
24-
* [Additional information](#additional-information)
19+
- [Features](#features-)
20+
- [Installation](#installation-)
21+
- [Usage](#usage-)
22+
- [Examples](#examples-)
23+
- [Additional information](#additional-information-)
2524

2625
## Features ✨
2726

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

34-
- ❌ No CSV parsing is supported. Its only possible to use Lists with actual values.
35-
36-
## Installation
33+
## Installation 🛠
3734

3835
```yaml
3936
dev_dependencies:
4037
parameterized_test: [latest-version]
4138
```
4239
43-
## Usage
44-
45-
Instead of using `groups` or `test` you can now use `parameterizedTest` and supply it list of test parameters to use in the same test.
46-
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.
47-
The package offers `TestParameters` classes up to 10 parameters. Instead of writing `TestParameters` completely it also possible to use `typedef`'s `p1`..`p10`.
48-
49-
## Examples
50-
51-
Example parameterizedTest with 1 parameter:
52-
53-
```dart
54-
parameterizedTest(
55-
'Number are less than 4 tests',
56-
[
57-
1,
58-
2,
59-
3,
60-
],
61-
p1((int number) {
62-
final result = number < 4;
63-
expect(result, true);
64-
}),
65-
);
66-
```
40+
## Usage ⚡️
6741
68-
Example parameterizedTest with 2 parameters:
42+
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.
43+
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.
44+
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.
6945

46+
For example:
7047
```dart
7148
parameterizedTest(
72-
'Amount of letters tests',
73-
[
74-
['kiwi', 4],
75-
['apple', 5],
76-
['banana', 6],
77-
],
78-
p2((String word, int length) {
79-
expect(word.length, length);
80-
}),
81-
);
82-
```
83-
84-
or
85-
86-
```dart
87-
parameterizedTest2(
88-
'Amount of letters tests',
49+
'Fruit name matches length',
50+
// List of values to test
8951
[
52+
// parameters for the test
9053
['kiwi', 4],
9154
['apple', 5],
9255
['banana', 6],
56+
['pineapple', 9],
9357
],
94-
(String word, int length) {
95-
expect(word.length, length);
58+
// Test function accepting the provided parameters
59+
(String fruit, int length) {
60+
expect(fruit.length, length);
9661
},
9762
);
9863
```
99-
100-
Example parameterizedTest with extra test options for a value:
101-
102-
```dart
103-
parameterizedTest(
104-
'Amount of letters',
105-
[
106-
['kiwi', 4],
107-
['apple', 5],
108-
['banana', 6].withTestOptions(skip: true),
109-
],
110-
p2((String word, int length) {
111-
expect(word.length, length);
112-
}),
113-
);
64+
This `parameterizedTest` will create a `group` with 4 `test` inside it. Each test will run the test function with the provided parameters.
11465
```
115-
116-
Example parameterizedTest with test enum values:
117-
118-
```dart
119-
enum AwesomeEnum { such, woow, much, skill}
120-
121-
parameterizedTest(
122-
'Doge enum tests',
123-
AwesomeEnum.values,
124-
p1((AwesomeEnum doge) {
125-
final result = doge.name.length >= 4;
126-
expect(result, true);
127-
}),
128-
);
66+
- Fruit name matches length (group)
67+
- [ 'kiwi', 4 ] (test)
68+
- [ 'apple', 5 ] (test)
69+
- [ 'banana', 6 ] (test)
70+
- [ 'pineapple', 9 ] (test)
12971
```
13072
131-
## How it works
73+
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.
74+
Here you still need to provide a `test`. This can be useful if you want to have nested groups of tests.
75+
76+
Besides accepting a list of test values, you can also provide a `setUp` and `tearDown` function to run before and after each test.
13277
133-
`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`.
78+
### Add test options to parameter 🔩
79+
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.
13480
81+
For example:
13582
```dart
13683
parameterizedTest(
137-
'Amount of letters',
84+
'Fruit name matches length',
85+
// List of values to test
13886
[
87+
// parameters for the test
13988
['kiwi', 4],
140-
['apple', 5],
89+
['apple', 5].options(skip: 'Apple is not ripe yet'),
14190
['banana', 6],
91+
['pineapple', 9],
14292
],
143-
p2((String word, int length) {
144-
expect(word.length, length);
145-
}),
93+
// Test function accepting the provided parameters
94+
(String fruit, int length) {
95+
expect(fruit.length, length);
96+
},
14697
);
14798
```
14899

149-
The above example roughly translates to:
150-
```dart
151-
group('Amount of letter', () {
152-
final testValues = [
153-
['kiwi', 4],
154-
['apple', 5],
155-
['banana', 6],
156-
];
157-
158-
for (final testValue in testValues) {
159-
test(testValue.toString(), () {
160-
final String word = testValue[0] as String;
161-
final int length = testValue[1] as int;
162-
163-
expect(word.length, length);
164-
});
165-
}
166-
});
167-
```
100+
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.
168101

169-
## Changing test description output
170-
By default the test description contains the test value used within the tests. This can be override by using `customDescriptionBuilder`.
102+
### Changing test description output 📝
103+
By default, the test description contains the test value used within the tests. you can override this by using `customDescriptionBuilder`.
171104

172105
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:
173106
```
@@ -190,31 +123,140 @@ My parameterized test 🚀[2] My parameterized test: <<third|fourth|false>>
190123

191124
>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.
192125
193-
## Extending parameters
126+
## Examples 📦
127+
### Simple test containing a list of single values
128+
```dart
129+
parameterizedTest(
130+
'Example of list of single values',
131+
[
132+
1,
133+
2,
134+
3,
135+
],
136+
(int value) {
137+
final result = value < 4;
138+
expect(result, true);
139+
},
140+
);
141+
```
194142

195-
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.
143+
### Simple test containing a list of multiple values
144+
```dart
145+
parameterizedTest('Example of list of multiple values', [
146+
[0, 1, 1],
147+
[1, 1, 2],
148+
[1, 2, 3],
149+
[2, 2, 4],
150+
], (int value1, int value2, int sum) {
151+
expect(value1 + value2, sum);
152+
});
153+
```
154+
### Test containing a list with complex objects
155+
```dart
156+
parameterizedTest('Example of a list with complex object', [
157+
[DateTime(2024, 4, 12), 5],
158+
[DateTime(1969, 07, 20), 7],
159+
], (DateTime dateTime, int expectedWeekday) {
160+
expect(dateTime.weekday, expectedWeekday);
161+
});
162+
```
196163

197-
For example:
164+
### Test containing a list of enums
198165
```dart
199-
class MyParameters<A1, A2> implements TestParameters {
200-
const MyParameters(this.body);
166+
enum TestEnum {
167+
one(3),
168+
two(3),
169+
three(5);
201170
202-
@override
203-
final dynamic Function(A1, A2) body;
171+
const TestEnum(this.myLength);
204172
205-
@override
206-
final int count = 2;
173+
final int myLength;
174+
}
207175
208-
@override
209-
dynamic mapBody<R>(Iterable<R> values) {
210-
final A1 a1 = values.elementAt(0) as A1;
211-
final A2 a2 = values.elementAt(1) as A2;
212-
return body(a1, a2);
213-
}
176+
parameterizedTest(
177+
'Example using enum as value',
178+
TestEnum.values,
179+
(TestEnum testEnum) {
180+
expect(testEnum.name.length, testEnum.myLength);
181+
},
182+
);
183+
```
184+
### Test retreiving the list of values from a function
185+
```dart
186+
List<dynamic> provideData() {
187+
return [
188+
[0, 1, 1],
189+
[1, 1, 2],
190+
[1, 2, 3],
191+
[2, 2, 4],
192+
];
214193
}
194+
195+
parameterizedTest(
196+
'Example of list of values from function',
197+
provideData(),
198+
(int value1, int value2, int sum) {
199+
expect(value1 + value2, sum);
200+
},
201+
);
202+
```
203+
204+
### Simple test with setup and teardown
205+
```dart
206+
parameterizedTest(
207+
'Example with setup and teardown ',
208+
[
209+
['kiwi', 4],
210+
['apple', 5],
211+
['banana', 6],
212+
],
213+
(String word, int length) {
214+
expect(word.length, length);
215+
},
216+
setUp: () {
217+
print('Setup everything I need for testing');
218+
},
219+
tearDown: () {
220+
print('tear it down again');
221+
},
222+
);
223+
```
224+
225+
### Test which is an async test
226+
```dart
227+
parameterizedTest(
228+
'Example using a async test',
229+
[
230+
100,
231+
200,
232+
300,
233+
],
234+
(int value) async {
235+
final millis = DateTime.now().millisecondsSinceEpoch;
236+
await Future<void>.delayed(Duration(milliseconds: value));
237+
final passed = DateTime.now().millisecondsSinceEpoch - millis;
238+
239+
expect(passed >= value, true);
240+
},
241+
);
242+
```
243+
> Note: This is a example test to showcase async tests are also possible.
244+
> But this is not a good practice to use a delay like
245+
> this in a test. Running this test will take longer. This could be
246+
> fixed by using a package like [fake_async](https://pub.dev/packages/fake_async).
247+
248+
### Test with CSV data
249+
Its also possible to combine parameterizedTest for example with the [csv](https://pub.dev/packages/csv) package.
250+
251+
```dart
252+
parameterizedTest('Example of CSV data',
253+
const CsvToListConverter().convert('kiwi,4\r\napple,5\r\nbanana,6'),
254+
(String fruit, int length) {
255+
expect(fruit.length, length);
256+
});
215257
```
216258

217-
## Additional information
259+
## Additional information 💡
218260

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

0 commit comments

Comments
 (0)