在浏览完关于测试的Flutter 文档之后,我在应用程序中达到了一个点,我想在应用程序上测试浅色和深色主题外观。 集成测试可能是一种选择,但是它们运行起来“昂贵”,我想将集成测试作为测试深色/浅色主题应用程序外观问题的最后手段。
这是我尝试过的(小部件测试)
testWidgets
:
void main() {
testWidgets("Test that the app renders properly in 'Dark Theme'.",
(WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
theme: ThemeData.dark(),
home: RegistrationHomePage(),
),
);
expect(
SchedulerBinding.instance.window.platformBrightness,
Brightness.dark,
reason: "The test suite should now be testing with app theme set to dark theme.",
);
})
}
然而,这次测试失败了。它失败了,因为小部件测试仍在浅色主题而不是深色主题中执行此测试。
更新: 实际上,我正在测试文本小部件将显示的颜色[在浅色主题和深色主题中]。
main.dart
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'My App',
debugShowCheckedModeBanner: false,
themeMode: ThemeMode.system,
theme: ThemeData.light(),
darkTheme: ThemeData.dark(),
home: RegistrationHomePage(),
);
}
}
registration_screen.dart
class RegistrationHomePage extends StatefulWidget {
// Constructor
RegistrationHomePage({Key key}) : super(key: key);
@override
_RegistrationHomePageState createState() => _RegistrationHomePageState();
}
class _RegistrationHomePageState extends State<RegistrationHomePage> {
void setState(fn) {
super.setState(fn);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text(
"Welcome to the app",
style: TextStyle(
color: MediaQuery.of(context).platformBrightness == Brightness.dark
? Colors.green.shade900
: Colors.green,
fontWeight: FontWeight.w600,
fontSize: 35.0,
),
textAlign: TextAlign.center,
),
),
);
}
}
测试.dart
void main() {
testWidgets("Test that the app renders properly in 'Dark Theme'.",
(WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
theme: ThemeData.dark(),
home: RegistrationHomePage(),
),
);
final Finder loginTextFinder = find.text("Welcome to the app.");
final Text loginText = tester.firstWidget(loginTextFinder);
expect(
WelcomeText.style.color,
Colors.green.shade900,
reason:
'While the system dark is dark theme, the text color should be dark green',
);
});
}
测试失败。测试失败,因为测试是在应用程序设置为浅色主题而不是深色主题的情况下进行的。我在这里一定做错了什么。目前看来我无法将测试应用程序设置为深色主题,我曾尝试在
test.dart
中使用 进行此操作
void main() {
testWidgets("Test that the app renders properly in 'Dark Theme'.",
(WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
theme: ThemeData.dark(),
home: RegistrationHomePage(),
),
);
});
}
如果我在深色主题中为应用程序运行小部件测试,我会采取以下路线:
void main() {
testWidgets("Test that the app renders properly in dark theme",
(WidgetTester tester) async {
await tester.pumpWidget(MaterialApp(
theme: ThemeData(brightness: Brightness.dark),
home: RegistrationHomePage(),
));
// Capture a BuildContext object
final BuildContext context = tester.element(find.byType(MaterialApp));
// Get finders and relevant objects that would be available at first load of MaterialApp()
final Finder welcomeTextFinder = find.text("Welcome to the app");
final Text welcomeText = tester.firstWidget(welcomeTextFinder);
// functions
bool testIsInLightTheme() {
/// return true if the test is in light theme, else false
if (Theme.of(context).brightness == Brightness.light) {
return true;
}
return false;
}
// Here is just a test to confirm that the MaterialApp is now in dark theme
expect(
Theme.of(tester.element(find.byWidget(welcomeText))).brightness,
equals(Brightness.dark),
reason:
"Since MaterialApp() was set to dark theme when it was built at tester.pumpWidget(), the MaterialApp should be in dark theme",
);
// Now let's test the color of the text
expect(
welcomeText.style.color,
testIsInLightTheme() ? Colors.green : Colors.green.shade900,
reason:
"When MaterialApp is in light theme, text is black. When Material App is in dark theme, text is white",
);
});
}
一些值得注意的提及: 在测试中捕获 BuildContext 对象:https://stackoverflow.com/a/67704136/7181909
关于如何进行主题测试的标准说明(基本上是一些处理主题测试的 flutter 源代码) [由为主题相关测试做出贡献的 Flutter 团队提供!]
这是我的简短解决方案,基于@Alvindera97 答案:
Future<void> testDarkMode(
WidgetTester tester, {
required keyElementToCheckDarkmodeIn,
required keyDarkmodeSwitcher,
}) async {
expect(
Theme.of(tester.element(_finder.key(keyElementToCheckDarkmodeIn))).brightness,
equals(Brightness.light),
);
await tester.tap(_finder.key(keyDarkmodeSwitcher));
await tester.pump();
await tester.pumpAndSettle(_testUtils.delay(DELAY));
expect(
Theme.of(tester.element(_finder.key(keyElementToCheckDarkmodeIn))).brightness,
equals(Brightness.dark),
);
}
Finder key(String keyText) {
return find.byKey(Key(keyText));
}
如果您在测试过程中需要更改亮度,可以使用 platformDispatcher 的
platformBrightnessTestValue
属性
测试内部:
widgetTester.platformDispatcher.platformBrightnessTestValue = Brightness.dark;
全球:
TestWidgetsFlutterBinding.instance.platformDispatcher.platformBrightnessTestValue = Brightness.dark;
更改值后请记得泵送