Introduction to unit tests
A unit test is a way of testing an individual unit of software. A unit is the smallest piece of code that can be logically isolated in a system. The purpose is to validate that each unit of the software performs as designed. In most programming languages, that is a function, a subroutine or a method. In the Software Factory unit tests can be written for the following logic concepts:
- Subroutines (of type Procedure or Scalar Function only)
The image below shows the unit test screen. This is the place to create, maintain and execute unit tests.
Creating a unit test
The list on the left shows all the objects for which unit tests can be created. Badges are used to show the amount of existing unit tests. After selecting the correct object and logic type a unit test can be created.
menu Quality > Unit tests > tab Logic > tab Form
- A title and description can be filled as well as if the unit test should succeed or not, with the Should abort checkbox.
- A preparation query can be used, for example, to influence parameter values. In tab Preparation, check the Use prepare query box to enable the query field.
- Certain unit tests (e.g., tasks and triggers) may require that the outcome of the unit test must be verified by queries, also known as an assertion query. The output parameters for a unit test are also available in the assertion query. In tab Assertion, check the Use assertion query box to enable the assertion query field. This field is filled with an example query by default, showing how the assertion result can be thrown when certain conditions are met.
When a unit test is created, parameters can be added, for which a distinction is made between input, output and row filter.
- The row filters are used in the 'where' clause when testing update or delete triggers.
- The output parameters will be checked after the unit test has been executed.
- Also the expected messages can be specified. These will also be checked after performing a unit test.
When specific data is needed to meet certain conditions in the code, the best practice is that the unit test doesn't rely on live data. Instead, data sets can be used as mock data. In this way, you can guarantee that the necessary data is available for the test.
Sometimes a unit test is temporarily unnecessary and shouldn't be executed. Therefore, unit tests can be deactivated and activated again using the Activate unit test and Deactivate unit test tasks.
Unit test overview
menu Quality > Unit tests > tab Overview
The Overview tab page shows an overview of all the unit tests for the selected project version. By selecting one or multiple rows the unit tests can be executed.
Unit tests can also be created, maintained or executed from the Functionality modeler.
Unit test in functionality modeler
The list shows all the unit tests that are directly connected with the program objects on the result page. For example, when a default procedure is created for Employee to combine the first and last name to display name, the written unit test that validates the email address is also shown in the list.
Also, all unit tests are shown that have the selected control procedure linked as primarily.
The Analysis menu group provides two cubes to monitor the unit test code coverage.
These cubes rely on the presence of program objects in the model, ensure the definition of the model is fully generated.
Unit test control procedure coverage
The Unit test control procedure coverage cube shows the ratio of control procedures covered by a unit test. Only control procedures of code groups that allow for unit tests are measured.
There are 3 cube views available:
- Coverage per code group
- Coverage per developer
- General coverage
Coverage per code group
The coverage status is determined as following. A control procedure can be either:
- Covered - A program object item created by the control procedure is present in a program object involved directly in any active unit test.
- Covered (linked only) - The control procedure is linked to an active unit test, but the program object items of this control procedure are not in any program object directly involved in an active unit test.
- Not covered - The program object items created by this control procedure are part of program objects not directy involved in any unit test, nor is the control procedure linked to an active unit test.
Unit test program object coverage
The Unit test program object coverage cube is similar to the control procedure coverage cube but measures the number of program objects instead. Only program objects of code groups that can have unit tests are measured.
There are two cube views available:
- Coverage per code group
- General coverage
The coverage for program objects is generally lower than the coverage for control procedures, as a dynamically assigned control procedure might not have a unit test on every program object where it is assigned.
Data sets for unit tests
Data sets are collections of data that can be used for testing purposes. The data from this set only exists in the context of your unit test. Every time you run a unit test, the data from your defined data set is added in a transaction. This transaction is rolled back at the end, which means the data will never actually be added to your database.
menu Quality > Unit tests > tab Data sets
When a data set is created, you can choose tables as data containers for this set. For each table, multiple rows can be added as data. When no rows are specified, the table will contain 0 records. In a data set, you don't need to take foreign key constraints into account. The data container table has references in this context.
The input values for unit test, don't need to exists in the data set. It depends on what you want to test. For example, if you wish to test a business rule to prevent a user from adding a duplicate value, you can add an input value that is already in the data set.
It is also possible to use Identity insert for your data set. If you leave the Identity column empty, an identity value is added automatically. If you define a static value into the Identity column, Identity insert is turned off, and your static value is added instead.
The created data sets can then be selected as mock data for a unit test.