Global procedures in test codeunits must be test methods (TA0001)

Codeunits with Subtype = Test define the executable surface for automated tests. Only procedures that represent actual tests are allowed to be globally visible in this context. Any global procedure must therefore be explicitly marked with the [Test] attribute.

A global procedure without a [Test] attribute in a test codeunit usually indicates one of two problems. Either a test was written but the [Test] attribute was forgotten, meaning the procedure will never be executed by the test runner, or reusable logic was placed directly in the test codeunit, unintentionally exposing it.

This rule enforces a clear separation of concerns. Test codeunits contain test entry points only. Helper logic that is specific to a single test codeunit must be declared as local. Logic that needs to be reused across multiple test codeunits must be moved to a dedicated library codeunit.

Example

codeunit 50100 MyTestCodeunit
{
    Subtype = Test;

    procedure MyGlobalHelper() // Global procedures in test codeunits must be test methods [TC0001]
    begin
    end;

    [Test]
    procedure MyTest()
    begin
    end;
}

In this example MyGlobalHelper is globally visible but is not marked as a test. It will not be executed by the test runner and should not be exposed from a test codeunit.

Correct usage

If the procedure is intended to be a test, explicitly mark it with the [Test] attribute.

[Test]
procedure MyTest()
begin
end;

If the procedure is a helper used only inside the same test codeunit, make it local.

local procedure MyHelper()
begin
end;

If the procedure must be shared across multiple test codeunits, move it to a library codeunit.

codeunit 50110 TestLibrary
{
    procedure SharedHelper()
    begin
    end;
}

Rationale

Allowing non-test global procedures in test codeunits blurs architectural boundaries and creates an implicit API surface that is neither production code nor a test entry point. This makes tests harder to reason about, encourages unintended coupling between test codeunits, and hides errors such as forgotten [Test] attributes.

By requiring all global procedures in test codeunits to be test methods, this rule keeps the test surface explicit, prevents dead or unreachable test code, and enforces a clean separation between tests, helpers, and reusable libraries.