Unit Testing In Flutter Using Welltested.AI

Introduction

Hi friends, In this article, we will learn one of the important topics Unit testing in Flutter. Unit testing in Flutter is essential for building reliable and maintainable applications. By writing and running unit tests, you can identify and fix issues early in the development process, improve code quality, and ensure that your Flutter app behaves as expected. Unit testing saves our time and effort in the long run and contributes to a more robust and bug-free application.

testing

Why Unit Testing?

How can you ensure that your app continues to work as you add more features or change existing functionality? By writing tests. Here are some important points why you should consider unit testing in your Flutter application-

  • Bug Detection and Prevention: Unit tests help you identify and fix bugs and issues in your code early in the development process. By catching problems at an early stage, you can prevent them from propagating to other parts of your application, making debugging easier and less time-consuming.
  • Code Reliability: Unit tests ensure that individual units of your code (e.g., functions, methods, classes) behave as expected. This contributes to the overall reliability of your application because you can have confidence that each unit works correctly.
  • Refactoring Support: When you need to make changes to your code, whether it's refactoring or adding new features, unit tests act as a safety net. They help you verify that your changes haven't introduced new bugs or broken existing functionality.
  • Documentation: Unit tests serve as living documentation for your code. They provide examples of how your code should be used and what its expected behavior is. This can be particularly valuable when multiple developers work on a project or when you revisit your code after some time.
  • Regression Testing: As your application grows, it becomes more complex and interconnected. Unit tests ensure that previously implemented functionality remains intact when you make changes. This prevents regressions, where new code modifications inadvertently break existing features
  • Isolation of Components: Unit tests focus on testing individual units of code in isolation from the rest of the application. This isolation makes it easier to pinpoint the source of problems and simplifies debugging.
  • Improved Code Design: Writing unit tests often encourages better code design practices. It encourages you to write modular, decoupled, and testable code, which leads to more maintainable and extensible applications.
  • Continuous Integration (CI): Unit tests can be integrated into your continuous integration (CI) pipeline. This means that your tests can run automatically whenever changes are pushed to the code repository, helping to ensure that only code that passes the tests is deployed.
  • Time and Cost Savings: While writing unit tests may seem like an additional overhead, it often saves time and costs in the long run. It reduces the time spent on manual testing and debugging and minimizes the risk of costly production issues.
  • Developer Confidence: Unit tests provide developers with confidence in the correctness of their code. When you make changes or add new features, you can quickly verify that existing functionality remains intact by running the tests.
  • Maintainability: Over time, unit tests make your codebase more maintainable. They make it easier for new team members to understand and modify the code, and they help you catch regressions when updating dependencies or making changes to the codebase.

What is Welltested.ai?

Welltested.ai

Welltested is a Testing Pilot helping developers add and maintain tests as they code and deliver stable welltested apps to users. If We write our unit test case manually it will take so much time and usually, we don't have time to write a test case for our application, but using Welltested, we can generate our unit test case in just 10 minutes.

Let's understand practically with Android Studio.

Step 1. Create a new Flutter project.

Step 2. Add the required dependency in pubspec. yaml. Open your terminal in Android Studio and run the following command

flutter pub add welltested_annotation dev:mockito dev:build_runner

After successfully running this command, press the pub get button.

Step 3. Generate your API Key using registering this Register on welltested.ai URL.

Step 4. Create a .env file at the root of your project, and add your API key received in the email.

WELLTESTED_API=YOUR_API_KEY

Please replace the YOUR_API_KEY with your API key.

Step 5. Activate the well-tested CLI globally using the following command

dart pub global activate welltested

Example 1

Step 1. Create a new file inside the lib folder named FindMaxAndMinNumber.dart and Add the below code

void findMaxAndMinNumber(){

  List<int> numbers = [5, 10, 2, 8, 1, 15, 7];

  int maxNumber = numbers[0];
  int minNumber = numbers[0];

  for (int i = 1; i < numbers.length; i++) {
    if (numbers[i] > maxNumber) {
      maxNumber = numbers[i];
    }
    if (numbers[i] < minNumber) {
      minNumber = numbers[i];
    }
  }

  print("Maximum number: $maxNumber");
  print("Minimum number: $minNumber");

}

Step 2. Just mark any class that you want to test with @Welltested annotation, and the tests will be generated automatically.

@Welltested()
void findMaxAndMinNumber(){

  List<int> numbers = [5, 10, 2, 8, 1, 15, 7];

  int maxNumber = numbers[0];
  int minNumber = numbers[0];

  for (int i = 1; i < numbers.length; i++) {
    if (numbers[i] > maxNumber) {
      maxNumber = numbers[i];
    }
    if (numbers[i] < minNumber) {
      minNumber = numbers[i];
    }
  }

  print("Maximum number: $maxNumber");
  print("Minimum number: $minNumber");

}

Step 3. To generate unit tests for annotated classes, please run the following command.

welltested generate unit

After running this command, the test case is generated successfully in the test folder.

Output

Now go to the test folder, and you can see a new test file is generated.

findMaxAndMinNumber.welltested_test.dart

import 'package:flutter_test/flutter_test.dart';
import 'package:unit_test_using_welltested_ai_example/FindMaxAndMinNumber.dart';

void main() {
  group('FindMaxAndMinNumber', () {
    test('findMaxAndMinNumber should return the correct maximum and minimum numbers', () {
      List<int> numbers = [5, 10, 2, 8, 1, 15, 7];
      int maxNumber = numbers[0];
      int minNumber = numbers[0];
      for (int i = 1; i < numbers.length; i++) {
        if (numbers[i] > maxNumber) {
          maxNumber = numbers[i];
        }
        if (numbers[i] < minNumber) {
          minNumber = numbers[i];
        }
      }
      expect(maxNumber, 15);
      expect(minNumber, 1);
    });
  });
}

