3

How do I get 100% code coverage on a main function for an application that looks like this?

lib/main.dart
import 'package:flutter/material.dart';

void main() {
  runApp(App());
}

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(body: Center(child: Text('Home Page'))),
    );
  }
}
test/main_test.dart
import 'package:flutter_test/flutter_test.dart';
import 'package:example/main.dart';

void main() {
  testWidgets('Counter increments smoke test', (WidgetTester tester) async {
    await tester.pumpWidget(MyApp());

    // Verify that the init page is the Home Page.
    expect(find.text('Home Page'), findsOneWidget);
  });
}

--

Recreating code coverage:

$ flutter test --coverage --coverage-path ./coverage/lcov.info
$ genhtml ./coverage/lcov.info -o ./coverage/html

Output

...
Generating output.
Processing file lib/main.dart
Writing directory view page.
Overall coverage rate:
  lines......: 66.7% (4 of 6 lines)
  functions..: no data found

and the

lcov.info
SF:lib/main.dart
DA:3,0
DA:4,0
...

The only "uncovered" code is:

void main() {
  runApp(App());
}

How should I write a test to ensure that this function is covered? Can it be done out-side of an integration test?

Apealed
  • 1,415
  • 8
  • 29

1 Answers1

1

mian function is an entry point of Flutter application. Usually there are a lot of environment settings and DI instructions for your working app inside main (or at least near it) that should be overridden from test.

Unit/widget tests have their own overridden settings, test doubles for tested class and another main entry point (as you can see from your own example). Test settings usually take place in setUp() function of main.

Resume: It is ok that your tests don't call main app function. They have their own main. What about 100% code coverage - this purpose not justified. Good coverage percent depends on your testing policy. As for me, I guess 70% is good.

Mol0ko
  • 2,938
  • 1
  • 18
  • 45
  • I agree with you, but there are occasions that you insert initializations inside the `main` function. The value of ensuring that you cover `main` in these cases are important so that you are initializing those dependencies. What would be the approach in a case like that? – Apealed Apr 06 '21 at 13:59
  • 1
    The only solution I see is to move all initialization code you want to test from `main` function to other functions or classes that can be tested. `main` itself cant be tested because it is an entry point without result to return. – Mol0ko Apr 06 '21 at 14:44
  • Late to the conversation, but making sure the main method works is what [integration testing](https://docs.flutter.dev/cookbook/testing/integration/introduction) is for (although it still doesn't count towards coverage). In an integration test, you will start it by calling the main method. – Clavum Apr 21 '23 at 16:49