DEV Community

Krisada Vivek
Krisada Vivek

Posted on • Edited on

2 1

Testing on Flutter: generate unit test badge using LCOV to your repository

TLDR; in this publication, I assumed that you all know how to write test and testing terminology and methods, no mentions here.

What is LCOV

LCOV is a graphical front-end for GCC’s coverage testing tool gcov. It collects gcov data for multiple source files and creates HTML pages containing the source code annotated with coverage information. It also adds overview pages for easy navigation within the file structure. LCOV supports statement, function, and branch coverage measurement.

Installing LCOV

brew install lcov
Enter fullscreen mode Exit fullscreen mode
  • Generating an example app — flutter counter app

    import 'package:flutter/material.dart';
    void main() {
    runApp(MyApp());
    }
    class MyApp extends StatelessWidget {
    // This widget is the root of your application.
    @override
    Widget build(BuildContext context) {
    return MaterialApp(
    title: 'Flutter Demo',
    theme: ThemeData(
    primarySwatch: Colors.blue,
    visualDensity: VisualDensity.adaptivePlatformDensity,
    ),
    home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
    }
    }
    class MyHomePage extends StatefulWidget {
    MyHomePage({Key key, this.title}) : super(key: key);
    final String title;
    @override
    _MyHomePageState createState() => _MyHomePageState();
    }
    class _MyHomePageState extends State<MyHomePage> {
    int _counter = 0;
    void _incrementCounter() {
    setState(() {
    _counter++;
    });
    }
    @override
    Widget build(BuildContext context) {
    return Scaffold(
    appBar: AppBar(
    title: Text(widget.title),
    ),
    body: Center(
    child: Column(
    mainAxisAlignment: MainAxisAlignment.center,
    children: <Widget>[
    Text(
    'You have pushed the button this many times:',
    ),
    Text(
    '$_counter',
    style: Theme.of(context).textTheme.headline4,
    ),
    ],
    ),
    ),
    floatingActionButton: FloatingActionButton(
    onPressed: _incrementCounter,
    tooltip: 'Increment',
    child: Icon(Icons.add),
    ),
    );
    }
    }
    view raw main.dart hosted with ❤ by GitHub
  • example test scripts ./test/widget_test.dart

    // This is a basic Flutter widget test.
    //
    // To perform an interaction with a widget in your test, use the WidgetTester
    // utility that Flutter provides. For example, you can send tap and scroll
    // gestures. You can also use WidgetTester to find child widgets in the widget
    // tree, read text, and verify that the values of widget properties are correct.
    import 'package:flutter/material.dart';
    import 'package:flutter_test/flutter_test.dart';
    import 'package:test_lcov_bedge/main.dart';
    void main() {
    testWidgets('Counter increments smoke test', (WidgetTester tester) async {
    // Build our app and trigger a frame.
    await tester.pumpWidget(MyApp());
    // Verify that our counter starts at 0.
    expect(find.text('0'), findsOneWidget);
    expect(find.text('1'), findsNothing);
    // Tap the '+' icon and trigger a frame.
    await tester.tap(find.byIcon(Icons.add));
    await tester.pump();
    // Verify that our counter has incremented.
    expect(find.text('0'), findsNothing);
    expect(find.text('1'), findsOneWidget);
    });
    }

Objective of lcov

  • To see the coverage of the code.
  • To deliver the code with quality.

To perform the test with coverage

install test_coverage library in pubspec.yml under dev_dependencies

dev_dependencies:
    flutter_test:
       sdk: flutter
    test_coverage: ^0.4.2
Enter fullscreen mode Exit fullscreen mode
  • then run test command with flags
flutter test --coverage
Enter fullscreen mode Exit fullscreen mode
  • when test complete it will generate folder ‘coverage” in the project directory, to see the result in visualized, run this commands
genhtml -o coverage coverage/lcov.info
# Open in the default browser (mac):
open coverage/index.html
this is the html report, that generated out looks like.
Enter fullscreen mode Exit fullscreen mode

Alt Text

  • now you will get the coverage result, but I want to present in the GitHub repo how do I do that? you should get a badge!!!

To generate badge image

  • assume that you are at the root of the project
$ yarn init
$ yarn add lcov2badge — more detail here
Enter fullscreen mode Exit fullscreen mode
  • then create a javascript script to generate a badge form the coverage file.
const lcov2badge = require("lcov2badge");
const fs = require("fs");
lcov2badge.badge("./coverage/lcov.info", function (err, svgBadge) {
if (err) throw err;
try {
if (fs.existsSync("./coverage_badge.svg")) {
fs.unlinkSync("./coverage_badge.svg");
console.log("[INFO] remove old file");
}
} catch (err) {
console.error(err);
}
console.log("[INFO] generate coverage image");
fs.writeFile("./coverage_badge.svg", svgBadge, (_) =>
console.log("[INFO] complete")
);
});
view raw covBadgeGen.js hosted with ❤ by GitHub
  • what you get is the ./coverage_badge.svg that you can use inside the README.md file, like this.

Alt Text

![Coverage](./coverage_badge.svg?sanitize=true)
Enter fullscreen mode Exit fullscreen mode
  • the example Github code can be found here!

GitHub logo 3lVv0w / test_lcov_bedge

this repo demonstrate how to generate coverage badge form lcov.info for unit testing




If you have any question/discussion with me, you can contact/ follow me
FB: Krisada Vivek
DEV.to: @3lvv0w

Follow me Krisada Vivek for a more upcoming tech publication

ThankYou! ❤

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

Top comments (0)

Billboard image

📊 A side-by-side product comparison between Sentry and Crashlytics

A free guide pointing out the differences between Sentry and Crashlytics, that’s it. See which is best for your mobile crash reporting needs.

See Comparison

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay