CI with SonarQube and Flutter - Part 1
Tags: flutter, testing, docker, mobile
Published: 2022-06-14 20:16:37

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.
```

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),
      ),
    );
  }
}
```

`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);
  });
}

```

With the project created, in next part we will learn how to download [Docker Desktop](https://docs.docker.com/desktop/mac/install/) according your O.S and then go to [SonarQube website](https://www.sonarqube.org) 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](https://dev.to/matteuus/ci-with-sonarqube-and-flutter-part-2-3gd6)**