<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mateus Daniel</title>
    <description>The latest articles on DEV Community by Mateus Daniel (@matteuus).</description>
    <link>https://dev.to/matteuus</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F754554%2F1ae29e0a-53d2-4bea-85e7-933c25f930d2.jpeg</url>
      <title>DEV Community: Mateus Daniel</title>
      <link>https://dev.to/matteuus</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/matteuus"/>
    <language>en</language>
    <item>
      <title>My challenges until release my first dart package at pub.dev and how you can make it too</title>
      <dc:creator>Mateus Daniel</dc:creator>
      <pubDate>Fri, 10 Feb 2023 03:42:46 +0000</pubDate>
      <link>https://dev.to/matteuus/my-challenges-until-release-my-first-dart-package-at-pubdev-and-how-you-can-make-it-too-2eep</link>
      <guid>https://dev.to/matteuus/my-challenges-until-release-my-first-dart-package-at-pubdev-and-how-you-can-make-it-too-2eep</guid>
      <description>&lt;p&gt;As part of a Flutter developer routine, in my last four years I was very familiar with widgets components to make the UI, and some business logic of course, so now I've decided to dive into some pure dart code and maybe learn something different this time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reason and the path
&lt;/h2&gt;

&lt;p&gt;Sometimes I used to do some projects using only dart since I want to automatize little tasks in my day as a programmer, in  my job I act as a Tech Lead, and one of my main tasks is to standardize the workflow of mobile developers, setting best practices and also architectural models. To reach all of them the first thing was to make use of a pattern to make commits more understandable, to reach this objective we use the &lt;a href="https://www.conventionalcommits.org/en/v1.0.0/" rel="noopener noreferrer"&gt;conventional commits&lt;/a&gt;, with that we easily make the message commits work as we want, in this article I will focus on that point, so to grant that the commits will be sent with this pattern I've decided to create a little dart project to make it.&lt;/p&gt;

&lt;p&gt;After working on that for a while I've finally published it at pub.dev you can check here: &lt;a href="https://pub.dev/packages/git_helper" rel="noopener noreferrer"&gt;git_helper&lt;/a&gt;, but that's not all, as part of this article I show the basics starting from creating a dart project until publishing it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get started
&lt;/h2&gt;

&lt;p&gt;Consider that you already have the dart on your O.S, if not, download it from &lt;a href="https://dart.dev/get-dart" rel="noopener noreferrer"&gt;Dart SDK&lt;/a&gt;, with that configured you can check if everything is set up with the command &lt;code&gt;dart --version&lt;/code&gt;, if this return a dart version so you have successfully install it on your computer.&lt;/p&gt;

&lt;p&gt;With that configured let's create a new dart project with the command &lt;code&gt;dart create my_project&lt;/code&gt; where &lt;code&gt;my_project&lt;/code&gt; is your project name, so you can give any name that you want, if you are a flutter developer can notice that the project structure is a little bit different, the main folders are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;bin&lt;/code&gt;: where you have your code entry point with the &lt;code&gt;main()&lt;/code&gt; function.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;lib&lt;/code&gt;: here you can write all your logic code that makes things happen.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;test&lt;/code&gt;: this folder, as the name said, it's used to put all your test codes, to test then just type &lt;code&gt;dart test&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After you write your code, you can start the process to publish it, there are some important points to notice here, the main one says that once you publish you can't delete, cause may impact if someone is using it, to make things happen we can use the command &lt;code&gt;dart pub publish --dry-run&lt;/code&gt;, with that we can see a report of what's missing to start the publication, the major points are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;pubspec.yaml&lt;/code&gt;: in this file, you should declare some points like the name, version, description, and platforms, you can take this as an example:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;my_project&lt;/span&gt;
&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;1.0.0&lt;/span&gt;

&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;A simple dart project&lt;/span&gt;
&lt;span class="na"&gt;repository&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://github.com/your_name/your_repository&lt;/span&gt;

&lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;sdk&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;&amp;gt;=2.18.6&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;lt;3.0.0'&lt;/span&gt;

&lt;span class="na"&gt;dev_dependencies&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^1.16.0&lt;/span&gt;

&lt;span class="na"&gt;dependencies&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;interact&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^2.1.1&lt;/span&gt;

&lt;span class="na"&gt;executables&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
  &lt;span class="na"&gt;my_project&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 

&lt;span class="na"&gt;platforms&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;linux&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;macos&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
  &lt;span class="na"&gt;windows&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;README.md&lt;/code&gt;: in this markdown file you should give instructions on how to use your project, here try to cover all that your code does.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;CHANGELOG.md&lt;/code&gt;: this is also a markdown file, every version that will be published should be described here with your changes, you can take this as an example:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;## 1.0.0&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; My first project release.
&lt;span class="p"&gt;-&lt;/span&gt; Implement my amazing feature

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and the last one, but also very important is the license, probably your project doesn't have this file by default, which means you should know what kind of license you want to use for the project, there are many types like GPL, MIT, and BSD each one has your own rules, like an open source project, I will give an example using the MIT license:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The MIT License (MIT)

Copyright (c) [year] [full name of copyright owner]

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is strongly important that you know what your license grant and why you opted for it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Publishing
&lt;/h2&gt;

&lt;p&gt;After all these steps, is finally time to publish your dart code as a package, to do that is more simple than all the processes before, but first, you should have an account on the platform, to make sure just go &lt;a href="https://pub.dev" rel="noopener noreferrer"&gt;pub.dev&lt;/a&gt; and click on sign in button, now it's time to make the magic happen, just type &lt;code&gt;dart pub publish&lt;/code&gt;, if is your first time the terminal, will appear a link to authenticate with you user, after that, all the upload process will be done automatically and that's it, just pay attention that your project will be revised, this process could take a while, in my case 30 minutes, after that, you have your package on pub.dev and ready to share with anyone in the world :).&lt;/p&gt;

&lt;h2&gt;
  
  
  Considerations
&lt;/h2&gt;

&lt;p&gt;Since I've planned to create this git helper project and share it on pub.dev to help me and my teammates, you could have many opportunities to make something cool that could help someone, with all that said, really hope you have understood and enjoyed this journey, see you next time.&lt;/p&gt;

&lt;p&gt;My final project is the &lt;a href="https://pub.dev/packages/git_helper" rel="noopener noreferrer"&gt;git_helper&lt;/a&gt;, you can download my package and try it, if you want to improve, PRs are always welcome.&lt;/p&gt;

</description>
      <category>leadership</category>
      <category>career</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Testing your Flutter app</title>
      <dc:creator>Mateus Daniel</dc:creator>
      <pubDate>Thu, 02 Feb 2023 20:11:29 +0000</pubDate>
      <link>https://dev.to/matteuus/testing-your-flutter-app-ao0</link>
      <guid>https://dev.to/matteuus/testing-your-flutter-app-ao0</guid>
      <description>&lt;p&gt;Hello everybody, today we're gonna talk about tests with flutter and the importance of doing that in your projects, so let's get started.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why do we need to test?
&lt;/h2&gt;

&lt;p&gt;As our flutter project grows the importance of testing it grows too, so since your code was well made using good patterns and following the best practices, it makes easier to implement a test to grant you the app works as you've projected for. &lt;/p&gt;

&lt;h2&gt;
  
  
  Concept
&lt;/h2&gt;

&lt;p&gt;There are some concepts of how to write tests and provide better and well-projected apps, one of the most common is the TDD (Test Driven Development), which says that you have to write your test first and then write the code, and repeat the process of how many times you need to ensure that everything is passing in test and the code only does what it has to do.&lt;/p&gt;

&lt;h2&gt;
  
  
  Types of test
&lt;/h2&gt;

&lt;p&gt;With Flutter we have three types of tests, they are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Unit test: as the name said, this kind of test has the purpose of checking if the minimum part of your code is working as expected, this includes for example functions and classes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Widget test: This one verifies if the widgets are working as expected, so the purpose of this kind of test is to check the UI consistency.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Integration test: The last one, the integration test, it's personally my favorite type, this is like a mix of the two types of the test described before, with this you can check an entire flow, so you can verify if the checkout of an e-commerce app is working as expected for example.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With all that said let's dive inside some examples to understand a little bit better. In this case, I will show how to test a login because it is a common feature for most of the projects.&lt;/p&gt;

&lt;p&gt;To get started, suppose that you've already the flutter in your O.S then just create a project with the command &lt;code&gt;flutter create login_test&lt;/code&gt; where the name &lt;code&gt;login_test&lt;/code&gt; can be changed if you wanna give another name for your project, with this created verify in your root directory and you be able to find a folder called &lt;code&gt;test&lt;/code&gt;, all of your testing code should be inside that and by default, all the classes created for this purpose have to be in the the &lt;code&gt;_test.dart&lt;/code&gt; to let the language recognize this as a test class.&lt;/p&gt;

&lt;p&gt;To get started using the TDD concept, let's create the unit test first before the implementation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Unit test
&lt;/h2&gt;

