Skip to the content

News

Service to service authentication in Business Central 18.3 – How to test (Postman & Insomnia)

This is the next blog post in a series about service to service authentication in Business Central. Please see the previous blog posts for more information: Usage and license terms How to set up Test with VS Code REST Client ...

Directions EMEA Community Award 2021

Super exited to announce the Directions EMEA Community Award 2021! After a successful edition in 2019, we are running the Community Awards again, because we want to honour and put a spotlight on Dynamics Partners who have done something outstanding in the past year. Becoming a Directions Community Award Winner is an honour within the Dynamics Community but it's also a reward for the hard work and the extra mile your team has run to make it happen! It will be an inspiration to all of us! 

2021 Wave 2 Release plans for Dynamics 365 and Power Platform released

Dynamics 365 & Power Platform Plans Here are the links to the external release plans; the PDF copy is available when you access these links · https://aka.ms/Dynamics365Wave2ReleasePlan · https://aka.ms/PowerPlatformWave2ReleasePlan Dynamics 365 Business Central Plan for Release 2021 Wave2 (r.19) This topic lists features that are planned to release from October 2021 through March 2022. Because […]

L'articolo proviene da .

Service to service authentication in Business Central 18.3 – How to test (REST Client & PowerShell)

In the previous blog posts I’ve described the usage scenarios around OAuth client credentials flow for Business Central and how to set it up. The next step is to test the APIs and with OAuth authentication to see if it ...

The Testability Framework: Pillar 6 – Test Permissions

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.

Test Permissions

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 OnBeforeTestRun and 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.

TestPermissions property

The 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.

PermissionTestHelper

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 TestPermissions property:

codeunit 60051 "MyFifthTestCodeunit.Codeunit"
{
  Subtype = Test;

  [Test]
  procedure DeleteItemLedgerEntry()
  begin
    DeleteILE();
  end;

  [Test]
  [TestPermissions(TestPermissions::Disabled)]
  procedure DeleteItemLedgerEntryTpDisabled()
  begin
    DeleteILE();
  end;

  [Test]
  [TestPermissions(TestPermissions::Restrictive)]
  procedure DeleteItemLedgerEntryTpRestrictive()
  begin
    DeleteILE();
  end;

  [Test]
  [TestPermissions(TestPermissions::NonRestrictive)]
  procedure DeleteItemLedgerEntryTpNonRestrictive()
  begin
    DeleteILE();
  end;

  [Test]
  [TestPermissions(TestPermissions::InheritFromTestCodeunit)]
  procedure DeleteItemLedgerEntryTpInheritFromTestCodeunit()
  begin
    DeleteILE();
  end;

  local procedure DeleteILE()
  var
    ItemLedgerEntry: Record "Item Ledger Entry";
  begin
    ItemLedgerEntry.FindLast();
    ItemLedgerEntry.Delete();
  end;
}

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";
  Permissions =
    TableData "AL Test Suite" = rimd,
    TableData "Test Method Line" = rimd;

  trigger OnRun()
  begin
    ALTestSuite.Get(Rec."Test Suite");
    CurrentTestMethodLine.Copy(Rec);
    TestRunnerMgt.RunTests(Rec);
  end;

  var
    ALTestSuite: Record "AL Test Suite";
    CurrentTestMethodLine: Record "Test Method Line";
    TestRunnerMgt: Codeunit "Test Runner - Mgt";
    PermissionTestHelper: DotNet NavPermissionTestHelper;

  trigger OnBeforeTestRun(CodeunitId: Integer; CodeunitName: Text;
    FunctionName: Text;
    FunctionTestPermissions: TestPermissions): Boolean
  begin
    if IsNull(PermissionTestHelper) then
      PermissionTestHelper :=
        PermissionTestHelper.PermissionTestHelper;

    PermissionTestHelper.Clear();

    case FunctionTestPermissions of
      TestPermissions::Restrictive:
        PermissionTestHelper.
          AddEffectivePermissionSet('O365 BASIC');
      TestPermissions::NonRestrictive:
        PermissionTestHelper.
          AddEffectivePermissionSet('O365 BUS FULL ACCESS');
      TestPermissions::Disabled:
        PermissionTestHelper.
          AddEffectivePermissionSet('SUPER');
    end;

    exit(
        TestRunnerMgt.PlatformBeforeTestRun(
        CodeunitId,
        CopyStr(CodeunitName, 1, 30),
        CopyStr(FunctionName, 1, 128),
        FunctionTestPermissions,
        ALTestSuite.Name,
        CurrentTestMethodLine.GetFilter("Line No."))
      );
  end;

  trigger OnAfterTestRun(CodeunitId: Integer; CodeunitName: Text;
    Functionate: Text; FunctionTestPermissions: TestPermissions;
    IsSuccess: Boolean)
  begin
   if IsNull(PermissionTestHelper) then
      PermissionTestHelper :=
        PermissionTestHelper.PermissionTestHelper;

    if FunctionTestPermissions <> TestPermissions::Disabled then
      PermissionTestHelper.Clear;

    TestRunnerMgt.PlatformAfterTestRun(
        CodeunitId, CopyStr(CodeunitName, 1, 30),
        CopyStr(FunctionName, 1, 128),
        FunctionTestPermissions,
        IsSuccess, ALTestSuite.Name,
        CurrentTestMethodLine.GetFilter("Line No.")
      );
  end;
}

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: .

