In the 1st edition of my book I discussed the testability framework, that resides in the Business Central platform, by means of 5 pillars. In the 2nd edition I wanted to add a 6th pillar: test permissions. I did write the text, but eventually decided not to add it to the book, because of two reasons: (1) it seems not to work well on BC18 and older versions (2) with the new updated test runners in - what will probably be released and get known as - BC19, together with the Permissions Mock app, there still seems to be no major reason to make use of the test permissions feature. Nevertheless, as the feature is there, being the TestPermissions property and attribute on respectively test codeunits and test functions, it does make sense to share this text with the community. So, here we go.
The sixth and final pillar of the testability framework, test permissions, has been added in Dynamics NAV 2017 and allows you to set permissions for your test run, so you can verify whether your code can be executed for given sets of permissions. If you don’t want to apply any permission set, it’s common practice to run your tests with full permission by assigning the SUPER role to the user account that will run the tests.
Next to having assigned the SUPER role to the user account that runs the tests, it was mandatory to have a full development license installed on the on-prem Business Central environment the tests were run on. Recently, Microsoft lifted this requirement and allowed you to run tests with any license. As a matter of fact, any license now has full development capabilities.
Running tests with permissions sets are based on a joined set up in the relevant test codeunit(s) and the test runner being used. In a basic setup, the test codeunit points out that test permissions should be applied (or not) and the test runner implements what specific permissions should be applied. For this, a test codeunit has the property
TestPermissions and through the
TestPermissions data type parameter on the
OnAfterTestRun triggers the test runner will be handed over this setting. So, the
TestPermissions property itself does not do anything but based on its value that is handed of to the test runner you can implement code that determines what permissions should be applied when running the tests in that codeunit. You actually can refine this to a specific test as each test function also has a
TestPermissions property and attribute on respectively and allows you to point out what permissions the test runner should set when running them. For both test codeunit and test function the
TestPermissions property/attribute has the following values:
- Disabled: Based on this value the test runner should not implement any permission restrictions.
- NonRestrictive: Based on this value the test runner could implement a broad set of user permissions.
- Restrictive: Based on this value the test runner could implement a restricted set of user permissions. Note that this is the default
Next to that, the
TestPermissions attribute on a test function has one additional value:
- InheritFromTestCodeunit: Using this value, your test function will inherit the
TestPermissions value from the codeunit.
Before we can have a look at how this works out by means of some example code, we need to discuss a platform component required to restrict, that is lower, and elevate permissions during (test) code execution.
In the example below you will see how this works.
As .dlls can only be used in an on-prem installation of Business Central the usage of test permissions is confined to an on-prem environment.
The PermissionTestHelper can only elevate permissions to the level of the permissions of the user account that runs the tests. To cover the whole range of permissions, make sure to run your tests with a user account that has the SUPER role assigned.
Example of how to apply TestPermissions
Let’s first built a couple of tests, in one test codeunit, with
TestPermissions set. Each test does the same, being deleting the last item ledger entry in the database, but with a different setting of the
codeunit 60051 "MyFifthTestCodeunit.Codeunit"
Subtype = Test;
local procedure DeleteILE()
ItemLedgerEntry: Record "Item Ledger Entry";
As you might know in the normal operation of Business Central, that is as a user with a meaningful set of permissions assigned, ledger entries are blocked from deletion. Running this test with SUPER role would allow deletion of the item ledger entry.
Now that the tests with
TestPermissions have been coded, we need to get our test runner shaped. For this, we will clone the standard test runner we discussed in Pillar 4 – Test runner and test isolation and add code to set the effective permission (in the
OnBeforeTestRun trigger) and lift it again (in the
OnAfterTestRun trigger). See the following cloned test runner with the code added that implements to set and lift permissions:
codeunit 60050 MyTestRunnerCodeunit
Subtype = TestRunner;
TestIsolation = Codeunit;
TableNo = "Test Method Line";
TableData "AL Test Suite" = rimd,
TableData "Test Method Line" = rimd;
ALTestSuite: Record "AL Test Suite";
CurrentTestMethodLine: Record "Test Method Line";
TestRunnerMgt: Codeunit "Test Runner - Mgt";
PermissionTestHelper: DotNet NavPermissionTestHelper;
trigger OnBeforeTestRun(CodeunitId: Integer; CodeunitName: Text;
FunctionTestPermissions: TestPermissions): Boolean
if IsNull(PermissionTestHelper) then
case FunctionTestPermissions of
AddEffectivePermissionSet('O365 BUS FULL ACCESS');
CopyStr(CodeunitName, 1, 30),
CopyStr(FunctionName, 1, 128),
trigger OnAfterTestRun(CodeunitId: Integer; CodeunitName: Text;
Functionate: Text; FunctionTestPermissions: TestPermissions;
if IsNull(PermissionTestHelper) then
if FunctionTestPermissions <> TestPermissions::Disabled then
CodeunitId, CopyStr(CodeunitName, 1, 30),
CopyStr(FunctionName, 1, 128),
To allow usage of the PermissionTestHelper it needs to be wrapped in a dotnet wrapper. On BC19, the aforementioned Permission Mock app does this for us.
Running these tests with the new test runner in the AL Test Tool shows that only the test with
TestPermissions set to Disabled succeeds. All other tests do have set
TestPermissions to either NonRestrictive or Restrictive. The latter implicitly on the first and last test inheriting this from the test codeunit:
Interested in the 2nd edition of the book?
It will be published around the released of Dynamics 365 Business Central 2021 wave 2. You can read about its project content here: .
I wrote this article weeks ago. In the mean time MS has added the Permissions Mock app to 18.3 that was released at the start of this week.