&lt;p&gt;delete the file that comes with the project and create a file called &lt;code&gt;unit_login_test.dart&lt;/code&gt; in &lt;code&gt;test&lt;/code&gt; folder with the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:flutter_test/flutter_test.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Login controller'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"success login"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;LoginController&lt;/span&gt; &lt;span class="n"&gt;controller&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;LoginController&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"username"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"failed login"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;LoginController&lt;/span&gt; &lt;span class="n"&gt;controller&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;LoginController&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"invalidUsername"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"invalidPassword"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We create a main function, which starts in this case these tests, we have to import the class &lt;code&gt;flutter_test&lt;/code&gt; to execute as we want, to do this we create a &lt;code&gt;group&lt;/code&gt; and inside put all our test cases, initiate our class and execute the function with some given parameters, and the expected return in expect test function to do that we imagine that we have a controller and inside a login function that receives the username and the password and if match returns a boolean. To execute now we have to create a file called &lt;code&gt;login_controller.dart&lt;/code&gt; inside the &lt;code&gt;lib&lt;/code&gt; folder with the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LoginController&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"username"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With that, we only have to import this class inside our test class and execute it to see the result &lt;/p&gt;

&lt;p&gt;&lt;code&gt;import 'package:login_test/login_controller.dart';&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgizzgl646gg2hhslbsjl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgizzgl646gg2hhslbsjl.png" alt="Unit test passing" width="530" height="72"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now let's move to the second type of test&lt;/p&gt;

&lt;h2&gt;
  
  
  Widget test
&lt;/h2&gt;

&lt;p&gt;Like the unit test, we will create the test file and implement that, to get started create a file called &lt;code&gt;widget_login_test.dart&lt;/code&gt; and put the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:flutter/material.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:flutter_test/flutter_test.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;testWidgets&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Login UI"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tester&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;tester&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;pumpWidget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;MaterialApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;home:&lt;/span&gt; &lt;span class="n"&gt;LoginPage&lt;/span&gt;&lt;span class="p"&gt;()));&lt;/span&gt;

    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;byKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"usernameTextField"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;byKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"passwordTextField"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;loginButton&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;byKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"loginButton"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

    &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;findsOneWidget&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;findsOneWidget&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;loginButton&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;findsOneWidget&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;tester&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;enterText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"username"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;tester&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;enterText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;tester&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;tap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;loginButton&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;tester&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;pump&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;successMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;byKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'success'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;successMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;findsOneWidget&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The widget test renders the widgets and you can perform actions like &lt;code&gt;tap()&lt;/code&gt; and &lt;code&gt;enterText()&lt;/code&gt; to interact with the components, in this test case we need to search using the Key parameter, you can do it using a text, but the Key gives you more confidence about getting the right thing. Now to implement the code just create a file called &lt;code&gt;login_page.dart&lt;/code&gt; and put this code below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:flutter/material.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:login_test/login_controller.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;LoginController&lt;/span&gt; &lt;span class="n"&gt;loginController&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;LoginController&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="n"&gt;TextEditingController&lt;/span&gt; &lt;span class="n"&gt;usernameController&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TextEditingController&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;TextEditingController&lt;/span&gt; &lt;span class="n"&gt;passwordController&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TextEditingController&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LoginPage&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;StatelessWidget&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;LoginPage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Scaffold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;mainAxisAlignment:&lt;/span&gt; &lt;span class="n"&gt;MainAxisAlignment&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;center&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;children:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="n"&gt;TextField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nl"&gt;controller:&lt;/span&gt; &lt;span class="n"&gt;usernameController&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nl"&gt;key:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'usernameTextField'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
          &lt;span class="p"&gt;),&lt;/span&gt;
          &lt;span class="n"&gt;TextField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nl"&gt;controller:&lt;/span&gt; &lt;span class="n"&gt;passwordController&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nl"&gt;key:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'passwordTextField'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
          &lt;span class="p"&gt;),&lt;/span&gt;
          &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;SizedBox&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;height:&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
          &lt;span class="n"&gt;ElevatedButton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nl"&gt;key:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'loginButton'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Login"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="nl"&gt;onPressed:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="c1"&gt;// Example login logic&lt;/span&gt;
              &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;loginController&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                  &lt;span class="n"&gt;usernameController&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;passwordController&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;showDialog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                  &lt;span class="nl"&gt;context:&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="nl"&gt;builder:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;AlertDialog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                    &lt;span class="nl"&gt;key:&lt;/span&gt; &lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'success'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                    &lt;span class="nl"&gt;title:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Login Successful"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                  &lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="p"&gt;);&lt;/span&gt;
              &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we only need to import the &lt;code&gt;LoginPage&lt;/code&gt; in our widget test file, just type &lt;code&gt;import 'package:login_test/login_page.dart';&lt;/code&gt; with that you can execute your test and should see something like &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyax9zfxi0saeu2t2yzqf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyax9zfxi0saeu2t2yzqf.png" alt="Widget test" width="530" height="72"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Integration test