Update

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.

The Testability Framework: Pillar 6 – Test Permissions (1)

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.

Test Permissions

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 OnBeforeTestRun and 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.

TestPermissions property

The 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.

PermissionTestHelper

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 TestPermissions property:

codeunit 60051 "MyFifthTestCodeunit.Codeunit"
{
  Subtype = Test;

  [Test]
  procedure DeleteItemLedgerEntry()
  begin
    DeleteILE();
  end;

  [Test]
  [TestPermissions(TestPermissions::Disabled)]
  procedure DeleteItemLedgerEntryTpDisabled()
  begin
    DeleteILE();
  end;

  [Test]
  [TestPermissions(TestPermissions::Restrictive)]
  procedure DeleteItemLedgerEntryTpRestrictive()
  begin
    DeleteILE();
  end;

  [Test]
  [TestPermissions(TestPermissions::NonRestrictive)]
  procedure DeleteItemLedgerEntryTpNonRestrictive()
  begin
    DeleteILE();
  end;

  [Test]
  [TestPermissions(TestPermissions::InheritFromTestCodeunit)]
  procedure DeleteItemLedgerEntryTpInheritFromTestCodeunit()
  begin
    DeleteILE();
  end;

  local procedure DeleteILE()
  var
    ItemLedgerEntry: Record "Item Ledger Entry";
  begin
    ItemLedgerEntry.FindLast();
    ItemLedgerEntry.Delete();
  end;
}

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";
	Permissions =
	TableData "AL Test Suite" = rimd,
	TableData "Test Method Line" = rimd;

	trigger OnRun()
	begin
	ALTestSuite.Get(Rec."Test Suite");
	CurrentTestMethodLine.Copy(Rec);
	TestRunnerMgt.RunTests(Rec);
	end;

	var
	ALTestSuite: Record "AL Test Suite";
	CurrentTestMethodLine: Record "Test Method Line";
	TestRunnerMgt: Codeunit "Test Runner - Mgt";
	PermissionTestHelper: DotNet NavPermissionTestHelper;

	trigger OnBeforeTestRun(CodeunitId: Integer; CodeunitName: Text;
	FunctionName: Text;
	FunctionTestPermissions: TestPermissions): Boolean
	begin
	if IsNull(PermissionTestHelper) then
		PermissionTestHelper :=
		PermissionTestHelper.PermissionTestHelper;

	PermissionTestHelper.Clear();

	case FunctionTestPermissions of
		TestPermissions::Restrictive:
		PermissionTestHelper.
			AddEffectivePermissionSet('O365 BASIC');
		TestPermissions::NonRestrictive:
		PermissionTestHelper.
			AddEffectivePermissionSet('O365 BUS FULL ACCESS');
		TestPermissions::Disabled:
		PermissionTestHelper.
			AddEffectivePermissionSet('SUPER');
	end;

	exit(
		TestRunnerMgt.PlatformBeforeTestRun(
		CodeunitId,
		CopyStr(CodeunitName, 1, 30),
		CopyStr(FunctionName, 1, 128),
		FunctionTestPermissions,
		ALTestSuite.Name,
		CurrentTestMethodLine.GetFilter("Line No."))
		);
	end;

	trigger OnAfterTestRun(CodeunitId: Integer; CodeunitName: Text;
	Functionate: Text; FunctionTestPermissions: TestPermissions;
	IsSuccess: Boolean)
	begin
	if IsNull(PermissionTestHelper) then
		PermissionTestHelper :=
		PermissionTestHelper.PermissionTestHelper;

	if FunctionTestPermissions <> TestPermissions::Disabled then
		PermissionTestHelper.Clear;

	TestRunnerMgt.PlatformAfterTestRun(
		CodeunitId, CopyStr(CodeunitName, 1, 30),
		CopyStr(FunctionName, 1, 128),
		FunctionTestPermissions,
		IsSuccess, ALTestSuite.Name,
		CurrentTestMethodLine.GetFilter("Line No.")
		);
	end;
}

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: .

