The AL test framework

Writing automated tests in AL — test codeunits, test runners, test isolation, and the libraries Microsoft ships with Business Central.

Updated 2025-10-18

Business Central ships with a full test framework for AL that's the right tool for both unit tests and integration tests of your extensions. Adopting it is a one-time investment that pays back the first time you regression-test a major release wave update.

Test codeunits. A test codeunit is a normal codeunit with the Subtype = Test property set. Each test method is decorated with [Test], optionally [HandlerFunctions(...)] to register UI handlers, and [TransactionModel(...)] to control transactional isolation. The test runner discovers test codeunits in installed extensions and executes them in containers.

Test isolation. By default, each test runs in a rolled-back transaction, so changes don't persist between tests. This is what makes the suite re-runnable against the same database. For tests that genuinely need to commit (e.g. testing a sequence of posted documents), TransactionModel::AutoCommit is available; use it sparingly.

Test libraries. Microsoft publishes a set of test libraries as separate AL packages: Test Library - Sales, Test Library - Inventory, Test Library - ERM, etc. They give you helper functions like CreateCustomer, CreateItem, PostSalesDocument that produce valid test data without you wiring up every field. They live on AppSource and are installed into sandbox environments where tests run.

Handler functions. AL tests run headless, so any dialogs or pages the code-under-test opens need a handler. A [MessageHandler], [ConfirmHandler], [ModalPageHandler], or [ReportHandler] registered on the test codeunit catches the call and lets the test assert and respond.

Assertions. The Assert codeunit provides IsTrue, IsFalse, AreEqual, AreNotEqual, RecordCount, and string/error variants. Idiomatic AL tests follow the arrange, act, assert pattern.

Running tests. Inside Business Central, the Test Tool page lists test codeunits, lets you run them interactively, and shows pass/fail. From CI, the Run-TestsInBcContainer PowerShell cmdlet (part of the BC Container Helper) runs tests headless and emits results in JUnit XML for build pipelines.

Code coverage. AL has built-in code coverage reporting; the test runner can produce a coverage map showing which lines of the system-under-test were exercised.

Where to start. Don't try for 100% coverage. Start by testing the posting paths that matter — your sales discount calculation, your custom price formulas, your event subscribers — and grow from there.

Related guides