&lt;/h2&gt;

&lt;p&gt;This is the last type of test, it works by executing a complete feature, to do that you need a real device, to start we need to add a new dependency in our file &lt;code&gt;pubspec.yaml&lt;/code&gt; in the section &lt;code&gt;dev_dependencies&lt;/code&gt; called &lt;code&gt;integration_test: sdk: flutter&lt;/code&gt;, after this just type &lt;code&gt;flutter pub get&lt;/code&gt; to update the dependencies, with this set up complete you need to create a folder called &lt;code&gt;integration_test&lt;/code&gt; in the root directory, then insert a file who you can call &lt;code&gt;app_test.dart&lt;/code&gt;with the code below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:flutter/material.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:flutter_test/flutter_test.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:integration_test/integration_test.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:login_test/login_page.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;IntegrationTestWidgetsFlutterBinding&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ensureInitialized&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="n"&gt;WidgetsFlutterBinding&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ensureInitialized&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'LoginPage'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;testWidgets&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Login UI"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tester&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;tester&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;pumpWidget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;MaterialApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;home:&lt;/span&gt; &lt;span class="n"&gt;LoginPage&lt;/span&gt;&lt;span class="p"&gt;()));&lt;/span&gt;

      &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;byKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"usernameTextField"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
      &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;byKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"passwordTextField"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
      &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;loginButton&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;byKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"loginButton"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

      &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;findsOneWidget&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;findsOneWidget&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;loginButton&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;findsOneWidget&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;tester&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;enterText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"username"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;tester&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;pumpAndSettle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;seconds:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;tester&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;enterText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;tester&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;pumpAndSettle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;seconds:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;tester&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;tap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;loginButton&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;tester&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;pumpAndSettle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;seconds:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
      &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;successMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;byKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'success'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
      &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;successMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;findsOneWidget&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;this code is very similar to the widget test, but we have a few differences, we use &lt;code&gt;IntegrationTestWidgetsFlutterBinding.ensureInitialized();&lt;/code&gt; and &lt;code&gt;WidgetsFlutterBinding.ensureInitialized();&lt;/code&gt; to ensure that we have the integration test and the widgets ready to start the process.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus
&lt;/h2&gt;

&lt;p&gt;With an additional part of this article, we gonna see how to get a visual report of the test coverage, if you don't wanna learn this just skip to the conclusion.&lt;/p&gt;

&lt;p&gt;to do that we have to run in terminal &lt;code&gt;flutter test --coverage&lt;/code&gt;, after executing this should create a folder called coverage with a file named lcov.info inside as we see below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff97uoy7j1gm1romn06c5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff97uoy7j1gm1romn06c5.png" alt="Coverage folder" width="474" height="86"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;after that you have to convert this file into a bunch of files to be read by a web server, to continue just type in your terminal &lt;code&gt;genhtml coverage/lcov.info -o coverage/html&lt;/code&gt; where the &lt;code&gt;coverage/lcov.info&lt;/code&gt; is the path of the file created above and the &lt;code&gt;coverage/html&lt;/code&gt; after the flag -o is the directory where I want to save the generated files when this part finish, you will see a folder with the given name created where you choose.&lt;/p&gt;

&lt;p&gt;to finish we have to expose this directory to access in a web browser, to do that I recommend getting the &lt;code&gt;dhttpd&lt;/code&gt; library from &lt;a href="https://pub.dev/packages/dhttpd" rel="noopener noreferrer"&gt;here&lt;/a&gt; just type in your terminal &lt;code&gt;dart pub global activate dhttpd&lt;/code&gt; with this you've downloaded the library globally, after this just type &lt;code&gt;dhttpd --path coverage/html/&lt;/code&gt; and open a browser to put the URL &lt;code&gt;http://localhost:8080&lt;/code&gt; and finally you will be able to see a full report about your test like you see bellow:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw1iisor30wrk3zzoxgfa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw1iisor30wrk3zzoxgfa.png" alt="Flutter coverage" width="800" height="434"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With this we finish the bonus part, this could be essential to understand where the code is not covered and where the tests are failing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;As we see, the tests give us more confidence in the final result focus on the release, this process can take more time to finish a feature, but the gain with that is more valuable than if a bug was reported after distribute of the project, so hope everybody understands how to do and the importance, hope to see you next time.&lt;/p&gt;

