Flutter simple widget test

Look at this simple example to create a test for a button in flutter

Thu, 29 Jun 2023

Show me the money

Here is a full example for testing a simple button

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:housemates_suite_components/widgets/buttons/button_base.dart';
import 'package:housemates_suite_components/widgets/buttons/primary_button.dart';

void main() {
  testWidgets('Base button renders correctly', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: ButtonBase(buttonStyle: ButtonStyle(), buttonChild: Container()),
      ),
    );

    expect(find.byType(ButtonBase), findsOneWidget);
  });
  testWidgets('Buttons on press working', (WidgetTester tester) async {
    int counter = 1;
    await tester.pumpWidget(
      MaterialApp(
        home: ButtonBase(
          buttonStyle: ButtonStyle(),
          buttonChild: Container(),
          onPressed: () => counter += 1,
        ),
      ),
    );
    final button = find.byType(ButtonBase);
    await tester.tap(button);
    await tester.pump();
    expect(counter == 2, true);
  });
  testWidgets('Main buttons renders', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: PrimaryButton(textContent: 'Test'),
      ),
    );

    expect(find.text("Test"), findsOneWidget);
  });
}

Lets break it down

You do want to wrap your widgets inside of something. So far the simplest solution I found was to wrap them around MaterialApp and then for the home page I would just put the widget I want to render

Render the widget

This is somewhat redudant since the additional tests would all render the widget. I like to be explicit with it so if the test does fail, it would fail while rendering I wouldn’t have to figure out if the additional logic in the test failed

  testWidgets('Base button renders correctly', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: ButtonBase(buttonStyle: ButtonStyle(), buttonChild: Container()),
      ),
    );

    expect(find.byType(ButtonBase), findsOneWidget);
  });

The expect makes an assertion to look for a widget typeOf ButtonBase which is the class for this button. If the assertion only finds one, the test is complete since it rendered the button and rendered only 1

Button Clicks

  testWidgets('Buttons on press working', (WidgetTester tester) async {
  int counter = 1;
  await tester.pumpWidget(
    MaterialApp(
      home: ButtonBase(
        buttonStyle: ButtonStyle(),
        buttonChild: Container(),
        onPressed: () => counter += 1,
      ),
    ),
  );
  final button = find.byType(ButtonBase);
  await tester.tap(button);
  await tester.pump();
  expect(counter == 2, true);
});

I render the button again but this time I give it a simple function. It will add 1 to my counter each time the button is pressed. The first thing I do is find the button with

final button = find.byType(ButtonBase);

Once I find the button, we want to tap it. Once its tapped you want the tester to update frames to apply the button tap

    await tester.tap(button);
    await tester.pump();
    ```

The final piece is to confirm that my counter value did in fact go up by one.  So I make an assertion to make sure `counter = 2`
Buy Me A CoffeeDigitalOcean Referral Badge
Loading...
Edward Beazer

Edward Beazer - I just like to build shit. Sometimes I get stuck for hours, even days while trying to figure out how to solve an issue or implement a new feature. Hope my tips and tutorials can save you some time.

DigitalOcean Referral Badge