This is the fourth post in a unit testing series. For the past incarnations, see the links at the bottom of this blog. This blog post aims to examine the ongoing controversy surrounding unit testing in more detail. This discussion is not restricted to low-code; but, in order to keep the discussion focused, I will only discuss my personal experiences with Mendix low-code projects and the teams that work on them.
Whenever I bring up the subject of unit testing, I typically receive the same queries or responses.
No advantages for me
One major one is because I have never used it and don’t think there are any advantages. Fundamentally, this phrase seems to suggest a fear of novelty or even a resistance to altering the process of development in order to enhance quality. This view is subject to evolve, presuming that improving the quality while preserving low-code development speed is a common objective.
As you can see, the testing pyramid’s base is unit testing. With each release adding test cycles or just not testing everything that might be important, it gets more and harder to test everything accurately as the layers of complexity for a Mendix application rise. The two highest tiers of the pyramid—UI and API testing and manual and exploratory testing—are used to test the majority of Mendix applications. Even the UI and API testing is automated in Mendix applications as they evolve. Testing layers that require a large amount of data input in pages and are more than four sub-microflows deep are difficult to scale to different scenarios and are difficult to test from the user interface.
Unit testing might be helpful in this situation. Make sure that the single-purpose sub-microflows that handle the various components of your functionality are located at the bottom of your microflow spaghetti. Although it will need more upkeep, applying unit tests to each of these sub-microflows should enable you to eliminate some UI tests that essentially test the tip of the pyramid and are not scalable.
Verifying that the microflows being examined are single-purpose is vital. Large microflows with a great deal of intricate logic are not good candidates for unit testing. In that scenario, you would experience the same headaches as with the UI testing approach with every piece or requirement change.
Unit tests allow you to test multiple scenarios without requiring an excessively complex set of input parameters, and when one unit or the user interface changes, you only need to modify the tests for that particular unit rather than all of them. These are two advantages of using unit tests to address doubts.
Tests on smaller projects are not necessary.
Generally speaking, I disagree with this assertion. In the event that your project is intended for production, it will require ongoing development or maintenance by someone. Unit tests will therefore assist you in developing the code you believed you did not modify and the updated/newly introduced code, as well as your fellow developers in the future (even you in six months).
Unit tests should be written for any functionality that is tested that involves any logic and isn’t just a basic object creation or page opening. After all, the unit test could have likely been built and you may have saved time going forward if you had manually tested it once or twice. Of course, you would need to update the unit test if the functionality being tested changed, but most of the time, updating requires less work than creating the test from scratch. The templates will make it easier for you to fill in the blanks with the modified module that I previously detailed in a blog iteration.
And keep in mind that you want to release as soon as possible following that problem repair when you are in a pinch because production is on fire. Do you like to hold off until your test engineer has reviewed everything? Are you certain you conducted every test? The majority of the work could be tested with a single button click because unit tests were already in place. So, using unit testing is beneficial for all projects, even tiny ones.
Additionally, the functionality of your code gains context from your unit tests. After you interpret the code, knowing which input parameters should produce which output is helpful to anyone working on this project. This might save a lot of work, in addition to annotations, documentation, and user stories.
Unit tests shouldn’t be essential to add needless complexity to well-written code and well divided modules/functions.
The code is written with higher quality when unit tests are implemented. As previously stated, in order to effectively use unit tests, you must have single-purpose microflows; otherwise, the unit tests that attempt to verify the functioning of those microflows would get too complicated. What is a Mendix best practice, by the way? Reusable, tiny microflows are what you want.
If you have separated modules and functions appropriately, your code should be well suited for unit testing. Even in this case, relying solely on manual testing or automating your testing through pure UI testing would not be scalable. Unit tests are not, in my opinion, an unneeded complexity to add. Yes, utilizing the enhanced version of the unit testing module adds more microflows, which means your project will require more code. If only Mendix could choose to have their own document type for the unit test microflow. But it also provides that code with context. It enables you to test the code as part of a Continuous Integration / Continuous Deployment (CI/CD) pipeline or at the touch of a button. It facilitates your UI testing team’s concentration on your application’s UI components.
It takes more time for the developer to perform unit testing; test engineers should handle testing.
This isn’t totally true or false, but you should feel very fortunate that your project team has committed test engineers. The functionality of their code should already be verified by every developer. Furthermore, I’m not only referring to the pleasant route. Because test engineers and developers are typically wired slightly differently, the former can come up with even more scenarios for code validation. An even more beneficial asset to the team is a test engineer who has a strong passion for Mendix. The same goes for a Mendix developer who has a penchant for testing. The scenarios for verifying the user story throughout refinement should be decided upon as a team, and developers and testers should work together to build those tests as unit tests in the project and the additional levels of testing using various tools.
Ultimately, it is everyone’s responsibility to develop a functional application. Instead of merely tossing a user narrative on the testing status when development is complete and pouting when it is returned because of errors, we should all work to make that happen.
What then is the ideal moment to utilize it—or not use it?
Unit testing should only be used in experiments or proof-of-concept projects that are never brought to the production level. Unit testing ought to be incorporated into every other project prior to the initial release or acceptance. and ideally even ahead of any user evaluations.
In summary
It goes without saying that I support unit testing. I make an effort to win everyone over and allow those that are receptive to use unit tests in their Mendix projects. When you take one step at a time, even the biggest challenges seem manageable! Use this blog to help persuade your team or yourself of the advantages of unit testing. I even extend an invitation for you to get in touch with me so we can talk about it as a team.
What comes next?
Lessons from my own unit testing experiences as well as the four blogs that have previously been written!
Lessons learned will come next!
Earlier blogs about unit testing
How do I begin?
Enhancements to the module!
Training made easier!
Examine the January 2024 meetup recording regarding unit testing while you’re at it.