&lt;p&gt;If you wanna see the full code, i've uploaded the code, the link is: &lt;a href="https://github.com/Matteuus/login_test" rel="noopener noreferrer"&gt;Repository&lt;/a&gt;&lt;/p&gt;

</description>
      <category>offers</category>
      <category>cryptocurrency</category>
      <category>web3</category>
    </item>
    <item>
      <title>How to prevent bad commits and test code with lefthook and integrate with Flutter</title>
      <dc:creator>Mateus Daniel</dc:creator>
      <pubDate>Fri, 17 Jun 2022 19:20:35 +0000</pubDate>
      <link>https://dev.to/matteuus/how-to-prevent-bad-commits-and-test-code-with-lefthook-and-integrate-with-flutter-1ni4</link>
      <guid>https://dev.to/matteuus/how-to-prevent-bad-commits-and-test-code-with-lefthook-and-integrate-with-flutter-1ni4</guid>
      <description>&lt;p&gt;Lefthook is a tool to give us more confidence in our commits, it work with a lot of programming languages and Frameworks such as Flutter, Go, Ruby, and many others, and even can execute some tasks like lint and test, with that said let's configure this to work with.&lt;/p&gt;

&lt;p&gt;To get started it depends on your O.S, with Linux distributions like Ubuntu and Debian you have two different ways to do that&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;using &lt;code&gt;curl&lt;/code&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -1sLf 'https://dl.cloudsmith.io/public/evilmartians/lefthook/setup.deb.sh' | sudo -E bash
sudo apt install lefthook
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you don't have curl installed just type: &lt;code&gt;sudo apt install curl&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;using &lt;a href="https://snapcraft.io/docs/installing-snap-on-ubuntu" rel="noopener noreferrer"&gt;Snap&lt;/a&gt;:
you just have to type: &lt;code&gt;snap install --classic lefthook&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are using a macOS, you can try with &lt;a href="https://brew.sh/index_pt-br" rel="noopener noreferrer"&gt;Homebrew&lt;/a&gt;, to do that just: &lt;code&gt;brew install lefthook&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;After this step, you should have the lefthook installed on your machine, let's see how to use it&lt;/p&gt;

&lt;p&gt;To use in your project you have to go to the terminal and then move it to root, after that you have to type: &lt;code&gt;lefthook install&lt;/code&gt; and a file named &lt;code&gt;lefthook.yml&lt;/code&gt; has to be created in your project, in this example I created a Flutter project and execute the command, you can see the result below: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F55fm11scia593r8nb07e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F55fm11scia593r8nb07e.png" alt="Lefthook created" width="377" height="585"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can set some instructions at some moment of the commit process such as &lt;code&gt;pre-commit&lt;/code&gt;, &lt;code&gt;pre-push&lt;/code&gt;, and &lt;code&gt;commit-msg&lt;/code&gt;, these instructions will be executed depending of what commit process they are inside, let me show an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pre-commit:
  parallel: true
  commands:
    tests:
      run: flutter test
    analyze:
      run: flutter analyze
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this code block above I'm executing some tasks in parallel before the commit process is done, in that case, I'm running the Flutter test and analyzing and the commit will be finished only if these tasks have been completed, let's have another example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pre-push:
  parallel: true
  commands:
    tests:
      run: flutter test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, with this code block above the task will run only when the push process has been started, in this case, I'm executing some Flutter test and the commit only will be done will all tests have been completed with success &lt;/p&gt;

&lt;p&gt;To finish, let's learn how to use the &lt;code&gt;commit-msg&lt;/code&gt; block, in our case we will check the commit message using as a base the conventional commits spec, if you don't know about this concept you can &lt;a href="https://gist.github.com/Zekfad/f51cb06ac76e2457f11c80ed705c95a3" rel="noopener noreferrer"&gt;click here&lt;/a&gt;, so let's move, in this example, we have to create a folder called &lt;code&gt;bin&lt;/code&gt; and inside then create a file called &lt;code&gt;commit_message.dart&lt;/code&gt;, the result should be&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fofudszvsrrl7wqzrylf6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fofudszvsrrl7wqzrylf6.png" alt="create folder and file" width="373" height="49"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Inside &lt;code&gt;bin/commit_message.dart&lt;/code&gt; file, we can insert the below code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import 'dart:io';

