How To Show Test Coverage Of A Flutter App In Visual Studio Code

Flutter category image

Introduction

Here is a short guide about how to show test coverage of a Flutter app in Visual Studio Code. With code coverage, you can identify parts of your app that aren’t tested yet. However, it doesn’t tell you if your tests are good or your app is free of bugs!

We are going to use Visual Studio Code and two free extensions from the Visual Studio Marketplace:

Extension to show code coverage for every file
Extension to show code coverage for every file
Extension to show covered and uncovered lines
Extension to show covered and uncovered lines

If you are unfamiliar with the concept of unit testing and how to write tests for a Flutter app please check my other article where I explain the basics of testing.

The test subject

I created a simple class called login_service.dart. It allows logging in, logging out, and checking the current state (logged in or not). It’s very basic and has flaws (like hard-coded user name and password) but will be enough to demonstrate how coverage works.

Dart
class LoginService {
  final String _expectedPassword = "abc123!?=";
  final String _expectedUser = "superUser";

  bool _isLoggedIn = false;

  void login(String? user, String? password) {
    if (_isLoggedIn) throw Exception("Please log out first");

    if (user != _expectedUser) throw Exception("Wrong user name");
    if (password != _expectedPassword) throw Exception("Wrong password");

    _isLoggedIn = true;
  }

  void logout() {
    _isLoggedIn = false;
  }

  bool isLoggedIn() {
    return _isLoggedIn;
  }
}

The unit tests

Furthermore, we have some unit tests to cover all possible statements of the LoginService. You can see it in the file below.

Dart
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_test_coverage/login_service.dart';

void main() {
  test("Verify failed login with wrong user", () {
    var _sut = LoginService();
    expect(() => _sut.login("user", "abc123!?="), throwsException);
    expect(_sut.isLoggedIn(), isFalse);
  });

  test("Verify failed login with wrong password", () {
    var _sut = LoginService();
    expect(() => _sut.login("superUser", "password"), throwsException);
    expect(_sut.isLoggedIn(), isFalse);
  });

  test("Verify logout before login", () {
    var _sut = LoginService();
    _sut.login("superUser", "abc123!?=");
    expect(_sut.isLoggedIn(), isTrue);

    expect(() => _sut.login("superUser", "abc123!?="), throwsException);
    expect(_sut.isLoggedIn(), isTrue);
  });

  test("Verify successful login", () {
    var _sut = LoginService();
    _sut.login("superUser", "abc123!?=");
    expect(_sut.isLoggedIn(), isTrue);
  });

  test("Verify logout works", () {
    var _sut = LoginService();
    expect(_sut.isLoggedIn(), isFalse);

    _sut.login("superUser", "abc123!?=");
    expect(_sut.isLoggedIn(), isTrue);

    _sut.logout();
    expect(_sut.isLoggedIn(), isFalse);

    _sut.logout();
    expect(_sut.isLoggedIn(), isFalse);
  });
}

Collect coverage information

Flutter has a built-in command to collect coverage information while executing all tests. So you just need to open a shell of your choice, navigate to the project root folder, and execute the following command flutter test --coverage.

This will execute all tests in your project and create a file lcov.info which contains the coverage information. The extensions you installed earlier rely on the file to visualize the information.

Become A Testing Expert!

Become a proficient Flutter app tester with my detailed guide. This ebook covers everything from unit tests over widget tests up to dependency mocking.

Show covered lines in the editor

After the coverage information has been collected open a file that has been tested (in this example the login_service.dart file). You should see something like this.

Covered lines by tests in Visual Studio Code
Covered lines by tests in Visual Studio Code

A green line means that there is a test executing this code line while a red line means that there is no test executing this code line. This class has a coverage of 100% as all unmarked lines (like field declarations) are not measured by the Flutter tool.

Warning

Be aware that the colors don’t indicate if a test passes or not. They just tell you if there is any test for a line.

If you can’t see any colorings check the status bar and enable the coverage gutters.

Coverage display is not enabled, click to enable
Coverage display is not enabled, click to enable
Coverage display is enabled, click to disable
Coverage display is enabled, click to disable

Show coverage information per file

In bigger projects, you’d like to have an overview of those files that have sufficient test coverage and those that don’t. To solve this problem you can use the Flutter Coverage extension. It shows the coverage percentage of every dart file in your project. Go to your Test Explorer in VS Code and open the Flutter Coverage drawer. You should see something like this.

Test coverage per file with Flutter Coverage in VS Code
Test coverage per file with Flutter Coverage in VS Code

The coverage of the login_service.dart class is 100% as we have concluded before. Especially if your project gets bigger and bigger, this view will be quite handy to identify insufficiently tested classes.

Credits

If you like the extensions, the developers appreciate a rating or any feedback.

Source code

You can find the source code on GitHub.

Conclusion

In this article, you saw how to show test coverage of a Flutter app in Visual Studio Code. All it takes are two extensions and the built-in Flutter tools. With code coverage, you can better identify what parts of your app need more testing.


Want More Flutter Content?

Join my bi-weekly newsletter that delivers small Flutter portions right in your inbox. A title, an abstract, a link, and you decide if you want to dive in!

Flutter โค๏ธ Firebase

Get started with Firebase and learn how to use it in your Flutter apps. My detailed ebook delivers you everything you need to know! Flutter and Firebase are a perfect match!

Become A Testing Expert!

Become a proficient Flutter app tester with my detailed guide. This ebook covers everything from unit tests over widget tests up to dependency mocking.