bcquality/microsoft/knowledge/testing/reset-per-test-state-before-the-isinitialized-guard.md
Stefano Demiliani 4287233f80
Strengthen review contracts and add AL reliability guidance (#196)
* Strengthen review contracts and HTTP guidance

- add outbound HttpClient transport and HTTP status review rules with paired fixtures`n- resolve layered action-skill overrides deterministically across enabled layers`n- validate findings reports and enforce measurable changed-fixture coverage

* Add data handling and test isolation guidance

- add SCM guidance for deriving base quantities through line unit-of-measure validation`n- add security guidance for parameterizing SetFilter with external text`n- add test isolation guidance for resetting per-test state before initialization guards`n- add web-service guidance for JSON null handling and invariant standard format 9`n- route and cover all five rules with paired evaluation fixtures

* Fix findings report rollup validation

* Validate findings report rollups

* Enforce merged finding identity

* Fix locationless finding deduplication

* Reject conflicting merged corrections

* Detect conflicting leaf corrections

* Route HTTP error checks to canonical web-services knowledge

Let the Error Handling leaf conditionally retrieve the existing HTTP owner articles, preserving applicability and exact-path provenance. Add deterministic source-contract and retrieval regressions without duplicating knowledge rules.

Copilot-Session-Id: a92a7788-103e-4651-9b84-19e34caffb94

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: wenjiefan <wenjiefan@microsoft.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Jesper Schulz-Wedde <jesper.schulzwedde@microsoft.com>
2026-09-29 13:03:39 +02:00

3.9 KiB

bc-version domain keywords technologies countries application-area
all
testing
initialize
isinitialized
library-test-initialize
ontestinitialize
library-variable-storage
library-setup-storage
test-fixture
test-codeunit
al
w1
all

Reset per-test state before the IsInitialized guard

Description

Standard Business Central test codeunits call a local Initialize procedure at the start of every test method. Global variables in a test codeunit keep their values between the codeunit's test methods, so a Boolean such as IsInitialized lets Initialize run expensive shared setup only once. The procedure therefore has two parts with different lifetimes: work that must run before every test, and one-time setup behind the guard. If per-test reset is placed after the guard, it runs only for the first test. Values left in Library - Variable Storage by a failed test, or setup records a test changed, then leak into later tests, which pass or fail depending on execution order.

Best Practice

Call Initialize() as the first statement of every test method. Inside it, keep this order, which the Base Application tests follow:

  1. Per-test work, before the guard: raise "Library - Test Initialize".OnTestInitialize, call LibraryVariableStorage.Clear(), and call LibrarySetupStorage.Restore() when setup tables were saved.
  2. if IsInitialized then exit;
  3. One-time work: raise OnBeforeTestSuiteInitialize, create the shared fixture and setup values, set IsInitialized := true, save the setup tables that tests may change (for example LibrarySetupStorage.SaveSalesSetup()), and raise OnAfterTestSuiteInitialize.

Create data that a single test changes inside that test, not in the shared fixture. Base Application suites also commit after the one-time setup so the shared fixture survives each test's transaction; whether that commit is valid depends on the test transaction model and runner isolation, see transactionmodel-attribute-governs-test-transactions.md and testisolation-belongs-on-the-test-runner.md.

A test codeunit with no shared setup and no queued values doesn't need an Initialize procedure. Don't report its absence on its own.

See sample: reset-per-test-state-before-the-isinitialized-guard.good.al.

Anti Pattern

if IsInitialized then exit; as the first statement of Initialize, followed by LibraryVariableStorage.Clear(), LibrarySetupStorage.Restore(), or other reset calls that are then skipped for every test after the first. A related defect is a test method in a codeunit that uses the pattern but doesn't call Initialize(), so it runs with whatever state the previous test left. Detection signal: in a Subtype = Test codeunit, a reset call placed after the IsInitialized exit, or a [Test] procedure that uses shared globals or queued values without first calling Initialize().

See sample: reset-per-test-state-before-the-isinitialized-guard.bad.al.

References