| [](https://github.com/dart-lang/tools/actions/workflows/test_reflective_loader.yaml) |
| [](https://pub.dev/packages/test_reflective_loader) |
| [](https://pub.dev/packages/test_reflective_loader/publisher) |
| |
| Support for discovering and running tests and test suites using reflection. |
| |
| This package follows an xUnit style where each class can be a test suite. |
| Test methods within the class are discovered reflectively based on their names or annotations. |
| |
| ## Usage |
| |
| A test file will typically have a `main` function that kicks off the test loader, and one or more classes annotated with |
| `@reflectiveTest`. |
| |
| Here is a simple example: |
| |
| ```dart |
| import 'package:test/test.dart'; |
| import 'package:test_reflective_loader/test_reflective_loader.dart'; |
| |
| void main() { |
| defineReflectiveSuite(() { |
| defineReflectiveTests(MyTestClass); |
| }); |
| } |
| |
| @reflectiveTest |
| class MyTestClass { |
| void test_simpleSuccess() { |
| expect(true, isTrue); |
| } |
| |
| @failingTest |
| void test_expectedToFail() { |
| expect(false, isTrue); |
| } |
| |
| @skippedTest |
| void test_skipped() { |
| // This test won't be run. |
| } |
| |
| void setUp() { |
| // setUp is called before each test. |
| print('setting up'); |
| } |
| |
| void tearDown() { |
| // tearDown is called after each test. |
| print('tearing down'); |
| } |
| } |
| ``` |
| |
| To run the tests, you would execute your test file with `dart test`. |
| |
| ### Test Discovery |
| |
| The `defineReflectiveSuite` and `defineReflectiveTests` functions are used to discover and define tests. |
| |
| * `defineReflectiveSuite`: This function creates a test suite. It takes a closure as an argument, and within that |
| closure, you can define tests and other nested suites. This allows you to group related tests together. |
| |
| * `defineReflectiveTests`: This function tells the test runner to look for tests in a given class. The class must be |
| annotated with `@reflectiveTest`. The test runner will then reflectively look for methods in that class that are |
| considered tests (see below). |
| |
| ### Test Suites |
| |
| Test suites are classes annotated with `@reflectiveTest`. The loader will instantiate this class for each test method, |
| so tests are isolated from each other. |
| |
| ### Test Methods |
| |
| The loader discovers tests in a few ways: |
| |
| * Methods whose names start with `test_` are treated as tests. |
| * Methods whose names start with `fail_` are treated as tests that are expected to fail. |
| * Methods whose names start with `skip_` are skipped. |
| |
| ### Annotations |
| |
| * `@failingTest`: Marks a test that is expected to fail. This is useful for tests that demonstrate a bug that has not |
| yet been fixed. |
| * `@skippedTest`: Marks a test that should be skipped and not run. |
| * `@soloTest`: Can be applied to a test class or a test method to indicate that only this test (or the tests in this |
| class) should be run. If multiple tests/classes have this annotation, they will all run. |
| |
| ### `setUp` and `tearDown` |
| |
| If a test class defines a `setUp()` method, it will be run before each test method in that class. If it defines a |
| `tearDown()` method, it will be run after each test method, even if the test fails. These are useful for setting up and |
| cleaning up test fixtures. Both `setUp()` and `tearDown()` can be `async` and return a `Future`. |
| |
| ### Asynchronous Tests |
| |
| If a test method, `setUp()`, or `tearDown()` returns a `Future`, the test runner will wait for the future to complete. |
| The `tearDown` method (if any) will be executed after the test method and its `Future` completes. |
| |
| ## Features and bugs |
| |
| Please file feature requests and bugs at the [issue tracker][tracker]. |
| |
| [tracker]: https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Atest_reflective_loader |