Update

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.

Business Central rel. 18.3 – The “Data Administration” Page

Business Central rel. 18.3 – The “Data Administration” Page In Dynamics 365 Business Central, administrators have different options for handling table and database sizes; until now, these options have been available through several different pages and roles. With this new page, all processes are displayed in a single place. An in-product assistant can be used for guidance. These features were […]

L'articolo proviene da .

The long awaited Report Inspector is Save report dataset to Excel in BC 18.3!

Yes! It’s here! The long awaited Report Inspector in Business Central. Don’t know what I’m talking about, well let me bring you up-to-date: Microsoft Idea  · Report Inspector (dynamics.com) And now, with the release of Update 18.3 for Microsoft...

How-to use the "old" Test Tool, aka CAL Test Tool

For a long while, ever since NAV 2016, the Test Tool has been part of the application, which is in a way is somewhat strange as a Test Tool is typically something you don't want to be present in a production environment. Among other - more - important reasons, Microsoft introduced the AL Test Tool in the time of BC15, which resides in it's own extension called Test Runner. This does not reside in a CRONUS database, and thus typically needs to be installed before you can use it. To discriminate better between the two test tools I will refer to the first as CAL Test Tool - which happens to be the internal naming anyway - and the AL Test Tool.

Both test tools allow you to manage and run the automated tests that reside in the database, and collect their results, be they test codeunits that belong to the standard application or that are part of your code, C/AL or AL based extensions. In the 1st edition of my book , written for BC14 and older versions, the AL Test Tool did not yet exist and in the various hands-on test example I heavily made use of the CAL Test Tool. The , to be released in October and based on BC19, will make use of the AL Test Tool as the CAL Test Tool will be soon deprecated. So, no mentioning of the latter test tool anymore in the 2nd edition.

For those, however, still wanting to use the CAL Test Tool, I will share in this blog post the description of this test tool from the 1st edition of the book.

Access the CAL Test Tool

You can easily access the test tool by searching for Test Tool in either the Windows or the Web client. When in a clean database, or at least a database or company where the Test Tool has not been used yet, this is how the Test Tool appears. A suite called DEFAULT with no records in it appears, as seen as follows:

Populate the CAL Test Tool

To populate the suite take the following steps:

  1. Select the Get Test Codeunits
  2. On the dialog that opens, you have the following two options:
    • Select Test Codeunits: This will open a list page showing all test codeunits that are present in the database from which you can select specific test codeunits; once you have selected and clicked OK, these codeunits will be added to the suite
    • All Test Codeunits: This will add all test codeunits that exist in the database to the test suite

