Flutter机器人控制插件flutter_robot的使用
Flutter机器人控制插件flutter_robot的使用
简介
flutter_robot
是一个用于创建页面测试的插件,通过模拟多设备屏幕大小、iOS主按钮、状态栏和键盘打开等场景,验证控制器(如Cubit/Bloc/MobX等)与视图之间的正确交互。
安装
首先,在项目的 pubspec.yaml
文件中添加 flutter_robot
作为开发依赖项:
$ dart pub add dev:flutter_robot
创建第一个机器人测试
第一步 - 创建机器人
在项目中创建两个文件:{page_name}_robot.dart
和 {page_name}_test.dart
。我们以 my_feature_page_robot.dart
和 my_feature_page_test.dart
为例。
my_feature_page_robot.dart
class MyFeaturePageRobot extends Robot {
MyFeaturePageRobot({
required super.tester,
});
@override
Widget build() {
// 返回要测试的页面或小部件
return const MyFeaturePage();
}
Future<void> assertScreen() {
// 捕获当前屏幕快照
return takeSnapshot('MyFeaturePage_screen');
}
// 创建其他方法来与 'WidgetTester' API 交互,如 tap、enterText 等。
// 或者使用 RobotElement 查找小部件并与其交互。
}
第二步 - 创建测试
my_feature_page_test.dart
import 'package:flutter_robot/flutter_robot.dart';
import 'package:flutter_test/flutter_test.dart';
import 'my_feature_page_robot.dart';
void main() {
// 设置机器人
setUpRobot(
(tester) => MyFeaturePageRobot(tester: tester),
);
// 运行测试
testRobot<MyFeaturePageRobot>(
'Should show page correctly',
(robot) async {
await robot.assertScreen();
},
);
}
创建黄金文件
运行以下命令更新黄金文件:
$ flutter test --update-goldens
如果一切正常,测试将通过并生成名为 golden_files
的文件夹,并在其中创建 MyFeaturePage_screen.png
文件。
使用场景
第一步 - 创建场景
在 my_feature_page_scenarios.dart
中定义场景:
abstract class MyFeaturePageScenarios extends RobotScenario {
@override
FutureOr<void> injectDependencies() {}
@override
FutureOr<void> mockScenario() {}
}
第二步 - 实现基础机器人文件
my_feature_page_robot.dart
class MyFeaturePageRobot extends Robot<MyFeaturePageScenarios> {
MyFeaturePageRobot({
required super.tester,
required super.scenario,
});
@override
Widget build() {
return const MyFeaturePage();
}
Future<void> assertSuccessScreenGolden() {
// 捕获成功场景的快照
return takeSnapshot('MyFeaturePage_success');
}
}
第三步 - 创建测试
my_feature_page_test.dart
import 'package:flutter_test/flutter_test.dart';
import 'my_feature_page_robot.dart';
import 'my_feature_page_scenarios.dart';
void main() {
// 设置机器人
setUpRobot(
(tester) => MyFeaturePageRobot(
tester: tester,
),
);
// 运行测试
testRobot<MyFeaturePageRobot>(
'Should show the success case correctly',
(robot) async {
await robot.assertSuccessScreenGolden();
},
scenario: MyFeaturePageSuccess(), // 定义成功的场景
);
}
在多设备上运行测试
为了在多设备上运行测试,可以传递 devices
参数给 testRobot
方法:
void main() {
// 设置机器人
setUpRobot(
(tester) => MyFeaturePageRobot(
tester: tester,
),
);
// 运行测试
testRobot<MyFeaturePageRobot>(
'Should run in all devices',
(robot) async {
await robot.assertScreen();
},
devices: [
RobotDevice.small(),
RobotDevice.medium(),
RobotDevice.large(),
RobotDevice(
name: 'custom',
sizeScreen: const Size(800, 800),
withStatusBar: true,
withKeyboard: true,
withIOSHomeButton: true,
),
],
);
}
使用 RobotElement
RobotElement
可帮助你查找和与小部件树中的特定元素进行交互。
my_feature_page_robot.dart
class MyFeaturePageRobot extends Robot {
MyFeaturePageRobot({
required super.tester,
});
@override
Widget build() {
return const MyFeaturePage();
}
// 通过键获取特定元素
RobotElement get submitButton => RobotElement.byKey(Key('submit_button'), tester);
// 通过类型获取元素
RobotElement get textField => RobotElement.byType(TextField, tester);
// 通过文本获取元素
RobotElement get welcomeText => RobotElement.byText('Welcome!', tester);
// 通过图标获取元素
RobotElement get settingsIcon => RobotElement.byIcon(Icons.settings, tester);
}
my_feature_page_test.dart
void main() {
// 设置机器人
setUpRobot(
(tester) => MyFeaturePageRobot(tester: tester),
);
// 运行测试
testRobot<MyFeaturePageRobot>(
'Should interact with the elements',
(robot) async {
await robot.submitButton.scrollTo();
await robot.submitButton.tap();
await robot.welcomeText.assertIsVisible();
await robot.settingsIcon.longPress();
await robot.textField.enterText('Test input');
},
);
}
加载字体
要加载字体以在黄金文件中显示文本和图标,可以使用 RobotFontLoaderManager
。
flutter_test_config.dart
import 'dart:async';
import 'package:flutter_robot/flutter_robot.dart';
Future<void> testExecutable(FutureOr<void> Function() testMain) async {
RobotFontLoaderManager().add(MyCustomIconFontLoader());
return testMain();
}
或者覆盖 Robot
类中的 fontLoaders
方法:
import 'dart:async';
import 'package:flutter_robot/flutter_robot.dart';
class MyRobot extends Robot {
List<RobotFontLoader> get fontLoaders => [
MyCustomIconFontLoader(),
];
}
加载资源
Robot
会尝试加载小部件树中的所有 ImageProvider
。如果需要手动加载资源,可以调用 loadAsyncImageProvider
。
黄金文件差异阈值
为了处理在不同操作系统上的差异,可以设置 threshold
来避免小差异导致测试失败。
flutter_test_config.dart
import 'dart:async';
import 'package:flutter_robot/flutter_robot.dart';
Future<void> testExecutable(FutureOr<void> Function() testMain) async {
RobotFileComparator.thresholdDefault = 0.05; // 5%
return testMain();
}
也可以为特定的 Robot
设置 threshold
:
class ExamplePageRobot extends Robot {
ExamplePageRobot({
required super.tester,
required super.scenario,
}) : super(goldenThreshold: 0.05);
...
}
更多关于Flutter机器人控制插件flutter_robot的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter机器人控制插件flutter_robot的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,关于Flutter中的flutter_robot
插件(请注意,flutter_robot
并非一个广泛认知的官方或主流插件,这里假设它是一个自定义或特定领域的插件,用于机器人控制),我可以提供一个假设性的代码示例来展示如何在Flutter应用中集成和使用这样一个插件。
首先,假设flutter_robot
插件提供了基本的机器人控制功能,比如移动、旋转、抓取等。以下是一个简化的示例,展示如何在Flutter中使用这个插件。
1. 添加依赖
首先,你需要在pubspec.yaml
文件中添加对flutter_robot
插件的依赖(假设它已经在pub.dev上发布,或者你已经将其作为本地包包含在内)。
dependencies:
flutter:
sdk: flutter
flutter_robot: ^1.0.0 # 假设版本号为1.0.0
2. 导入插件
在你的Dart文件中导入flutter_robot
插件。
import 'package:flutter_robot/flutter_robot.dart';
3. 初始化机器人控制器
假设flutter_robot
提供了一个RobotController
类来处理与机器人的通信。
class _MyHomePageState extends State<MyHomePage> {
late RobotController _robotController;
@override
void initState() {
super.initState();
// 初始化机器人控制器,这里可能涉及到连接到实际的机器人硬件或模拟环境
_robotController = RobotController.instance;
_robotController.connect(); // 假设有一个connect方法用于建立连接
}
@override
void dispose() {
_robotController.disconnect(); // 断开连接
super.dispose();
}
4. 使用控制器控制机器人
现在你可以使用_robotController
来发送控制命令给机器人。
void _moveForward() {
_robotController.move(direction: Direction.forward, speed: 50); // 假设有一个move方法,接受方向和速度参数
}
void _rotateLeft() {
_robotController.rotate(direction: Rotation.left, speed: 30); // 假设有一个rotate方法,接受旋转方向和速度参数
}
void _grabObject() {
_robotController.grab(action: GrabAction.open); // 打开抓手
Future.delayed(Duration(seconds: 1), () { // 延迟1秒后执行抓取动作
_robotController.grab(action: GrabAction.close); // 关闭抓手
});
}
5. 在UI中调用控制方法
最后,在你的Flutter UI中添加按钮来触发上述控制方法。
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Robot Control'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ElevatedButton(
onPressed: _moveForward,
child: Text('Move Forward'),
),
ElevatedButton(
onPressed: _rotateLeft,
child: Text('Rotate Left'),
),
ElevatedButton(
onPressed: _grabObject,
child: Text('Grab Object'),
),
],
),
),
);
}
注意事项
- 上述代码是一个假设性的示例,实际使用时需要根据
flutter_robot
插件提供的API进行调整。 - 连接和控制真实机器人硬件可能需要处理更多的细节,比如错误处理、状态反馈、安全机制等。
- 如果
flutter_robot
是一个私有或特定领域的插件,确保你有正确的访问权限和文档。
希望这个示例能帮助你理解如何在Flutter中集成和使用一个假设的机器人控制插件。如果你有具体的flutter_robot
插件文档或源代码,进一步定制和扩展这个示例将会更加直接和有效。