With a test runner enabling us to control the execution of all tests in one run, we also need to have control of the data created in one test codeunit, so that it will not influence the results of the tests in the next test codeunit. For this, the test codeunit TestIsolation property has been introduced, and it has three possible values:
Disabled: When selecting this value, or not setting the TestIsolation property explicitly, as this is the default value, any database transaction will be effectuated; after the execution of tests triggered by the test runner, the database will have changed compared to before running the test runner
Codeunit: When selecting this value, after a test codeunit execution has completed fully, all data changes made to the database will be reverted/rolled back
Function: When selecting this value, when a single test function has completed, all data changes made to the database will be reverted/rolled back
Related to this, it makes sense to share a couple of thoughts on running tests and their isolation:
Test isolation applies to database transactions, but does not apply to changes made outside of the database, and to variables, including temporary tables
With test isolation, Codeunit, or Function, all data changes will be rolled back, even if they were explicitly committed using the AL Commit statement
Running test codeunits outside of the test isolation, either Codeunit or Function of a test runner will effectuate any database transaction
Using test isolation, Function will give extra overhead compared to Codeunit, resulting in longer execution time, as with the ending of each test function, the database changes have to be reverted
Setting the test isolation to Function might be unwanted, as it fully disables dependencies between test functions, which might be needed when, for an extended test scenario, intermediate results should be reported, and this has been achieved by a series of individual, but interdependent, test functions
With the TestIsolation property of a test runner, we have control over how to revert data changes in a generic way; as we will later see, the test function TransactionModel tag allows us to have control of the transaction behavior of individual test functions