Let's select the first option, Select Test Codeunits. This will open the CAL Test Get Codeunits page showing all test codeunits. Unsurprisingly, in the context of the book, it shows the four test codeunits were created in Chapter 2, The Testability Framework, followed by the long list of over 700 standard test codeunits, as these were also added to the installation:

Note: as mentioned the 60000 range objects were created as part of Chapter 2 of the 1st edition. The code for these test codeunit can be found on the GitHub repo, folder Chapter 2, that goes with that edition: .

  1. Select the four test codeunits 60000 through 60003 and click OK.

The suite now shows for each test Codeunit a line with LINE TYPE = Codeunit and, linked to this line and indented, all its test functions (LINE TYPE = Function) as shown in the following screenshot:

  1. To run the tests, select the Run
  2. On the following dialog that opens, with options Active Codeunit and All, select All and press OK. Now all four test codeunits will be run and each test will yield a result Success or Failure:

Had we selected the option Active Codeunit only, the selected codeunit would have been executed.

For each failure, the First Error field will display the error that caused the failure. As you can see, First Error is a FlowField. If you drill down into it, the CAL Test Result window opens. This displays the whole test run history for a specific test. Note that the message dialog in MyFirstTestCodeunit yields an Unhandled UI error.

Running the test by selecting Run will call the standard test runner codeunit CAL Test Runner (130400) and will make sure that the following happen:

  • Tests run from the Test Tool will be run in isolation
  • The results of each test function will be logged

Test coverage map

The CAL Test Tool also holds a powerful feature that can be of great help in picking out relevant test codeunits for the code update you are working on. It is called Test Coverage Map (TCM). It combines the result of the code coverage tool that also resides in Business Central and the test tool. Having TCM turned on, it adds two extra options to the Get Test Codeunits feature already demoed in Chapter 3, The Test Tool and Standard Tests. There, we explained that Get Test Codeunits offers the following two options to let you populate your test suite:

  • Select Test Codeunits
  • All Test Codeunits

With TCM, two more options are added.

Choosing the third option, Get Test Codeunits based on Modified Objects, will select those test codeunits that will hit the application objects you are working on. The fourth optionGet Test Codeunits based on Selected Objects, let’s you select from a list those application objects you want to run tests against.

At this very moment, the Get Test Codeunits based on Modified Objects option only takes into account the application objects that reside in standard, that is, in C/SIDE. Unfortunately, it does not yet consider objects that reside in extensions.

Note: Probably for the latter reason TCM is only part of the CAL Test Tool and not of the AL Test Tool.

The fourth option, Get Test Codeunits based on Selected Objects, nevertheless includes all application objects.

To be able to use TCM, you need to turn it on. To do this, check mark the Update Test Coverage Map field on a test suite. If this has not been turned on, on any test suite, TCM will not have data to allow you to choose Get Test Codeunits based on Modified Objects and Get Test Codeunits based on Selected Objects options as described previously.

Note: For TCM to have the data available to do its job, the activated test suite should be run first.

In this overview of the CAL Test Tool, we used the following features:

  • Get test codeunits
  • Creating multiple test suites
  • Test Coverage Map

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: .

How-to use the "old" Test Tool, aka CAL Test Tool (1)

For a long while, ever since NAV 2016, the Test Tool has been part of the application, which is in a way is somewhat strange as a Test Tool is typically something you don’t want to be present in a production environment. Among other – more – important reasons, Microsoft introduced the AL Test Tool in the time of BC15, which resides in it’s own extension called Test Runner. This does not reside in a CRONUS database, and thus typically needs to be installed before you can use it. To discriminate better between the two test tools I will refer to the first as CAL Test Tool – which happens to be the internal naming anyway – and the AL Test Tool.

Both test tools allow you to manage and run the automated tests that reside in the database, and collect their results, be they test codeunits that belong to the standard application or that are part of your code, C/AL or AL based extensions. In the 1st edition of my book , written for BC14 and older versions, the AL Test Tool did not yet exist and in the various hands-on test example I heavily made use of the CAL Test Tool. The , to be released in October and based on BC19, will make use of the AL Test Tool as the CAL Test Tool will be soon deprecated. So, no mentioning of the latter test tool anymore in the 2nd edition.

