测试应用程序外观的最佳方法,当应用程序在黑暗/浅色主题(特别是黑暗主题)



在通过Flutter文档测试后,我已经在我的应用程序中找到了一个点,我想在应用程序上测试浅色和深色主题外观。集成测试可以是一种选择,但它们"昂贵";我想把集成测试作为测试深色/浅色主题应用外观的最后手段。

这是我尝试的(Widget测试)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.",
);
})
}

然而,此测试失败。失败是因为Widget测试仍然在浅色主题而不是深色主题中执行此测试.

  • 可以做些什么来补救这种情况,它是如何可行的运行小部件测试(专注于应用程序的外观)?
  • 在flutter中测试应用外观的通用默认设置应该是集成测试?

更新:实际上,我正在测试文本小部件在[浅色主题和深色主题]中显示的颜色。

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,
),
),
);
}
}

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(),
),
);
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));
}

最新更新