Testing in Flutter

Sep 19 2023 · Dart 2.19.3, Flutter 3.7.6, Android Studio 2021.3.1, Visual Studio Code 1.7.4

Part 3: Write Widget Tests

11. Test Different Login Scenarios

Episode complete

Play next episode

Next
About this episode
Leave a rating/review
See forum comments
Cinema mode Mark complete Download course materials
Previous episode: 10. Find & Pump Widget Next episode: 12. Mock Quotes Data & Override Riverpod Dependencies

Get immediate access to this and 4,000+ other videos and books.

Take your career further with a Kodeco Personal Plan. With unlimited access to over 40+ books and 4,000+ professional videos in a single subscription, it's simply the best investment you can make in your development career.

Learn more Already a subscriber? Sign in.

Transcript: 11. Test Different Login Scenarios

In the last episode, we checked if all the widgets are present on the login screen. Now test lets test the login screen with different scenarios. The first scenario is when the user enters invalid credentials.

We will enter the invalid email and password into the text form fields and tap the login button. Then we will check if the error text is displayed or not. If the error text is displayed, it will pass the test else. It will fail the test.

await tester.enterText(emailTextField, 'abcd');
await tester.enterText(passwordTextField, '1234');

await tester.tap(loginButton);

await tester.pumpAndSettle();
var emailErrorText = find.text(kEmailErrorText);
var passwordErrorText = find.text(kPasswordErrorText);

expect(emailErrorText, findsOneWidget);
expect(passwordErrorText, findsOneWidget);

We use tester.enterText function to enter text into the text form fields. This function takes a text form field and a string as an argument. The string is the text you want to enter into the text form field.

Then we tap the login button using tester.tap function. This function takes a widget as an argument. The widget is the widget you want to tap.

Then we use tester.pumpAndSettle function to wait for the animation to finish. This function takes a duration as an argument. The duration is when you want to wait for the animation to finish.

Then we use find.text function to find the error text. This function takes a string as an argument. The string is the text you want to find.

Then we use findsOneWidget matcher to check if the error text is present in the widget tree. If the error text is present, it will pass the test else it will fail the test.

Now that you know how to test the login screen with invalid credentials. Here is the next challenge for you. Test the login screen for valid credentials. Hint, enter the correct details and check if the error text is not present in the widget tree.

I hope you were able to complete this challenge. If not, here is the solution.

await tester.enterText(emailTextField, 'abcd@mail.com');
await tester.enterText(passwordTextField, 'abcd1234');

await tester.tap(loginButton);
await tester.pumpAndSettle();
emailErrorText = find.text(kEmailErrorText);
passwordErrorText = find.text(kPasswordErrorText);

expect(emailErrorText, findsNothing);
expect(passwordErrorText, findsNothing);

Bravo!! You have completed the challenge. Now you know how to test the Widget tests works. There is more Widget that needs to be added to the test. Can you guess what it is?

The Loading Indicator, yes. That’s what is missing from the test. Let’s add the loading indicator to the test. The loading indicator is shown when the user taps the login button. So we will tap the login button and check if the loading indicator is present in the widget tree. If the loading indicator is present, it will pass the test else it will fail the test.

Add the following code to the test run the test.

await tester.enterText(emailTextField, 'abcd@mail.com');
await tester.enterText(passwordTextField, 'abcd1234');

await tester.tap(loginButton);
await tester.pumpAndSettle();
expect(find.byKey(loginCircularProgressKey), findsOneWidget);

Does the test pass or fail. It fails; why? Because as mentioned previously pumpAndSettle function waits for the animation to finish. But the loading indicator is shown when the user taps the login button. And pump and settles keep on working till the loading indicator is present. When the expect function checks for the loading indicator, it is not present in the widget tree. So the test fails.

To fix this, we will use pump function. This function takes a duration as an argument. The duration is when you want to wait for the animation to finish.

Alter the code as follows and run the test.


  await tester.enterText(emailTextField, 'abcd@mail.com');
  await tester.enterText(passwordTextField, 'abcd1234');
  await doGolden('Login-Page', 'Valid Credentials', testCaseScreenInfo);

  await tester.tap(loginButton);
  await tester.pump(const Duration(seconds: 1));
  expect(find.byKey(loginCircularProgressKey), findsOneWidget);

  await tester.pump(Duration(seconds: 1));
  expect(find.byKey(loginCircularProgressKey), findsNothing);

The above test will pass. We also check if the loading indicator is not present in the widget tree after the animation is finished.

The final step; is testing if the user is navigated to the Quotes screen after entering valid credentials. This we will try in Next Episode.