繁体   English   中英

在应用程序处于深色/浅色主题(尤其是深色主题)时在 Flutter 中测试应用程序外观的最佳方法

[英]Best Approach To Testing App Appearance In Flutter While App Is In Dark/Light Theme (especially for Dark Theme)

在阅读有关测试Flutter 文档后,我在我的应用程序中达到了一个点,我想在应用程序上测试浅色和深色主题的外观。 集成测试可能是一种选择,但是它们运行起来“昂贵”,我想将集成测试作为测试暗/亮主题应用程序外观的最后手段。

这是我尝试使用(Widget Tests) 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 Test 仍然在 light theme 而不是 dark theme 中执行这个测试

  • 可以做些什么来补救这种情况,以及运行小部件测试(专注于应用程序外观)的可行性如何?
  • 在 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(),
    );
  }
}

注册_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));
  }


暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM