Flutter注解匹配插件finder_matcher_annotation的使用
以下是根据您的要求整理的内容,包含了完整的示例Demo,并且去掉了所有索引链接及网址:
Finder Matcher Gen #
❗ This package contains annotations for finder_matcher_gen. You cannot use this package independently of finder_matcher_gen.
- Motivation ✨
- Installation 💻
- Annotation usage 🎮
- [@Match](/user/Match) annotation
- Finders 🔍
- Matcher
- [@MatchDeclaration](/user/MatchDeclaration) annotation
- Linting
- Generate code
- Configure generation for integration tests
A Flutter package for generating custom Finder and Matcher for widget tests. Not sure what a Matcher or Finder is? Visit finder-matcher-gen documentation.
✨ Motivation #
I find myself writing custom Finder and Matcher to abstract validation code for widget/integration tests. Implementing these can be tedious.
Finder-Matcher-Gen tries to fix this by implementing these custom classes for you.
Before | After | |
---|---|---|
Finder | ||
Matcher |
💻 Installation #
❗ In order to start using Finder Matcher Gen you must have the Dart SDK installed on your machine.
Add `finder_matcher_annotation` to your `pubspec.yaml`:
Run the following command on your terminal:
flutter pub add finder_matcher_annotation
flutter pub add finder_matcher_gen --dev
flutter pub add build_runner --dev
Or add it manually to your pubspec.yaml file.
dependencies:
finder_matcher_annotation: ^[version]
dev_dependencies:
finder_matcher_gen: ^[version]
build_runner: ^[version]
Run the command below to install.
Install it:
flutter pub get
Copy and paste the code below into your test file to import.
import 'package:finder_matcher_annotation/finder_matcher_annotation.dart';
🚀 Annotation usage #
Finder-matcher-gen makes use of annotation declarations to generate code. This tool provides two annotations: `[@Match](/user/Match)` and `[@MatchDeclaration](/user/MatchDeclaration)` annotations.
[@Match](/user/Match) annotation #
Apply `[@Match](/user/Match)` annotation to a declaration, usually, the test `main()` function to specify widgets to generate a finder or matcher counterpart.
[@Match](/user/Match)(finders: [], matchers: [])
void main() {
//Test code in here
}
The `[@Match](/user/Match)` annotation accepts two parameters: a list of `Type` for finders; a list of `MatchWidget` for matchers.
Finders
For a widget named `TrafficLightLampWidget` pass the type of the widget to the finders param of the `[@Match](/user/Match)` annotation to generate a finder counterpart.
[@Match](/user/Match)(finders: [TrafficLightLampWidget])
You can pass any number of widget types to the `finders` param to generate a finder counterpart.
Matcher
Pass a list of `MatchWidget` to the `matchers` param. `MatchWidgets` accepts three params.
-
A required `type`: The runtime representation of this widget to generate a matcher counterpart.
-
A required `matchSpecification`: An enum of `MatchSpecification` to define the kind of Matcher to generate for this widget.
-
An optional `secondaryType`: The runtime representation of another widget that this Matcher will utilise.
Some Matcher specifications involve a different widget. For example, to generate a matcher that asserts if `WidgetA` is contained in `WidgetB`, `WidgetB` will be passed as the `secondaryType`.
[@Match](/user/Match)(matchers: [
MatchWidget(TrafficLightLampWidget, MatchSpecification.matchesOneWidget),
])
To learn more about the different match specifications you can set, click here.
[@MatchDeclaration](/user/MatchDeclaration) annotation #
In most cases, declarations (getters, fields, functions) defined in a widget are essential to the widget’s identity. In other words, they will be used for asserting this widget behaviour.
Annotate widget fields, getters, or functions with `[@MatchDeclaration](/user/MatchDeclaration)` to mark them for use in the validation code. The `[@MatchDeclaration](/user/MatchDeclaration)` annotation accepts a `defaultValue` argument used to compare to the actual value of the widget found in the test environment. A constructor field for this declaration will be added to the generated code if no default value is provided.
class RedTrafficLightLampWidget extends StatelessWidget{
[@MatchDeclaration](/user/MatchDeclaration)()
final Color lightColor;
[@MatchDeclaration](/user/MatchDeclaration)(defaultValue: 'STOP')
final String text;
}
The code below highlights the result of providing a default value and otherwise.
/// Where `_lightColor` is a constructor field of this generated code
return widget.lightColor == _lightColor && widget.text == 'STOP';
Linting #
A common pitfall while using this annotation is passing a wrong data type (different from the data type of the annotated property) to the `defaultValue`.
Fortunately, this package provides static analysis to throw an error when this kind of mistake is made.
Note: The annotation `[@MatchDeclaration](/user/MatchDeclaration)` can only be used on getters, fields, and non-void methods
🏭 Generate code #
Run the command below to generate the custom finder and matcher code.
flutter pub run build_runner build
After a successful run, you should notice two newly generated files.
- A `${my_test_file}.finders.dart` file containing generated finders.
- A `${my_test_file}.matchers.dart` file containing generated matchers.
For more information, see generate section to explore how to use generated files.
Configure generation for integration tests #
Create a `build.yaml` file in the top-level folder of your project. Insert the code below in the newly created file.
targets:
$default:
sources:
- integration_test/**
- lib/**
- test/**
# Note that it is important to include these in the default target.
- pubspec.*
- $package$
You can also include custom folders where you need to generate matchers and finders.
📄 Detailed Documentation #
For more detailed information of using this tool, visit the documentation.
🐛 Bugs/Request #
If you encounter any problems feel free to open an issue. If you feel the library is missing a feature, please raise a ticket on Github and I'll look into it. Pull requests are also welcomed.
🤖 Continuous Integration #
Finder Matcher Gen comes with a built-in GitHub Actions workflow powered by Very Good Workflows but you can also add your preferred CI/CD solution.
Out of the box, on each pull request and push, the CI formats, lints, and tests the code. This ensures the code remains consistent and behaves correctly as you add functionality or make changes. The project uses Very Good Analysis for a strict set of analysis options used by our team. Code coverage is enforced using the Very Good Workflows.
更多关于Flutter注解匹配插件finder_matcher_annotation的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter注解匹配插件finder_matcher_annotation的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何使用Flutter注解匹配插件finder_matcher_annotation
的代码示例。这个插件允许你通过注解的方式定义Finder,从而使得测试代码更加简洁和可维护。
首先,确保你已经在pubspec.yaml
文件中添加了依赖:
dependencies:
flutter:
sdk: flutter
flutter_test:
sdk: flutter
finder_matcher_annotation: ^x.y.z # 请替换为最新版本号
然后,运行flutter pub get
来获取依赖。
接下来,我们可以创建一个自定义Finder注解,并在测试中使用它。
步骤1:定义自定义Finder注解
创建一个新的Dart文件,比如custom_finder.dart
,用于定义注解:
import 'package:finder_matcher_annotation/finder_matcher_annotation.dart';
import 'package:flutter_test/flutter_test.dart';
// 定义一个自定义Finder注解
@Target({TypeChecker.byType(Finder)})
class CustomFinder extends StatelessMatcherAnnotation {
const CustomFinder();
@override
Matcher matcher() {
return findsOneWidgetWithTooltip(contains('My Custom Tooltip'));
}
}
步骤2:在测试中使用自定义Finder注解
现在,我们可以在测试文件中使用这个注解。创建一个新的测试文件,比如my_widget_test.dart
:
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:your_app/main.dart'; // 替换为你的主应用文件
import 'custom_finder.dart';
void main() {
testWidgets('finds widget with custom finder annotation', (WidgetTester tester) async {
await tester.pumpWidget(MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('My App'),
),
body: Center(
child: Tooltip(
message: 'My Custom Tooltip',
child: Text('Hover over me'),
),
),
),
));
// 使用自定义注解定义的Finder
expect(tester.widget<Tooltip>(@CustomFinder()), isNotNull);
});
}
在这个例子中,@CustomFinder()
注解被用来匹配具有特定tooltip消息的Tooltip
widget。matcher()
方法定义了如何匹配这个widget,即寻找tooltip包含’My Custom Tooltip’的widget。
注意事项
- 确保
finder_matcher_annotation
插件的版本与你的Flutter环境兼容。 @CustomFinder()
注解只能在expect
函数等接受Finder
参数的地方使用。- 这个插件主要用于测试代码,以提高测试代码的可读性和可维护性。
通过上述步骤,你可以利用finder_matcher_annotation
插件来创建和使用自定义Finder注解,使你的Flutter测试代码更加简洁和易于管理。