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

问题描述 投票:0回答:3

在浏览完关于测试的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.",
    );
  })
}

然而,这次测试失败了。它失败了,因为小部件测试仍在浅色主题而不是深色主题中执行此测试

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

测试.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(),
      ),
    );
  });
}
android flutter dart tdd flutter-test
3个回答
2
投票

如果我在深色主题中为应用程序运行小部件测试,我会采取以下路线:

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 团队提供!]


0
投票

这是我的简短解决方案,基于@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));
  }



0
投票

如果您在测试过程中需要更改亮度,可以使用 platformDispatcher 的

platformBrightnessTestValue
属性

测试内部:

widgetTester.platformDispatcher.platformBrightnessTestValue = Brightness.dark;

全球:

TestWidgetsFlutterBinding.instance.platformDispatcher.platformBrightnessTestValue = Brightness.dark;

更改值后请记得泵送

© www.soinside.com 2019 - 2024. All rights reserved.