DEV Community

Cover image for CI with SonarQube and Flutter - Part 1
Mateus Daniel
Mateus Daniel

Posted on

CI with SonarQube and Flutter - Part 1

Hello everybody, this is my first article, so feel free to comment on how can i get better, I will appreciate it.

In this article, I will show how to use the SonarQube tool with the Flutter framework to improve the code quality, to start that I will describe which versions it`s going to be used to do this

  • Flutter: 3.0.1, Stable version
  • SonarQube: 8.9.5, Community Edition
  • Docker Desktop: 4.9.0

Flutter is a framework made by google that compiles and runs with almost every common platform, from mobile to desktop and even embedded devices, so this is gonna be the start point. as the time pass and your app need to fit with specific requirements, with this in mind tests are a great way to understand if your code does what they have designed for, basically, in Flutter we have three types of tests, they are:

  • Unit test: the first one is used to test the minimal part of your code since you have variables and functions to perform. tip: always try to keep your functions only with a single responsibility, this makes the code clean and testable.
  • Widget test: as the name describe, this kind of test gives us feedback if the widgets are showing correctly for the user.
  • Integration test: the last one is used to perform a real interaction with the app with a set of instructions to cover more code, like modules.

Keep moving on, we need to create a new Flutter project with the command: flutter create project_name, where on project_name you can give a name to your project.

When finished you will see something like:

`

All done!
In order to run your application, type:

  $ cd project_name
  $ flutter run

Your application code is in project_name/lib/main.dart.
Enter fullscreen mode Exit fullscreen mode

just type cd project_name and then code . if you are using visual studio code.

Initially, a project structure comes with a simple counter app and a widget test for the same as you can see below:

lib/main.dart

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<MyHomePage> 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>[
            const Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

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 in the flutter_test package. 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:project_name/main.dart';

void main() {
  testWidgets('Counter increments smoke test', (WidgetTester tester) async {
    // Build our app and trigger a frame.
    await tester.pumpWidget(const 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);
  });
}

Enter fullscreen mode Exit fullscreen mode

With the project created, in next part we will learn how to download Docker Desktop according your O.S and then go to SonarQube website and download the software. With that in mind, hope you enjoy the first part and can't wait to see you in the next one.

CI with SonarQube and Flutter - Part 2

Discussion (7)

Collapse
irdevp profile image
Igor Melo

Nice article! đź‘Źđź‘Ź

Collapse
matteuus profile image
Mateus Daniel Author • Edited on

Thanks for the comment!

Collapse
alyssonmascarenhas profile image
Alysson Keysson

I'm starting to learn flutter, nice article!
You can speak about issues for begginers, such as Clean Architecture and Tests?

Collapse
matteuus profile image
Mateus Daniel Author

Glad to see that you enjoy this article, i will work on this points next time.

Collapse
iurynogueira profile image
Iury Nogueira

Great!

Collapse
matteuus profile image
Mateus Daniel Author • Edited on

I Appreciate your feedback!

Collapse
victoriabispo profile image
Victoria Ricarte Bispo Beserra

Very nice article!!!!