The AL test framework
Writing automated tests in AL — test codeunits, test runners, test isolation, and the libraries Microsoft ships with Business Central.
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
- AL events and integration patternsHow AL events let extensions hook into Business Central — business events, integration events, subscriber patterns, and what to avoid.
- AL extension architectureHow AL extensions are structured in Business Central — objects, namespaces, app.json, dependencies, and the runtime model.
- AL language and runtime evolutionHow the AL language for Business Central evolved from C/AL — runtime versions, language features added wave by wave, and what AL is becoming.
- Business Central CI/CD with AL-GoHow AL-Go for GitHub turns an AL extension repo into a build-test-deploy pipeline — secrets, environments, and continuous delivery.
- Business Central web servicesThe classic OData and SOAP web services in Business Central — how they differ from the v2.0 API, and when to use them.