dynamic main() {
  final rootDir = Directory.current;
  final commitFile = File("${rootDir.path}/.git/COMMIT_EDITMSG");
  final commitMessage = commitFile.readAsStringSync();

  final regExp = RegExp(
    r'(bugfix|feature|hotfix|none|chore|refactor|doc|style|test)(\(\w+\):\s?)(\[\w+-\d+])(.+)',
  );

  final valid = regExp.hasMatch(commitMessage);
  if (!valid) exitCode = 1;
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This file basically gets the commit message and then passes a regex to check if they are in concern with the conventional commits, finally in our &lt;code&gt;lefthook.yml&lt;/code&gt; file we can put&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;commit-msg:
  commands:
    validate:
      run: flutter pub run bin/commit_message.dart
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With that, we execute the file created to check with lefthook if the message commit has matched with what was expected, in my case the final looks like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pre-commit:
  parallel: true
  commands:
    tests:
      run: flutter test
    analyze:
      run: flutter analyze
    lint_code:
      glob: '*.dart'
      run: dart fix --dry-run lib &amp;amp;&amp;amp; git add .
    format_code:
      glob: '*.dart'
      run: flutter format {staged_files} &amp;amp;&amp;amp; git add .       

commit-msg:
  commands:
    validate:
      run: flutter pub run bin/commit_message.dart  

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For now, you've learned how to integrate this tool to keep your commits more safe and clean with clear messages, I hope that you liked it and see you in the next article.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/evilmartians/lefthook" rel="noopener noreferrer"&gt;Lefthook repo&lt;/a&gt;&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>git</category>
    </item>
    <item>
      <title>CI with SonarQube and Flutter - Part 2</title>
      <dc:creator>Mateus Daniel</dc:creator>
      <pubDate>Wed, 15 Jun 2022 17:02:07 +0000</pubDate>
      <link>https://dev.to/matteuus/ci-with-sonarqube-and-flutter-part-2-3gd6</link>
      <guid>https://dev.to/matteuus/ci-with-sonarqube-and-flutter-part-2-3gd6</guid>
      <description>&lt;p&gt;&lt;strong&gt;This is the second part of the article, to go to the first one just &lt;a href="https://dev.to/matteuus/ci-with-sonarqube-and-flutter-part-1-4hoi"&gt;click here&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Welcome back to everyone, in this second part as I said at the end of the last article we will download Docker and the SonarQube image, so let's go.&lt;/p&gt;

&lt;p&gt;We should start going to &lt;a href="https://docs.docker.com/desktop/mac/install/" rel="noopener noreferrer"&gt;Docker Desktop&lt;/a&gt; and the website will show something like: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh4mepv0f8d8gwjjikqqk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh4mepv0f8d8gwjjikqqk.png" alt="Docker download" width="800" height="393"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In my case the downloaded version will be the mac with an apple chip (arm architecture) because I'm using the m1 processor, if you're using a different O.S is just change go to &lt;a href="https://docs.docker.com/desktop/windows/install/" rel="noopener noreferrer"&gt;Docker for windows&lt;/a&gt; or &lt;a href="https://docs.docker.com/desktop/linux/install/" rel="noopener noreferrer"&gt;Docker for linux&lt;/a&gt; and proceed with the installation in mac after download just move the docker app to Applications folder like the image below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9pki31b7grag4kuemr61.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9pki31b7grag4kuemr61.png" alt="Docker .dmg" width="800" height="376"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When the installation process is done you have to open the docker application and probably should see something like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr4cyikwrxv8mpayr26d6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr4cyikwrxv8mpayr26d6.png" alt="Docker Installed" width="800" height="453"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we have a Flutter project created and the Docker downloaded, the next step is to download the SonarQube software, in this tutorial will be used the image to containerize, and for that, we have to open the &lt;a href="https://www.sonarqube.org/downloads/" rel="noopener noreferrer"&gt;SonarQube Download&lt;/a&gt; page, with that open you will see:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1ic1uooq8iq6dw0h0oq6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1ic1uooq8iq6dw0h0oq6.png" alt="SonarQube download" width="800" height="390"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now to download the image to use with docker just click on the Available From DockerHub button to move to the next page, when the load is finished move down a little bit until seeing something like the image below: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkbkn9fgc9hmkw4px5uiw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkbkn9fgc9hmkw4px5uiw.png" alt="SonarQube Docker Image" width="800" height="393"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When reached this part I have some notes to give, first of all, we will use the community edition because is open source and is enough for this tutorial proposal, the second point, users with a processors like Intel and AMD just need to type &lt;code&gt;docker pull sonarqube:9.5-community&lt;/code&gt; and download the official version, for users like me who use an ARM processor there is not an official version and for that, we have some trusted options to keep moving this tutorial, just type &lt;code&gt;docker pull mwizner/sonarqube&lt;/code&gt;, with that you should be able to download an image of version 9.4 who was made to this specific processor type.&lt;/p&gt;

&lt;p&gt;With the image downloaded, we go back to Docker and in the Images option we can see that like: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuaodjxyzoggr8i7qoloj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuaodjxyzoggr8i7qoloj.png" alt="Docker Images" width="800" height="452"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can also check type in terminal &lt;code&gt;docker images&lt;/code&gt;, and see something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;REPOSITORY                                    TAG               IMAGE ID       CREATED        SIZE
mwizner/sonarqube                             8.9.5-community   f5e2e7d2d122   5 months ago   521MB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Probably you will see just one image, and that's the option you chose, right now we should create a container with this image, and for that, we need to type in terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker create --name sonarqubeapp -p 9000:9000 f5e2e7d2d122
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where in parameter &lt;code&gt;--name&lt;/code&gt; we can give a name for our container in &lt;code&gt;-p&lt;/code&gt; we pass the 9000 port and finally, we should pass the image id, in that case, f5e2e7d2d122, after running this command we can move to container option in Docker Desktop and see something like this image:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6haxs6p7s0ccpss01i14.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6haxs6p7s0ccpss01i14.png" alt="Docker Containers" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this option you will notice that now we have a container created with the SonarQube image, now just run the container to start the software, for that we can just click the start button in the container created or just type &lt;code&gt;docker start sonarqubeapp&lt;/code&gt; in the terminal, where sonarquebeapp should be the name of the container.&lt;/p&gt;

&lt;p&gt;While the container is opening you can open your browser and type &lt;code&gt;http://localhost:9000/&lt;/code&gt;, after starting you will be able to see the login page:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp4l45wmoq596lsz1vrhm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp4l45wmoq596lsz1vrhm.png" alt="SonarQube login page" width="800" height="402"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By default to log in for the first time, just type admin in the login and password fields, you will be redirected to the home page and will see that:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc9w1pp1lp0qq0jxd6y69.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc9w1pp1lp0qq0jxd6y69.png" alt="SonarQube homepage" width="800" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At that point I have to give a note, Dart and Flutter are not supported officially by SonarQube yet, so for that reason, we need to download a plug-in that will do the work we need, to do that we have to open &lt;a href="https://github.com/insideapp-oss/sonar-flutter" rel="noopener noreferrer"&gt;this repository&lt;/a&gt; and go to releases page to download the last version, until this article date the version is 0.4.0. after downloading the .jar we move to the download folder in terminal type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker cp sonar-flutter-plugin-0.4.0.jar sonarqubeapp:/opt/sonarqube/extensions/plugins
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this command we copy the .jar file to our container, after that we need to restart to see the changes, just type &lt;code&gt;docker restart sonarqubeapp&lt;/code&gt; and wait for it.&lt;/p&gt;

&lt;p&gt;Log in again and to check if the plug-in was correctly installed click on the administration tab, later click on the Marketplace tab inside the admin options, and finally in Plugins click on Installed to see the page like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdrqb7xnpbg0dnwwqvcm9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdrqb7xnpbg0dnwwqvcm9.png" alt="SonarQube Flutter plugin installed" width="800" height="404"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With all that set up we now have to download the last thing (i promise this will be the last 😅), this will be the scanner to show our reports locally, to do that go to &lt;a href="https://docs.sonarqube.org/latest/analysis/scan/sonarscanner/" rel="noopener noreferrer"&gt;Sonar Scanner Download&lt;/a&gt;, after download unzip the file in any folder you want, I recommended to do that in your home folder.&lt;/p&gt;

&lt;p&gt;Now you will have to add the path in your &lt;code&gt;.bash_profile&lt;/code&gt; or &lt;code&gt;.zshrc&lt;/code&gt; (or in environment variables in windows), it depends on what kind of terminal you use, type: &lt;code&gt;export PATH="$HOME/sonar-scanner-4.7.0.2747-macosx/bin:$PATH"&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To finish now we have to set up our flutter project to export the reports to Sonar, to start the configuration we open our project and then create a file on root called &lt;code&gt;sonar-project.properties&lt;/code&gt;, and inside that you should put:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Project identification, either hardcode it or use Environment variables
sonar.projectKey=my-project-key
sonar.projectName=Project Name
sonar.login=my-long-token

# The host URL
sonar.host.url=http://localhost:9000

# Source code location.
# Path is relative to the sonar-project.properties file. Defaults to .
# Use commas to specify more than one folder.
sonar.sources=lib
sonar.tests=test

# Encoding of the source code. Default is default system encoding.
sonar.sourceEncoding=UTF-8

# exclude generated files
sonar.exclusions=test/**/*_test.mocks.dart,lib/**/*.g.dart
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this file created, go back to the SonarQube home page, and let's create a project manually, to do that just click on Button Add Project and the click the Manually option:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftq8rcf0043g18cgvpwea.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftq8rcf0043g18cgvpwea.png" alt="SonarQube Create project" width="382" height="174"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, we give a project key and a display name to the project and click on the setup button, next page the Sonar will ask you to generate a token, so create a name for your token and click in generate, this will show you a token, you need to copy and go back to &lt;code&gt;sonar-project.properties&lt;/code&gt; file and fill the projectKey, projectName and token with what was provided.&lt;/p&gt;

&lt;p&gt;With this file created and configured, we run some commands to store the tests and report to Sonar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flutter test --machine --coverage &amp;gt; tests.output
sonar-scanner
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When finishing this, you can refresh your SonarQube page to see the app insights:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv3t8100525ryl4fu4kfl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv3t8100525ryl4fu4kfl.png" alt="SonarQube analyasis" width="800" height="129"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In your homepage will have a banner and when you click on then you can see more feedback about your project like the image below: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxplrisqkam7el1xw73co.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxplrisqkam7el1xw73co.png" alt="SonarQube stats" width="800" height="370"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With all this configured you will be able to get all the information needed to improve your code, with this part finished, hope you enjoy it, and feel free to comment.&lt;/p&gt;

&lt;p&gt;Bonus: I will make a new article to level up this integration using pipelines in the remote repository and ngrok, as soon as I post I will put the link here, for now, that's all, thanks for everyone.&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>testing</category>
      <category>docker</category>
      <category>mobile</category>
    </item>
    <item>
      <title>CI with SonarQube and Flutter - Part 1</title>
      <dc:creator>Mateus Daniel</dc:creator>
      <pubDate>Tue, 14 Jun 2022 20:16:37 +0000</pubDate>
      <link>https://dev.to/matteuus/ci-with-sonarqube-and-flutter-part-1-4hoi</link>
      <guid>https://dev.to/matteuus/ci-with-sonarqube-and-flutter-part-1-4hoi</guid>
      <description>&lt;p&gt;Hello everybody, this is my first article, so feel free to comment on how can i get better, I will appreciate it.&lt;/p&gt;

&lt;p&gt;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&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Flutter: 3.0.1, Stable version&lt;/li&gt;
&lt;li&gt;SonarQube: 8.9.5, Community Edition&lt;/li&gt;
&lt;li&gt;Docker Desktop: 4.9.0 &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;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:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;li&gt;Widget test: as the name describe, this kind of test gives us feedback if the widgets are showing correctly for the user.&lt;/li&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Keep moving on, we need to create a new Flutter project with the command: &lt;code&gt;flutter create project_name&lt;/code&gt;, where on project_name you can give a name to your project.&lt;/p&gt;

&lt;p&gt;When finished you will see something like:&lt;/p&gt;

&lt;p&gt;`&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;All done!
In order to run your application, type:

  $ cd project_name
  $ flutter run

Your application code is in project_name/lib/main.dart.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;just type &lt;code&gt;cd project_name&lt;/code&gt; and then &lt;code&gt;code .&lt;/code&gt; if you are using visual studio code.&lt;/p&gt;

&lt;p&gt;Initially, a project structure comes with a simple counter app and a widget test for the same as you can see below:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;lib/main.dart&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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&amp;lt;MyHomePage&amp;gt; createState() =&amp;gt; _MyHomePageState();
}

class _MyHomePageState extends State&amp;lt;MyHomePage&amp;gt; {
  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: &amp;lt;Widget&amp;gt;[
            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`



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;// This is a basic Flutter widget test.&lt;br&gt;
//&lt;br&gt;
// To perform an interaction with a widget in your test, use the WidgetTester&lt;br&gt;
// utility in the flutter_test package. For example, you can send tap and scroll&lt;br&gt;
// gestures. You can also use WidgetTester to find child widgets in the widget&lt;br&gt;
// tree, read text, and verify that the values of widget properties are correct.&lt;/p&gt;

&lt;p&gt;import 'package:flutter/material.dart';&lt;br&gt;
import 'package:flutter_test/flutter_test.dart';&lt;/p&gt;

&lt;p&gt;import 'package:project_name/main.dart';&lt;/p&gt;

&lt;p&gt;void main() {&lt;br&gt;
  testWidgets('Counter increments smoke test', (WidgetTester tester) async {&lt;br&gt;
    // Build our app and trigger a frame.&lt;br&gt;
    await tester.pumpWidget(const MyApp());&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// 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);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;});&lt;br&gt;
}&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


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)**
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>flutter</category>
      <category>testing</category>
      <category>docker</category>
      <category>mobile</category>
    </item>
  </channel>
</rss>
