Translation prepared as part of an online course “Flutter Mobile Developer“.
We invite everyone to a free two-day intensive “We create a Flutter application for Web, iOS and Android”… You can find out more details and register here.
To be honest, I never really liked testing – it drags out development in general and often complicates updating the codebase. After a series of catastrophic defeats, I finally took up the materiel and figured out how testing actually works. Funnily enough, as a result, I fell in love with tests that I never imagined in the past.
In addition, I haven’t written any articles for a while, so it seemed like a great idea to go back to the pen and tell how my failures in a particular case ultimately led to the fact that it became an integral part of development.
Testing widgets – what is it really?
A Flutter application has many widgets for a wide variety of purposes. Widgets have specific layouts and interactive elements, each with its own purpose. In the process of developing an application, at some point you start to get confused in its elements. Because of my love for physics, albeit unrequited, I like one phrase:
Could a butterfly flap in Brazil trigger a Texas tornado?
This phrase is related to chaos theory, but I like to think that in the same way, one change you make to the application, which seems to have nothing to do with the rest of the code, can imperceptibly break its work. By testing widgets, you can test elements of your application, usually individual widgets, in a dedicated environment to ensure that the aforementioned “Texas tornado” does not make it into the production release scheduled for next Friday.
A common practice is to write several groups of tests that check various functionalities of the widget, for example, whether the visual elements are in place, whether the interactive elements give the desired result, whether the animation works, etc.
Alternatively, you can write gold tests – tests that verify that your widgets are still pixel perfect after months of midnight coding and caffeine doping coding sprints. We will consider all this, but first about the main thing.
Tests are usually located outside the comfortable and cozy lib folder and are located in their own test folder.
Widget tests run in the Flutter test environment, not on a physical or emulated device, so be aware of the limitations associated with this.
Let’s take a look at the test structure:
If you go to the top, everything looks pretty simple:
main(), apparently, there are tests.
testWidgets(), as the name suggests, contains the test itself.
Inside the function
testWidgets()there is a description of the test and a place to write the actual test code.
I am one of those people who learn to drive only after they understand the principle of the internal combustion engine. So let’s take a closer look at this function and see what it does.
Parsing the testWidgets () function
Let’s start with
testWidgets – why not?
Let’s see what possibilities this function hides.
Skipping the entire test
Let’s pretend that some Nashwhoever he was, asked you to write too many tests, and you know, some turned out to be quite clumsy. No problem – you can skip them entirely using the flag skip…
That is, the test cannot show unsuccessful results if you skip it. ¯ _ (ツ) _ / ¯
Adding timeouts to a test
This is a little more complex, as there are two parameters to set the timeout for the test.
Without going into details of why this is done in this way, we will describe the essence of this action:
initialTimeout – the main used timeout, which can be increased, but by a value, NOT EXCEEDING parameter value
To increase the timeout, we can do this:
Thus, time is added to the initial timeout, but if the increase exceeds the parameter value
timeout, then the excess will not be taken into account.
Aside: Exploring the setUp () and tearDown () Functions
Before proceeding further with the function
testWidgets(), let’s learn more about one useful feature of the Flutter testing environment – the ability to set the necessary settings before testing and perform the necessary cleanup after testing is completed.
This is done using four functions:
tearDownAll() are called once – before and after the tests are run, respectively.
tearDown() called before and after EACH test. These functions help you prepare and clean up your environment.
It is important to remember that the same functions are called for every test.
Back to testWidgets (): Exploring Test Options
Sometimes one test needs to be performed for several values, each of which requires its own tuning and cleaning, but with the same test code.
As a master of bad examples, I’ll suggest this: Let’s say we have three colors on which we must do the same test. Let’s put them in an enum:
Next, we create a test case that allows us to run the same test for multiple values:
We see functions familiar to us
tearDown(), although with different parameters, and we can perform the adjustment for each value, however, the most important thing here is
Now we can add values
WidgetColor in the test variant:
As a result, this variant can run the test for all values
WidgetColor… Now we can pass this to our test using the parameter
When you run this test, it will run three times for all values
Now that we are familiar with the main function, we can take a closer look at testing. It will be in second part articles.
Learn more about the course “Flutter Mobile Developer“.
Participate in an intensive “We create a Flutter application for Web, iOS and Android”