Flutter for Enterprise | Unit Testing Usecase [2/2]
By: Preyea Regmi
Tags: Flutter, Test Driven Development, Unit Testing, Flutter App Development, Clean Architecture

In my previous writing, we emphasized on the necessity of structuring our application. We addressed two major hurdle that could potentially bring the flutter project to a halt and took an architectural decision by adapting to Domain Driven Design principle. Now we want to incorporate Unit Test and adhere to Test Driven Development guidelines while implementing use-cases and learn how it supplements our approach towards building a scalable application.

Test Driven Development

Test driven development is more than just using automated test suite for validating our implemented logic. It’s kind of methodology which in a way drives the design aspect of writing code by following a certain convention in cycles. Essentially, this allows our test case to serve as a technical documentation for the behavior of our application.

This convention is described as below.

Upon receiving a feature/change request, the iteration of TDD starts.

1. Add a test case in support to the feature/change request. 2. Write the minimum code to make the test case pass. 3. Adjust with the rest of production code through refactoring.

This convention can be applied at different level as we have already decomposed our application into various layers/components as in the figure below.

Here we’ll be focusing on the “Unit Test”, which is at the bottom of testing pyramid.

Unit Test

In Object Oriented perspective, Unit Test is the testing of state/behavior of a class in isolation. We have seen already in previous article that structuring our application by decomposing into layers/components results in writing more code and ends up with a lot of classes. So it’s natural that we want to automate the testing of classes and test them in isolation in a time effective manner. That lead us to two approach of unit testing which are as follows.

Test Last Approach

This is the default testing approach that we think of intuitively. In this approach we perform test after writing the implementation detail of our code which means our test works for that specific implementation only. Any change in the implementation detail will break the contract of test case and results as failure which might not be correct all the time.

For example, suppose you want to go from place ‘A’ to place ‘B’ and you went by train. If you write test case to validate this logic using test last approach then you’ll end up including the mode of transportation as a part of the behavior that you want to validate. However that is just an implementation detail that you’ve used. Different people might use different mode of transportation to reach the same destination from the same starting point.

So Test Last Approach couples the behavior along with implementation detail which results in rigid code that is hard to maintain. Therefore we avoid this approach while Unit Testing but it is useful for other testing scenarios.

Test First Approach

This testing approach aligns with the convention that we have mentioned earlier while explaining TDD. So we’ll use this convention and explore further with some examples. In general, this is an iterative approach where we start with fail case, then we adjust the minimum change in our code to make it pass and finally refactor to improve the quality without affecting the behavior.