Code Coverage for Mendix apps
Introduction
When testing a Mendix app, you need to check and confirm the quality, functionality, and reliability of your app. You can test your Mendix app at different levels for these criterias, such as unit testing, component testing, process testing, and UI testing. Besides this distinction in test levels, there are two kinds of test approaches: white-box testing and black-box testing. White-box testing involves testing the internal structure and logic of the code, while black box testing checks whether your system is working according to the business requirement and end-users’ expectations without considering its programming or the internal functionalities.?
White box testing in Mendix means testing at the microflow and domain model level. Black box testing in Mendix is done through the UI and/or available API’s.
The white box and black box approaches also have two different coverage concepts. White box testing is linked to code coverage and black box testing to test coverage. Code coverage and test coverage are often mistaken or used interchangeably, but since they are linked to different test approaches they are not the same.
In this blog we explain the differences between code coverage and test coverage and how you can apply and measure code coverage in a Mendix application. In the last part of this blog we provide guidelines that can help you to determine how much code coverage you need for your Mendix app.
Difference between Code Coverage and Test Coverage
Code coverage and test coverage are two different but complementary metrics that can be used to evaluate the effectiveness and completeness of testing your Mendix app. Code coverage measures how many elements of the Mendix model are executed by the test cases, while test coverage measures how much of the software requirements or specifications are verified by the test cases. Both code coverage and test coverage are important for software quality assurance, as they can help identify where the system is tested and more importantly where it is NOT tested, and provide guidance for improvement and optimization.
Code Coverage
Code coverage is a measure of how many elements of the Mendix model are executed or covered by a set of test cases. Code coverage can be calculated at different levels of granularity, such as function coverage, statement coverage, exit coverage, branch coverage, condition coverage, etc. Code coverage can be expressed as a percentage of the total number of code elements (such as statements, exits, branches, functions, or conditions) that are covered by the test cases over the total number of code elements in the software product.
Code coverage can be used to assess the quality and completeness of white-box testing, as it indicates how well the internal structure and logic of the code are tested. Code coverage can also help identify the areas of the code that are not tested or have low coverage, and thus require more attention or improvement.?
While test coverage can be measured by platform independent tools, code coverage of Mendix apps can only be measured by specific tools that fit well with the Mendix platform.
Test Coverage
Test coverage is a measure of how much of the software requirements or specifications are verified or covered by a set of test cases. Test coverage can be calculated at different levels of abstraction, such as feature coverage, scenario coverage, use case coverage, or user story coverage. Test coverage can be expressed as a percentage of the total number of requirements or specifications that are covered by the test cases over the total number of requirements or specifications in the software product.
Test coverage can be used to assess the quality and completeness of black-box testing, as it indicates how well the external behavior and functionality of the software are tested. Test coverage can also help identify the gaps or discrepancies between the software requirements or specifications and the actual software product, and thus require more clarification or modification. Test coverage can be measured using various methods and tools, such as traceability matrix, test design, or test management.
Why is code coverage important?
The right level of code coverage in your automated tests helps you to:
Types of Code Coverage
Code coverage can be classified into different types. Some of the common types of code coverage that are useful in the context of Mendix apps are:
There are also different types of code coverage that are derived from or related to the above types, such as path coverage, condition coverage, loop coverage, parameter value coverage, etc. However, these types are less useful in the context of Mendix apps. The choice of the type of code coverage depends on the objectives, scope, and resources of your testing process, as well as the characteristics and requirements of the Mendix app. In general, higher levels of code coverage imply higher levels of code quality, but they also require more effort and cost to achieve. Therefore, it is important to balance the benefits and challenges of code coverage and use it as a relative and indicative measure rather than an absolute and definitive one.
Code coverage applied to Mendix
In Mendix we define a microflow as a “function” and a microflow activity as a “statement. The “exit” is the endpoint of a microflow (with or without return parameter).
A “branch” in a Mendix model is the most complex to define. There are explicit and implicit branches in Mendix models. Explicit branches are decision points in a microflow, but implicit branches in the logic of the Mendix model could be created by:?
To identify implicit branches in Mendix models? it is necessary to analyze the model elements that you want to test in depth. A Mendix model therefore becomes much more testable if the number of implicit branches is kept to the minimum. Testing becomes also easier if implicit branches are properly documented in the code.
We consider it not to be useful to measure statement coverage in a Mendix app at the application level. The microflow activities are provided by the Mendix platform and are tested already by Mendix. The only exception is for custom java activities. These, however, can be unit tested independently from the microflow in which they are used.
REMARK: Other types of functions in Mendix are nanoflows and object actions. However, nanoflows are not easy to execute separately and only exist in the context of a client. If a nanoflow wants to change something on the Mendix backend, it can only do this by calling a microflow or executing an object action.? Object actions are completely tested by the Mendix platform and do not need additional testing at the application level.?
Example of code coverage in Mendix on a single microflow
To make code coverage more concrete, we can apply the different types of code coverage to a specific microflow.
领英推荐
In the microflow above, which we also use as an example in our demo videos for showing how to build unit tests, we can define function, exit, branch and statement coverage as follows:
In the microflow above no implicit branches are present. There are only simple true or false statements in the decisions and only the last decision (Fuel?) uses an enumeration.
The same microflow could also have been built with the implicit branches in the decision Expression (see image below)
At first sight, such a microflow would look simpler than the one above, but because of the implicit branching it is much harder to test in a unit test.
What level of code coverage makes sense for each test level?
Function coverage is the starting point of Mendix code coverage, since it can be measured at all test levels (unit, component and process). Exit and branch coverage are also useful metrics, specifically to get a better idea how well you have tested the logic within microflows. For unit tests (simple microflows) it? is desirable to achieve 100% exit coverage and if possible also 100% branch coverage by varying the input data to make sure that their behavior is controlled under any circumstances.?
For more complex microflows (with multiple branches and exits) that behave more like a component or process there are two ways of dealing with exit and branch code coverage
In an earlier blog we already wrote about how to increase code coverage with less test cases?
In a future blog we will also address tactics on how and when to split a microflow into submicroflows. Not only to make them more testable but also to structure the microflows in? well-defined ways that makes them more maintainable and reusable.
How to measure code coverage in Mendix during a testrun?
Each test case in a test run can execute one or more microflows. Some of them are executed explicitly in a teststep. Other microflows are implicitly executed as a submicroflow.
Therefore, if you want to measure microflow coverage? in a Mendix app, you need to measure all executed microflows in a test run (and not only the ones that were part of your test case definition).
Branch coverage and exit coverage can (at this moment) only? be measured manually during the test run within Mendix StudioPro by using the built in debugging functionality for microflows. Adding breakpoints to the exit paths and branches makes this easy for explicit branches in a microflow.?
Measuring branch coverage for implicit branches in a microflow is a lot harder, because you cannot set a breakpoint in Mendix StudioPro at a specific point of your code within a microflow activity. If you use java functions in a microflow it is possible to debug these java functions, but this requires a specific java debugging setup for Mendix
How much code coverage do you need?
There is no definitive answer to how much code coverage is needed for a Mendix app, as it depends on various factors such as the complexity, size, type, and purpose of the app, the testing methodology and tools used, the available resources and time, and the quality standards and expectations of the stakeholders.
However, some general guidelines and best practices can be followed to determine an appropriate level of code coverage for a software project, such as:
Sometimes it is hard to set one coverage goal for an application. Multiple coverage goals can be set for example by:
In such a case it is necessary that you can measure the coverage for each of these goals.
Conclusion
In this blog we have described what code coverage is, how it differs from test coverage and how you can apply it to Mendix apps. Code coverage is certainly a useful concept for Mendix apps as an addition to other quality measures. Although it seems logical to see coverage as the measure of quality, the reverse is actually even more true, because the insight into what has NOT been tested can be more important than what has been tested.?
In a future blog we will explore how you can use the results of code coverage in your organization to increase the quality of your tests and therefore of your Mendix application.
This blog is also published on the Menditect website https://menditect.com/code-coverage-for-mendix-apps/