DEV Community

Cover image for Why We Call Saving the Magical Feature
Yogesh Choudhary for Welltested AI

Posted on

Why We Call Saving the Magical Feature

Recently, the entire team at Welltested AI engaged in a discussion to understand what according to us is the most notable feature of Welltested at the moment. And, everyone agreed upon welltested save unit which we also call the magic command :)

While we internally love it, quick analytics into our database showed us that most of our users are not yet using it! This led to the question: are we talking about it enough? haha.

So, we decided to write this blog to share with our users what is so special about Welltested's save feature and how to use it effectively. Let's dive into it.

Setup Your Project

For starters, download the flutter twitter clone project that we will be using. You can also use your project or download any other open-source project of your choice to follow along. The steps that we will follow will mostly remain the same.

Next, open the project in the IDE. After opening the project, we will need to head to Welltested on pub.dev. Then, follow the instructions available on the page to set up Welltested. Since the setup process is fairly straightforward and well-documented, you will not face any issues following along. The general steps include:

  1. Getting the API key and adding it to the project
  2. Adding the Welltested packages
  3. Activating Welltested CLI in your terminal

Once done we are ready to generate and save the tests :)

Generate Unit Tests

To generate the tests. We'll need to add the @Welltested annotation to the methods or classes for which we need to generate tests. This will help Welltested pick methods for whom test generation is requested.

Open lib/helper/utility.dart file in the project. We will find Utility class with a bunch of static methods declared inside it:

Utility Class Definition

For this blog, we will generate tests for the methods present in the Utility class only. Add the Welltested annotation at the top of the Utility class:

@Welltested()
Enter fullscreen mode Exit fullscreen mode

This annotation above the Utility class enables Welltested to know that we're interested in generating tests for the methods defined in this class.

Next, we will generate the tests by running the following chain of commands in the terminal:

welltested generate unit -m getPostTime2 && 
welltested generate unit -m getDob && 
welltested generate unit -m getJoiningDate && 
welltested generate unit -m getUserName
Enter fullscreen mode Exit fullscreen mode

Upon execution of the above commands, Welltested will start generating the tests for the methods mentioned after the -m parameter that have the @welltested annotation too - either directly or on the class containing the methods.

Open the generated tests located in the tests/helper/utility directory after the execution of the generate commands is finished. Take a look at the generated files. Congratulations! You have successfully generated tests for your code in less than 5 minutes. Isn't it great :)

Looking at the generated tests. You will see that some of the tests have errors:

Fig. 2 — Generated Tests Errors

But don't worry, Welltested has got you covered here. And this is where the Welltested's save command shines 😎

Welltested's Save Command

Welltested AI has the ability to constantly learn and improve as you interact with it. Since this is our first interaction with the AI, it may make mistakes in the initial tests as it hasn't yet learned about your project and your coding style. However, fixing this is simple.

You can just simply fix the broken generated tests and save the tests using Welltested's save command. Welltested will automatically learn from them and provide much smarter and error-free test cases in the future.

To understand this in more detail. Let's look at an example by updating and saving one of the earlier generated unit tests. Afterwards, we will use Welltested's generate command to generate the remaining tests again.

Open test/helper/utility/getPostTime2.welltested_test.dart file and update it with the following:

import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_twitter_clone/helper/utility.dart';

void main() {
  group('Utility getPostTime2', () {

    // 1.
    // Older version
    // test('When date is null, should return empty string', () {
    //   final mockUtility = MockUtility();
    //   when(mockUtility.getPostTime2(null)).thenReturn('');
    //   expect(mockUtility.getPostTime2(null), '');
    // });
    test('When date is null, should return empty string', () {
      expect(Utility.getPostTime2(null), equals(''));
    });

    test('When date is empty, should return empty string', () {
      expect(Utility.getPostTime2(''), equals(''));
    });

    test('When date is not in correct format, should throw FormatException',
        () {
      expect(() => Utility.getPostTime2('invalid date'), throwsFormatException);
    });

    test('When date is in correct format, should return formatted date', () {
      String date = '2022-12-01T20:18:04';
      String expectedDate = '08:18 PM - 01 Dec 22';
      expect(Utility.getPostTime2(date), equals(expectedDate));
    });

    // 2.
    // Older version
    // test('When date is in correct format but in different timezone, should return formatted date in local timezone', () {
    //   final mockUtility = MockUtility();
    //   String date = '2022-12-01T13:18:04Z'; // This is 20:18 in GMT+7
    //   String expectedDate = '08:18 PM - 01 Dec 22';
    //   when(mockUtility.getPostTime2(date)).thenReturn(expectedDate);
    //   expect(mockUtility.getPostTime2(date), equals(expectedDate));
    // });
    test(
        'When date is in correct format but in different timezone, should return formatted date in local timezone',
        () {
      String date = '2022-12-01T14:48:04Z'; // This is 20:18 in IST
      String expectedDate = '08:18 PM - 01 Dec 22';
      expect(Utility.getPostTime2(date), equals(expectedDate));
    });
  });
}
Enter fullscreen mode Exit fullscreen mode

On comparing the updated code with the previously generated test code. You will find two major differences here:

  1. The generated code utilizes MockUtility, which is a mock version of the Utility class. However, the updated code directly employs the Utility class. This is because our objective is to test the methods that are encapsulated within this class.
  2. The final test case aims to verify that the getPostTime2 function accurately converts a date from a different time zone into the local time zone. Initially, the AI assumed GMT+7 was the local time zone, but this led to a failure because my actual local time zone is IST. Consequently, the code was adjusted to employ a date that, when processed by getPostTime2, would align with the date stored in the expectedDate variable for Indian Standard Time (IST).

Now, since we have only updated one test, we will delete all other generated tests. This is because when we execute the save test command, Welltested saves all the tests it has generated and that are present in the test directory. We want to ensure that our AI doesn't learn from code with errors. Don't you agree?

After deleting all the test files except /getPostTime2.welltested_test.dart, run the following command in the terminal:

welltested save unit
Enter fullscreen mode Exit fullscreen mode

After a successful save, you'll receive the following message in the terminal:

✅ Succeeded. 1 were saved.
Enter fullscreen mode Exit fullscreen mode

Now, add the following command on the terminal to generate tests again:

welltested generate unit -m getDob && 
welltested generate unit -m getJoiningDate && 
welltested generate unit -m getUserName
Enter fullscreen mode Exit fullscreen mode

After the test generation is completed. Revisit the generated tests:

Fig. 3 — Updated Tests using Welletested

This time, the tests adhere to our coding style. Also, the generated code correctly uses the local time zone for my case based on the saved code which is fantastic. Don't you agree? I certainly do.

Conclusion

By now, I hope you can appreciate the power of saving tests in Welltested and how it can assist you in crafting more efficient tests tailored to your specific needs and coding style.

I encourage you to generate tests using Welltested and to save all of them. This will not only speed up the test generation process but also enhance the quality of your tests over time. Happy Testing :)

Top comments (0)