Example 2

Step 1. Create a new file named calculation. dart inside the lib folder and add the following code

int add(int a, int b) {
  return a + b;
}

int subtract(int a, int b) {
  return a - b;
}

int multiply(int a, int b) {
  return a * b;
}

double divide(int a, int b) {
  if (b == 0) {
    throw ArgumentError('Cannot divide by zero');
  }
  return a / b;
}

Step 2. Just mark all functions with @Welltested annotation, and the tests will be generated automatically.

@Welltested()
int add(int a, int b) {
  return a + b;
}

@Welltested()
int subtract(int a, int b) {
  return a - b;
}

@Welltested()
int multiply(int a, int b) {
  return a * b;
}

@Welltested()
double divide(int a, int b) {
  if (b == 0) {
    throw ArgumentError('Cannot divide by zero');
  }
  return a / b;
}

Step 3. To generate unit tests for annotated classes, please run the following command

welltested generate unit

Output

Now go to the test folder, and you can see a new test file is generated.

add.welltested_test.dart

import 'package:flutter_test/flutter_test.dart';
import 'package:unit_test_using_welltested_ai_example/Calculation.dart';

void main() {
  group('add', () {
    test('should return the correct sum of two positive integers', () {
      expect(add(3, 5), 8);
    });

    test('should return the correct sum of two negative integers', () {
      expect(add(-3, -5), -8);
    });

    test(
        'should return the correct sum of one positive and one negative integer',
        () {
      expect(add(3, -5), -2);
    });

    test('should return the correct sum of two zero integers', () {
      expect(add(0, 0), 0);
    });

    test(
        'should return the correct sum of one zero and one positive integer',
        () {
      expect(add(0, 5), 5);
    });

    test(
        'should return the correct sum of one zero and one negative integer',
        () {
      expect(add(0, -5), -5);
    });

    test('should return the correct sum of the maximum integer values', () {
      expect(add(2147483647, 2147483647), 4294967294);
    });

    test('should return the correct sum of the minimum integer values', () {
      expect(add(-2147483648, -2147483648), -4294967296);
    });
  });
}

divide.welltested_test.dart

import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'package:unit_test_using_welltested_ai_example/Calculation.dart';


void main() {
  group('Calculation', () {
    test('divide should return the correct quotient of two positive numbers', () {
      expect(divide(10, 2), 5.0);
    });

    test('divide should return the correct quotient of two negative numbers', () {
      expect(divide(-10, -2), 5.0);
    });

    test('divide should return the correct quotient of a positive and a negative number', () {
      expect(divide(-10, 2), -5.0);
    });

    test('divide should throw an ArgumentError when dividing by zero', () {
      expect(() => divide(10, 0), throwsA(isA<ArgumentError>()));
    });
  });
}

multiply.welltested_test.dart

import 'package:flutter_test/flutter_test.dart';
import 'package:unit_test_using_welltested_ai_example/Calculation.dart';

void main() {
  group('Calculation', () {
    test('multiply should return the correct product of two positive integers', () {
      expect(multiply(3, 5), 15);
    });

    test('multiply should return the correct product of two negative integers', () {
      expect(multiply(-3, -5), 15);
    });

    test(
        'multiply should return the correct product of one positive and one negative integer',
        () {
      expect(multiply(3, -5), -15);
    });

    test('multiply should return zero when multiplying by zero', () {
      expect(multiply(0, 5), 0);
      expect(multiply(5, 0), 0);
    });

    test('multiply should return the correct product of the maximum integer values', () {
      expect(multiply(2147483647, 2147483647), 4611686014132420609);
    });

    test('multiply should return the correct product of the minimum integer values', () {
      expect(multiply(-2147483648, -2147483648), 4611686018427387904);
    });
  });
}

subtract.welltested_test.dart

import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:unit_test_using_welltested_ai_example/Calculation.dart';

void main() {
  group('subtract', () {
    test('subtract should return the correct difference of two positive integers', () {
      expect(subtract(5, 3), 2);
    });

    test('subtract should return the correct difference of two negative integers', () {
      expect(subtract(-3, -5), 2);
    });

    test(
        'subtract should return the correct difference of one positive and one negative integer',
        () {
      expect(subtract(3, -5), 8);
    });

    test('subtract should return the correct difference of two zero integers', () {
      expect(subtract(0, 0), 0);
    });

    test(
        'subtract should return the correct difference of one zero and one positive integer',
        () {
      expect(subtract(0, 5), -5);
    });

    test(
        'subtract should return the correct difference of one zero and one negative integer',
        () {
      expect(subtract(0, -5), 5);
    });

    test('subtract should return the correct difference of the maximum integer values', () {
      expect(subtract(2147483647, 2147483647), 0);
    });

    test('subtract should return the correct difference of the minimum integer values', () {
      expect(subtract(-2147483648, -2147483648), 0);
    });
  });
}

Note. To save the unit test case, run the following command.

welltested save unit

Conclusion

In this article, we have seen how to write test cases easily using AI in Flutter. Thanks for reading, and I hope you like it. If you have any suggestions or queries about this article, please share your thoughts. You can read my other articles by clicking here.

Source Code Link. https://github.com/absinghal10/Unit-testing-In-Flutter-Using-Welltested.ai/tree/master

Resource Link

Happy learning, friends.


Similar Articles