Flutter自动化测试辅助插件widget_driver_generator的使用
Flutter自动化测试辅助插件widget_driver_generator的使用
widget_driver_generator
是一个辅助包,它支持 widget_driver
包并生成所需的引导代码以完全设置您的 Drivers
。
使用
依赖
要使用 widget_driver_generator
,你需要在 pubspec.yaml
中添加以下依赖:
dependencies:
# ... 其他依赖项
widget_driver: <最新版本>
dev_dependencies:
# ... 其他开发依赖项
build_runner: <最新版本>
widget_driver_generator: <最新版本>
源代码
下面的指令解释了如何创建和注解您的 Drivers
以使用此生成器。除了导入 widget_driver
包之外,还需要包含一个引用生成的 Dart 文件的 part
指令。生成的文件名称始终为 [source_file].g.dart
。
import 'package:widget_driver/widget_driver.dart';
part 'this_file.g.dart';
在组织好导入语句之后,定义您的 Driver
并用 @GenerateTestDriver()
注解。如果您忘记这样做,则不会生成任何代码。
@GenerateTestDriver()
class MyDriver extends WidgetDriver {
...
}
现在只需一步即可完成。您的 Driver
中的任何公共属性和方法都可以被注解,以便它们在测试中提供特定值。所有简单的返回类型(如 Dart 的内置类型、枚举、可选类型和小部件中经常使用的类型,如 Color
、IconData
和 FontWeight
)都已涵盖。更复杂的类型(如自定义类)必须在您的代码中处理。
注解您想要在 TestDriver
中显式定义的属性,使用 @TestDriverDefaultValue({default_value})
。作为 TestDriverDefaultValue
的参数,传递您希望驱动程序在测试时给小部件的默认值。
也可以用 @TestDriverDefaultValue({default_return_value})
注解您的方法。作为 TestDriverDefaultValue
的参数,传递您希望驱动程序在测试期间小部件调用该方法时返回的默认值。如果方法不返回任何内容,则只需传递空参数。
如果方法返回一个未来,可以使用 @TestDriverDefaultFutureValue
注解。它将正确生成带有您传递的返回值的未来。
@GenerateTestDriver()
class MyDriver extends WidgetDriver {
...
int get value => _someService.value;
@TestDriverDefaultValue(CustomClass())
CustomClass get value => _counterService.getCustomClass;
void doSomething() {
...
}
String giveMeSomeString() {
return _someService.getSomeString();
}
Future<int> giveMeSomeIntSoon() {
return _someService.getSomeIntSoon();
}
@TestDriverDefaultFutureValue(CustomClass())
Future<CustomClass> giveMeSomeCustomClassSoon() {
return _someService.getSomeCustomClassSoon();
}
}
(可选) 指定全局测试默认值
作为替代方案,您还可以在 build.yaml
中全局指定应该为类型生成什么值。这将加载您指定的值到从其中获取默认值的表中。
重要的是,您必须指定如何构造它们,而不是像类的 JSON 版本。注意这里,如何指定 CustomClass
。确保用于生成类的驱动程序知道构造函数中使用的所有类,否则您会遇到编译错误。
在 pubspec.yaml
同级目录下添加 build.yaml
,按以下模式:
targets:
$default:
builders:
widget_driver_generator:
options:
defaultTestValues:
"bool": "true"
"Color": "Colors.yellow"
"int": "123"
"CustomClass": "const CustomClass(\n name: 'name',\n description: 'Some desc',\n imageUrl: 'http://www.exampleImage.com/image',\n )"
"String": "'Hello World'"
这可以在多种情况下帮助您。上述示例做了两件事:
-
它覆盖了已经指定的内置和常用类型的值(布尔值、颜色、整数、字符串)。虽然不需要添加注释就可以使生成工作,但这更像是一个“锦上添花”。
-
它指定了
CustomClass
的值。如果没有注释,这个值将不会生成。通过在这里指定它,您可以省去在所有驱动程序中为该类添加注释的步骤。
生成代码
现在您已经完成了所有导入、定义和注解。
然后运行一次构建:
dart run build_runner build --delete-conflicting-outputs
更多关于使用 build_runner
的信息,请参阅 pub.dev。
WidgetDriver简介
有关 widget_driver
框架的更多信息,请阅读 这里。
示例代码
在项目中实现一个Driver
@GenerateTestDriver()
class MyDriver extends WidgetDriver {
...
@TestDriverDefaultValue(1)
int get value => _someService.value;
@TestDriverDefaultValue()
void doSomething() {
...
}
@TestDriverDefaultValue('The string')
String giveMeSomeString() {
return _someService.getSomeString();
}
@TestDriverDefaultFutureValue(123)
Future<int> giveMeSomeIntSoon() {
return _someService.getSomeIntSoon();
}
}
你也可以将数据从小部件传递到驱动程序
class MyDriver extends WidgetDriver {
final SomeType someNamedVariable;
final SomeType somePositionalVariable;
MyDriver(
@driverProvidableProperty this.somePositionalVariable, {
@driverProvidableProperty required this.someNamedVariable
});
...
}
class MyWidget extends DriveableWidget<MyDriver> {
@override
Widget build(BuildContext context) {
...
}
@override
WidgetDriverProvider<MyDriver> get driverProvider => $MyDriverProvider(
somePositionalVariable: xyz,
someNamedVariable: zyx,
);
}
这适用于命名参数、位置参数和/或可选参数。
注意:请谨慎使用。这仅用于向驱动程序传递模型数据(例如点击列表项)。尽量不要用于提供存储库,以避免耦合并简化测试。
生成代码
为了生成 TestDrivers
和 WidgetDriverProviders
,只需运行以下命令:
dart run build_runner build --delete-conflicting-outputs
更多关于Flutter自动化测试辅助插件widget_driver_generator的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter自动化测试辅助插件widget_driver_generator的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何在Flutter项目中使用widget_driver_generator
插件来进行自动化测试辅助的示例。widget_driver_generator
插件可以帮助你生成测试驱动代码,从而简化UI测试的编写过程。
步骤一:添加依赖
首先,你需要在你的pubspec.yaml
文件中添加widget_driver_generator
的依赖。
dev_dependencies:
flutter_test:
sdk: flutter
widget_driver_generator: ^x.y.z # 请替换为最新版本号
步骤二:运行生成器
在终端中运行以下命令来生成测试驱动代码:
flutter pub get
flutter pub run widget_driver_generator:generate
步骤三:编写Widget和测试
假设你有一个简单的Widget,比如CounterWidget
,代码如下:
// counter_widget.dart
import 'package:flutter/material.dart';
class CounterWidget extends StatefulWidget {
@override
_CounterWidgetState createState() => _CounterWidgetState();
}
class _CounterWidgetState extends State<CounterWidget> {
int _count = 0;
void _increment() {
setState(() {
_count++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Counter'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_count',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _increment,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
步骤四:生成测试驱动代码
在widget_driver_generator
运行后,它会在你的测试目录中生成一个与CounterWidget
对应的驱动文件,比如counter_widget_driver.dart
。
// counter_widget_driver.dart (自动生成)
import 'package:flutter_driver/flutter_driver.dart';
import 'package:test/test.dart';
void main() {
group('CounterWidget tests', () {
FlutterDriver driver;
setUpAll(() async {
driver = await FlutterDriver.connect();
});
tearDownAll(() async {
if (driver != null) {
driver.quit();
}
});
test('tap on floating action button increments counter', async () async {
// Find the counter text element
SerializableFinder counterTextFinder = find.byValueKey('counterText');
SerializableFinder fabFinder = find.byTooltip('Increment');
// Wait for the counter text to appear
String counterText = await driver.getText(counterTextFinder);
expect(int.parse(counterText), 0);
// Tap the floating action button
await driver.tap(fabFinder);
// Wait for the counter text to update
await Future.delayed(Duration(seconds: 1));
counterText = await driver.getText(counterTextFinder);
expect(int.parse(counterText), 1);
});
});
}
注意:在实际生成的代码中,SerializableFinder
可能需要根据你的Widget中的具体实现进行调整。例如,byValueKey
和byTooltip
可能需要替换为byText
或其他适当的Finder。
步骤五:运行测试
你可以使用以下命令来运行Flutter的集成测试:
flutter drive --target=test_driver/app.dart
其中,app.dart
是你的测试启动文件,通常内容如下:
// test_driver/app.dart
import 'package:flutter_driver/flutter_driver.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:your_app/main.dart' as app; // 替换为你的主应用入口
void main() {
enableFlutterDriverExtensions();
app.main();
}
这样,你就可以使用widget_driver_generator
生成的测试驱动代码来运行和验证你的Flutter应用的UI行为了。