Reader small image

You're reading from  Flutter Cookbook, Second Edition - Second Edition

Product typeBook
Published inMay 2023
Reading LevelIntermediate
PublisherPackt
ISBN-139781803245430
Edition2nd Edition
Languages
Tools
Right arrow
Author (1)
Simone Alessandria
Simone Alessandria
author image
Simone Alessandria

Simone Alessandria wrote his first program when he was 12. It was a text-based fantasy game for the Commodore 64. Now, he is a trainer (MCT), author, speaker, passionate software architect, and always a proud coder. He is the founder and owner of Softwarehouseit. His mission is to help developers achieve more through training and mentoring. He has authored several books on Flutter, including Flutter Projects, published by Packt, and web courses on Pluralsight and Udemy.
Read more about Simone Alessandria

Right arrow

Creating a unit test

There are several advantages of using unit tests in Flutter, including improving the overall quality of your code, ease of debugging, and better design. When writing good tests, you may also reduce the time required to maintain your code in the long run. Writing unit tests requires some practice, but it’s well worth your time and effort.

In this recipe, you’ll see how to write a simple unit test.

Getting ready

You should have created the default Flutter app as shown in the previous recipe before writing a unit test.

How to do it...

You will now update the default Flutter app: you will change the color of You have pushed the button this many times:. The text will be red for even numbers, and green for odd numbers, as shown in Figure 2.9:

Figure 2.9: Red text for even numbers

  1. In the main.dart file in the lib folder, at the bottom of the file, and out of any class, create a method that returns true when the number passed is even, and false when the number is odd:
    bool isEven(int number) {
        if (number % 2 == 0) {
          return true;
        } else {
          return false;
        }
      }
    
  2. At the top of the _MyHomePageState class, under the int _counter = 0; declaration, declare Color, and set it to red:
    Color color = Colors.red;   
    
  3. In the _incrementCounter method, edit the setState call, so that it changes the color value:
    void _incrementCounter() {
        setState(() {
          _counter++;
          if (isEven(_counter)) {
            color = Colors.red;
          } else {
            color = Colors.green;
          }
        });
      }
    
  4. In the build method, edit the text containing You have pushed the button this many times:, so that you change its color and size, and remove its const keyword, as shown below:
    Text(
      'You have pushed the button this many times:',
      style: TextStyle(
         color: color,
         fontSize: 18,
      )
    ),
    
  5. Run the app; you should see the color of the text changing each time you press the button.

Now that the app is ready, let’s test whether the isEven function works as expected.

  1. In the tests folder, create a new file, called unit_test.dart.
  2. At the top of the new file, import the flutter_test.dart library and your project’s main.dart file (note that you may have to change hello_flutter to your package name if you named your app differently):
    import 'package:flutter_test/flutter_test.dart';
    import 'package:hello_flutter/main.dart';
    
  3. Create a main method under the import statements:
    void main() {}
    
  4. In the main method, call the test method, passing Is Even as its name and calling the isEven method twice, and checking its results, as shown here:
    void main() {
      test('Is Even', () {
        bool result = isEven(12);
        expect(result, true);
        result = isEven(123);
        expect(result, false);
      });
    }
    
  5. Run the test by typing flutter test in your Terminal. You should see the All tests passed! message.
  6. Instead of writing a single test method, let’s create two separate tests:
    void main() {
        test('Is Even', () {
          bool result = isEven(12);
          expect(result, true);
        });
        test('Is Odd', () {
          bool result = isEven(123);
          expect(result, false);
        });
    }
    
  7. Run the tests with the flutter test command in your Terminal, and note the success message that appears again in the Terminal: All tests passed.
  8. Make one of the tests fail:
    void main() {
        test('Is Even', () {
          bool result = isEven(12);
          expect(result, true);
        });
        test('Is Odd', () {
          bool result = isEven(123);
          expect(result, true);
        });
    }
    
  9. Run the test again, with the flutter test command in your Terminal. You should see an error, as shown in Figure 2.10:

