dimanche 28 mars 2021

Flutter - Inconsistent Widget Test Results for Checking If TextFormField Error Text Appears

I am currently conducting widget tests on Flutter to determine whether the error text, "Please enter an email!", gets displayed in my Login/Register Pages whenever user submits form with an empty email field. The project follows an MVVM-style architecture called Stacked (by FilledStacks).

This is my TextFormField validator function for the login page:

/// Email Validator
  String validateEmail(String email) {
    email = email.trim(); // trim leading/trailing whitespace
    if (email.isEmpty) {
      return 'Please enter an email!';
    } else {
      return null;
    }
  }

This is my test function for the login validator (PASSES):

testWidgets('Textfield should display warning string for empty email.',
        (WidgetTester tester) async {
      // Arrange
      await tester.pumpWidget(createWidgetForTesting(LoginView()));
      final emailFieldFinder = find.widgetWithText(TextFormField, 'Email');
      final buttonFinder = find.widgetWithText(ElevatedButton, 'Login');
      final emailErrorFinder = find.text('Please enter an email!');
      // Act
      await tester.enterText(emailFieldFinder, '');
      await tester.tap(buttonFinder);
      await tester.pump(const Duration(milliseconds: 100)); // add delay
      // Assert
      expect(emailErrorFinder, findsOneWidget);
    });

Now I replicate the SAME EXACT validator function for a register page, which has the following test function (FAILS):

testWidgets('Textfield should display warning string for empty email.',
            (WidgetTester tester) async {
          // Arrange
          await tester.pumpWidget(createWidgetForTesting(RegisterView()));
          final emailFieldFinder = find.widgetWithText(TextFormField, 'Email');
          final buttonFinder = find.widgetWithText(ElevatedButton, 'Register');
          final emailErrorFinder = find.text('Please enter an email!');
          // Act
          await tester.enterText(emailFieldFinder, '');
          await tester.tap(buttonFinder);
          await tester.pump(const Duration(milliseconds: 100)); // add delay
          // Assert
          expect(emailErrorFinder, findsOneWidget);
        });

I verified that all widget finders (except the error text finders) can find their respective widgets (TextFormField, ElevatedButton, etc.), and I also verified that the validators do their work because when I manually test both login and register pages, the error messages attached to the TextFormFields show up accordingly whenever I try to submit empty fields. So what confuses me is for testing, why will only one page (LoginPage) pass the widget test but not the other (RegisterPage)?

For reference, LoginPage is the root or starting screen/widget for this Flutter application. I have also tried changing the starting screen but it produces the same result (LoginPage passes and RegisterPage fails) instead of reversing the result of the test.

Aucun commentaire:

Enregistrer un commentaire