Bird
Raised Fist0
Fluttermobile~20 mins

Test coverage in Flutter - Mini App: Build & Ship

Choose your learning style10 modes available
Build: Simple Counter Test
A screen with a counter and a button to increase the count. We want to write tests to cover the button tap and counter display.
Target UI
Counter: 0

[ Increment ]
Display a number starting at 0
A button labeled 'Increment' that increases the number by 1 when tapped
Write a widget test to verify the initial counter value is 0
Write a widget test to verify tapping the button increments the counter
Starter Code
Flutter
import 'package:flutter/material.dart';

class CounterScreen extends StatefulWidget {
  @override
  State<CounterScreen> createState() => _CounterScreenState();
}

class _CounterScreenState extends State<CounterScreen> {
  int _counter = 0;

  void _increment() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Counter Test')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('Counter: $_counter', key: const Key('counterText')),
            const SizedBox(height: 20),
            ElevatedButton(
              key: const Key('incrementButton'),
              onPressed: _increment,
              child: const Text('Increment'),
            ),
          ],
        ),
      ),
    );
  }
}

// TODO: Write widget tests for initial counter and increment button
Task 1
Task 2
Task 3
Solution
Flutter
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

class CounterScreen extends StatefulWidget {
  @override
  State<CounterScreen> createState() => _CounterScreenState();
}

class _CounterScreenState extends State<CounterScreen> {
  int _counter = 0;

  void _increment() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Counter Test')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('Counter: $_counter', key: const Key('counterText')),
            const SizedBox(height: 20),
            ElevatedButton(
              key: const Key('incrementButton'),
              onPressed: _increment,
              child: const Text('Increment'),
            ),
          ],
        ),
      ),
    );
  }
}

void main() {
  testWidgets('Initial counter value is 0', (WidgetTester tester) async {
    await tester.pumpWidget(MaterialApp(home: CounterScreen()));

    expect(find.byKey(const Key('counterText')), findsOneWidget);
    expect(find.text('Counter: 0'), findsOneWidget);
  });

  testWidgets('Tapping increment button increases counter', (WidgetTester tester) async {
    await tester.pumpWidget(MaterialApp(home: CounterScreen()));

    final Finder button = find.byKey(const Key('incrementButton'));
    await tester.tap(button);
    await tester.pump();

    expect(find.text('Counter: 1'), findsOneWidget);
  });
}

This code defines a simple counter screen with a button to increase the count. The key parts are:

  • The counter text has a key 'counterText' so tests can find it easily.
  • The increment button has a key 'incrementButton' for testing taps.
  • Two widget tests are written:
    • One checks the initial counter text is 'Counter: 0'.
    • The other taps the increment button and verifies the counter updates to 'Counter: 1'.
  • This shows how to write basic test coverage for UI behavior in Flutter.
Final Result
Completed Screen
Counter: 0

[ Increment ]
User sees the counter starting at 0
User taps the 'Increment' button
Counter text updates to 1
Stretch Goal
Add a decrement button that decreases the counter but never below 0, and write tests for it.
💡 Hint
Add a new ElevatedButton with key 'decrementButton' and check counter does not go below zero in tests.

Practice

(1/5)
1.

What does test coverage measure in a Flutter app?

easy
A. How much of the app's code is executed by tests
B. The number of tests written
C. The speed of test execution
D. The size of the app's binary

Solution

  1. Step 1: Understand test coverage meaning

    Test coverage shows what percentage of your code runs when tests are executed.
  2. Step 2: Compare options to definition

    Only How much of the app's code is executed by tests matches this meaning by describing code executed by tests.
  3. Final Answer:

    How much of the app's code is executed by tests -> Option A
  4. Quick Check:

    Test coverage = code executed by tests [OK]
Hint: Coverage means code tested, not test count or speed [OK]
Common Mistakes:
  • Confusing coverage with number of tests
  • Thinking coverage measures test speed
  • Assuming coverage relates to app size
2.

Which command runs Flutter tests and collects coverage data?

?
easy
A. flutter test --coverage
B. flutter run --coverage
C. flutter build --coverage
D. flutter analyze --coverage

Solution

  1. Step 1: Recall Flutter test commands

    The command to run tests and collect coverage is flutter test --coverage.
  2. Step 2: Eliminate incorrect commands

    flutter run runs the app, flutter build builds it, and flutter analyze checks code style, none collect coverage.
  3. Final Answer:

    flutter test --coverage -> Option A
  4. Quick Check:

    Run tests with coverage = flutter test --coverage [OK]
Hint: Use flutter test --coverage to get coverage data [OK]
Common Mistakes:
  • Using flutter run instead of flutter test
  • Confusing build or analyze commands with testing
  • Omitting the --coverage flag
3.

Given this test code snippet, what is the coverage result for increment() method?

class Counter {
  int value = 0;
  void increment() {
    value++;
  }
}

void main() {
  final counter = Counter();
  test('value starts at 0', () {
    expect(counter.value, 0);
  });
}
medium
A. 100% coverage including increment()
B. Partial coverage of increment() method
C. 0% coverage for increment() method
D. Syntax error prevents coverage

Solution

  1. Step 1: Analyze test coverage of increment()

    The test only checks initial value; it never calls increment().
  2. Step 2: Determine coverage for increment()

    Since increment() is never executed, coverage for it is 0%.
  3. Final Answer:

    0% coverage for increment() method -> Option C
  4. Quick Check:

    Method not called = 0% coverage [OK]
Hint: Only called code counts as covered [OK]
Common Mistakes:
  • Assuming all methods are covered by default
  • Confusing test presence with code execution
  • Ignoring that increment() is never called
4.

Identify the error in this test setup that causes coverage to be incomplete:

void main() {
  final counter = Counter();
  test('increment test', () {
    counter.increment;
    expect(counter.value, 1);
  });
}
medium
A. Test name is missing
B. Missing parentheses to call increment() method
C. expect() syntax is incorrect
D. Counter class is not imported

Solution

  1. Step 1: Check method call syntax

    The code uses counter.increment; which references the method but does not call it.
  2. Step 2: Understand impact on coverage

    Because increment() is not called, coverage misses this method.
  3. Final Answer:

    Missing parentheses to call increment() method -> Option B
  4. Quick Check:

    Method call needs () to execute [OK]
Hint: Method calls need () to run and count for coverage [OK]
Common Mistakes:
  • Forgetting () after method name
  • Assuming method reference calls it
  • Ignoring test name importance (not required)
5.

You want to improve test coverage for this class. Which test addition best increases coverage?

class Calculator {
  int add(int a, int b) => a + b;
  int subtract(int a, int b) => a - b;
  int multiply(int a, int b) => a * b;
}

Current tests only call add().

hard
A. Add tests checking only Calculator class existence
B. Add tests calling add() multiple times
C. Add tests that print results without assertions
D. Add tests calling subtract() and multiply() methods

Solution

  1. Step 1: Identify untested methods

    Only add() is tested; subtract() and multiply() are not covered.
  2. Step 2: Add tests for untested methods

    Writing tests that call subtract() and multiply() will increase coverage.
  3. Final Answer:

    Add tests calling subtract() and multiply() methods -> Option D
  4. Quick Check:

    Test all methods to increase coverage [OK]
Hint: Test all methods, not just one, to boost coverage [OK]
Common Mistakes:
  • Testing only one method repeatedly
  • Testing class existence without method calls
  • Printing results without assertions doesn't count
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard