* Add 3 more AL/BC patterns from CURABIS Academy testing course material Third batch from CURABIS ApS: item-ledger-entry document-no lookup after Ship-and-Invoice posting, TestPage.Visible()/.Enabled() as the mechanism for verifying field UI state, and LibraryUtility.GenerateGUID() for collision-free test fixture values. * Address Jesper Schulz-Wedde's review on PR #158 - use-generateguid-for-unique-test-fixture-values.md: GenerateGUID() is a Code[10] number-series value, not a real GUID; truncating it with CopyStr for a shorter field cuts off the changing digits. Point to GenerateRandomCode/GenerateRandomCodeWithLength/GenerateRandomXMLText instead, which verify uniqueness against the actual table. - Split use-testpage-visible-enabled-to-verify-field-ui-state.md: drop its editability claim (the sample opens with OpenView() and asserts Enabled(), which verifies enabled state, not editability — Editable() and Enabled() are distinct TestField methods). New companion article use-testpage-editable-to-verify-field-editability.md covers Editable() with OpenEdit() specifically. - Wire GenerateGUID/CopyStr and TestPage Visible/Enabled/Editable cues into al-testing-review.md, and the Item Ledger Entry/Last Shipping No. posting cue into al-data-modeling-review.md. The Item Ledger Entry article itself was independently verified against current BCApps source and needs no changes. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * Address second round of Jesper Schulz-Wedde's review on PR #158 - use-generateguid-for-unique-test-fixture-values.md/.good.al: documented each LibraryUtility helper's actual behavior, verified against LibraryUtility.Codeunit.al. GenerateRandomCode opens the target table as a temporary RecordRef, so despite taking TableNo it never checks real data. GenerateRandomXMLText performs no table lookup at all. Only GenerateRandomCodeWithLength/GenerateRandomCode20 (capped at Code[10]/ Code[20]) genuinely verify against the real table. Fixture switched to GenerateRandomCodeWithLength where the comment claims verified uniqueness. - al-testing-review.md: rewired the cue to catch the actual anti-pattern (hardcoded literals, hand-built uniqueness, short-field GUID truncation) instead of only matching the compliant GenerateGUID()+CopyStr shape; broadened tokens to include TestPage, Library - Utility, and .Visible()/.Enabled()/.Editable(). - al-data-modeling-review.md: restricted the Item Ledger Entry Last-Shipping-No. cue to sales combined posting; purchase combined posting is Receive+Invoice and uses different fields entirely. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * Fix remaining correctness issues from Jesper's 2026-09-15 re-review - use-generateguid-for-unique-test-fixture-values.md: narrowed the collision rule to primary-key/unique-lookup fields - an ordinary descriptive field carries no uniqueness constraint, so a hardcoded or deterministic value there isn't the anti-pattern (the article and its al-testing-review.md worklist cue both said "primary-key or descriptive field"). Also corrected GenerateRandomCode: it opens its target table as a temporary RecordRef that starts and stays empty, so its repeat/until loop always exits after one iteration and never retries even within a single test run - the "non-colliding within a test run" claim was false. It's the rightmost N characters of GenerateGUID()'s sequential series, so a short field's value cycles (Code[1] repeats every 10 calls, Code[2] every 100). Verified against LibraryUtility.Codeunit.al in the BCApps reference clone. - item-ledger-entry-document-no-follows-last-shipping-no: both fixtures called FindSet() without consuming its optional Boolean, which raises a runtime error on an empty result set - the opposite of the article's own claimed "silently matches zero rows, no error" behavior. Wrapped in `if ... then;` per the existing guard-database-reads.good.al idiom. - al-data-modeling-review.md: widened both not-applicable scope clauses (intro and outcome) to include dimension wiring, posting- routine structure, and Item Ledger Entry document-number lookups - the leaf declared itself not-applicable outside setup/master/key/ numbering/block/audit surfaces despite having a targeted cue for this PR's own new article. - Converted this PR's 8 plain-backtick "See sample: `x.good.al`." references (across all 4 new articles) to the READ-convention markdown-link form required by Knowledge-Retrieval.ps1. Rebased onto upstream/main (one conflict in al-data-modeling-review.md intro wording, merged). * Stop routing GenerateRandomCode20 as compliant for shorter fields al-testing-review.md's cue presented GenerateRandomCodeWithLength and GenerateRandomCode20 as interchangeable options for "a shorter field needing real verified uniqueness." They aren't: verified against LibraryUtility.Codeunit.al, GenerateRandomCode20 truncates GenerateGUID()'s sequential value down to the target field's length by keeping the leftmost (slowest-changing) characters via PadStr, so its retry loop against a field shorter than 20 can churn through the same truncated prefix for a long time. GenerateRandomCodeWithLength has no such problem (it generates exactly the requested length of random text). The knowledge article itself already scoped GenerateRandomCode20 to Code[20] correctly - only the skill cue needed narrowing to match. --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
1.4 KiB
| bc-version | domain | keywords | technologies | countries | application-area | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
testing |
|
|
|
|
Verify field editability with TestPage.Editable(), opened in edit mode
Description
Whether a field can actually be changed is a distinct state from whether it is shown or enabled — Editable() and Enabled() are separate TestField functions. Verifying editability also requires opening the TestPage with OpenEdit(), not OpenView(): OpenView() opens the page in view mode, so it does not exercise the field's own conditional editability logic the way an actual edit-mode session does.
Best Practice
Open the TestPage with OpenEdit(), navigate to the relevant record, then assert against TestPageField.Editable() to verify whether the field can be changed under the given precondition.
See sample: use-testpage-editable-to-verify-field-editability.good.al.
Anti Pattern
Asserting Enabled() (or checking nothing at all) when the actual claim is about editability, or opening the page with OpenView() when the field's editability depends on business logic that only applies in edit mode.
See sample: use-testpage-editable-to-verify-field-editability.bad.al.