For those, however, still wanting to use the CAL Test Tool, I will share in this blog post the description of this test tool from the 1st edition of the book.

Access the CAL Test Tool

You can easily access the test tool by searching for Test Tool in either the Windows or the Web client. When in a clean database, or at least a database or company where the Test Tool has not been used yet, this is how the Test Tool appears. A suite called DEFAULT with no records in it appears, as seen as follows:

Populate the CAL Test Tool

To populate the suite take the following steps:

  1. Select the Get Test Codeunits
  2. On the dialog that opens, you have the following two options:
    • Select Test Codeunits: This will open a list page showing all test codeunits that are present in the database from which you can select specific test codeunits; once you have selected and clicked OK, these codeunits will be added to the suite
    • All Test Codeunits: This will add all test codeunits that exist in the database to the test suite

Let’s select the first option, Select Test Codeunits. This will open the CAL Test Get Codeunits page showing all test codeunits. Unsurprisingly, in the context of the book, it shows the four test codeunits were created in Chapter 2, The Testability Framework, followed by the long list of over 700 standard test codeunits, as these were also added to the installation:

Note: as mentioned the 60000 range objects were created as part of Chapter 2 of the 1st edition. The code for these test codeunit can be found on the GitHub repo, folder Chapter 2, that goes with that edition: .

  1. Select the four test codeunits 60000 through 60003 and click OK.

The suite now shows for each test Codeunit a line with LINE TYPE = Codeunit and, linked to this line and indented, all its test functions (LINE TYPE = Function) as shown in the following screenshot:

  1. To run the tests, select the Run
  2. On the following dialog that opens, with options Active Codeunit and All, select All and press OK. Now all four test codeunits will be run and each test will yield a result Success or Failure:

Had we selected the option Active Codeunit only, the selected codeunit would have been executed.

For each failure, the First Error field will display the error that caused the failure. As you can see, First Error is a FlowField. If you drill down into it, the CAL Test Result window opens. This displays the whole test run history for a specific test. Note that the message dialog in MyFirstTestCodeunit yields an Unhandled UI error.

Running the test by selecting Run will call the standard test runner codeunit CAL Test Runner (130400) and will make sure that the following happen:

  • Tests run from the Test Tool will be run in isolation
  • The results of each test function will be logged

Test coverage map

The CAL Test Tool also holds a powerful feature that can be of great help in picking out relevant test codeunits for the code update you are working on. It is called Test Coverage Map (TCM). It combines the result of the code coverage tool that also resides in Business Central and the test tool. Having TCM turned on, it adds two extra options to the Get Test Codeunits feature already demoed in Chapter 3, The Test Tool and Standard Tests. There, we explained that Get Test Codeunits offers the following two options to let you populate your test suite:

  • Select Test Codeunits
  • All Test Codeunits

With TCM, two more options are added.

Choosing the third option, Get Test Codeunits based on Modified Objects, will select those test codeunits that will hit the application objects you are working on. The fourth option, Get Test Codeunits based on Selected Objects, let’s you select from a list those application objects you want to run tests against.

At this very moment, the Get Test Codeunits based on Modified Objects option only takes into account the application objects that reside in standard, that is, in C/SIDE. Unfortunately, it does not yet consider objects that reside in extensions.

Note: Probably for the latter reason TCM is only part of the CAL Test Tool and not of the AL Test Tool.

The fourth option, Get Test Codeunits based on Selected Objects, nevertheless includes all application objects.

To be able to use TCM, you need to turn it on. To do this, check mark the Update Test Coverage Map field on a test suite. If this has not been turned on, on any test suite, TCM will not have data to allow you to choose Get Test Codeunits based on Modified Objects and Get Test Codeunits based on Selected Objects options as described previously.

Note: For TCM to have the data available to do its job, the activated test suite should be run first.

In this overview of the CAL Test Tool, we used the following features:

  • Get test codeunits
  • Creating multiple test suites
  • Test Coverage Map

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: .