Figure 2.10: Terminal showing failing test

  1. Note the error message, showing the name of the failing test (Is Odd in this case).
  2. Let’s group the two tests together using the group method:
    void main() {
      group('Iseven group', () {
        test('Is Even', () {
          bool result = isEven(12);
          expect(result, true);
        });
        test('Is Odd', () {
          bool result = isEven(123);
          expect(result, true);
        });
      });
    }
    
  3. Run the test and note the error message has changed, adding the group name to the name of the failing test.

Figure 2.11: Terminal showing failing test with group name

  1. Edit the Is Odd test as shown below, then run the test again, and note that the error has been fixed.
    test('Is Odd', () {
          bool result = isEven(123);
          expect(result, false);
        });
    

How it works...

You can use unit tests in Flutter to test specific parts of your code, like functions, methods, and classes.

In this recipe, you wrote a simple function, called isEven, that returns true when the number passed as an argument is even, and false when it’s odd:

bool isEven(int number) {
    if (number % 2 == 0) {
      return true;
    } else {
      return false;
    }
  }

Probably there isn’t much need to test a function as simple as this one, but as your business logic evolves and gets more complex, testing your units of code becomes important.

When you create a new project, you’ll find a test directory in your project’s root folder. This is where you should place your test files, including unit tests.

In this recipe, you created a new file, called unit_test.dart. When you choose the name for a file containing tests, you might want to add test as a prefix or suffix to follow the naming convention for tests. For example, if you are testing functions that deal with parsing JSON, you might call your file test_json.dart.

In your test files, you need to import the flutter_test.dart package, which contains the methods and classes that you use to run your tests:

import 'package:flutter_test/flutter_test.dart';

You also need to import the files where the methods and classes you want to test are written. In this recipe’s example, the isEven method is contained in the main.dart file, so this is what you imported:

import 'package:hello_flutter/main.dart';

Like in any Flutter app, the main method is the entry point of your tests. When you execute the flutter test command in a Terminal, Flutter will look for this method to start executing your tests.

You write a unit test using the test function, which takes two arguments: a string to describe the test, and a callback function that contains the test itself:

void main() {
  test('Is Even', () {
    bool result = isEven(12);
    expect(result, true);
  });
}

In this case, we are running a test in the isEven() function. When you pass an even number to isEven(), like 12, you expect true to be the return value. This is where you use the expect() method. The expect() method takes two arguments: the actual value and the expected value. It compares the two values, and if they don’t match it throws an exception and the test fails.

In our example, the instruction:

expect(result, true);

succeeds when result is true, and fails when result is false.

To run the tests, you can type the flutter test command in your terminal. This will run all tests in your project. You can also run your tests from your editor, like any other Flutter app. If your tests succeed, you get a success message, otherwise, you will see which specific test failed.

When you have several tests, you can group related tests together, using the group method:

group('Iseven group', () {
    test('Is Even', () {
      bool result = isEven(12);
      expect(result, true);
    });
    test('Is Odd', () {
      bool result = isEven(123);
      expect(result, true);
    });
  });

Like the test method, the group method takes two arguments. The first is a String containing the group description, and the second is a callback function, which in turn contains one or more test() functions. You use the group() function to better organize your test code, making it easier to read, maintain, and debug.

In general, the goal of unit testing is to test single units of code, like individual functions, to ensure that they are working as expected.

See also

In addition to unit tests, there are other types of tests that you can create for your Flutter application. In particular, widget tests are used to test the functionality of widgets, and integration tests test the integration of different parts of your application. See the official documentation at https://docs.flutter.dev/testing for more information about writing tests in Flutter.

Previous PageNext Page
You have been reading a chapter from
Flutter Cookbook, Second Edition - Second Edition
Published in: May 2023Publisher: PacktISBN-13: 9781803245430
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $15.99/month. Cancel anytime

Author (1)

author image
Simone Alessandria

Simone Alessandria wrote his first program when he was 12. It was a text-based fantasy game for the Commodore 64. Now, he is a trainer (MCT), author, speaker, passionate software architect, and always a proud coder. He is the founder and owner of Softwarehouseit. His mission is to help developers achieve more through training and mentoring. He has authored several books on Flutter, including Flutter Projects, published by Packt, and web courses on Pluralsight and Udemy.
Read more about Simone Alessandria