Skip to content

Commit bfef8e1

Browse files
Document test standards: built-module testing, no mocks, local run commands
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
1 parent 0b4b9e8 commit bfef8e1

2 files changed

Lines changed: 18 additions & 2 deletions

File tree

src/docs/Modules/Standards.md

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -311,9 +311,21 @@ Each `*.Tests.ps1` file must declare the Pester 6 requirement:
311311
#Requires -Modules @{ ModuleName = 'Pester'; ModuleVersion = '6.0.0'; MaximumVersion = '6.*' }
312312
```
313313

314-
Tests run against the built module artifact installed locally, across a multi-OS matrix (Linux, macOS, Windows). The full suite must also remain runnable locally without mandatory cloud resources, special access, or secrets that cannot be mocked.
314+
Tests run against the **built and imported module artifact**, never against source files under `src/`. The Process-PSModule pipeline builds the module first, imports the built module, and only then runs the test matrix, across a multi-OS matrix (Linux, macOS, Windows). Test files must not build or import the module themselves — they assume the module is already imported into the session by the framework (or by the contributor locally, see below) and call its exported commands directly.
315315

316-
Unit tests mock boundaries owned by the module, not third-party APIs or SDKs directly. Wrap external dependencies behind a thin module-owned interface and fake that interface. Where the external contract matters, back the unit tests with a small integration suite that exercises the live dependency.
316+
The full suite must also remain deterministic and runnable locally without mandatory cloud resources, special access, or secrets that cannot be faked. See [Running tests locally](#running-tests-locally).
317+
318+
**No mocks.** Tests use real inputs and real expected outputs against the actual exported commands — see [Test Specification](Test-Specification.md#5-test-guidelines). Where a command depends on an external system that cannot be exercised in CI (a live third-party API, for example), that dependency is wrapped behind a thin module-owned interface, and a small integration suite exercises the live dependency directly, rather than substituting a mock into the unit tests.
319+
320+
A single consolidated `tests/<ModuleName>.Tests.ps1` file (the **Simple** profile below) is the preferred layout for a module. Only split into the **Standard** or **Advanced** profile when the consolidated file becomes too large or unrelated to read as one suite.
321+
322+
### Running tests locally
323+
324+
1. Build the module: `./build.ps1` (or the repository's equivalent local build entry point under `tools/*.ps1`).
325+
2. Import the built artifact, not the source: `Import-Module ./output/<ModuleName>/<ModuleName>.psd1 -Force`.
326+
3. Run the suite: `Invoke-Pester -Path ./tests/ -CI`.
327+
328+
Never run `Invoke-Pester` against `src/` or with the module imported via a source-loading helper — that does not reproduce what CI validates.
317329

318330
### Shared test infrastructure
319331

@@ -322,6 +334,8 @@ Tests run in parallel across multiple OS runners. When integration tests need sh
322334
- `tests/BeforeAll.ps1` — special root workflow phase that runs once before the full test matrix. Create shared resources here.
323335
- `tests/AfterAll.ps1` — special root workflow phase that runs once after the full test matrix. Remove shared resources here.
324336

337+
`tests/BeforeAll.ps1` is a shared setup entry point owned by the framework, not a place to import or build the module — the framework already guarantees the built module is imported before any test phase runs. Use it only for shared external resources (test fixtures, live service state) that every test file in the matrix depends on.
338+
325339
These exact root files are detected separately and are not recursive test entries. Nested files with these names do not create workflow phases.
326340

327341
Use `$env:GITHUB_RUN_ID` (stable per workflow run, shared across all runners) for deterministic resource names:

src/docs/Modules/Test-Specification.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
This document defines the structure and guidelines for writing Pester tests for PowerShell functions. The goal is to ensure consistency and comprehensive test coverage while maintaining clarity.
66

7+
Tests run against the **built and imported module**, not against source files, and test files do not bootstrap or import the module themselves. See [Standards § Tests](Standards.md#tests) for the full process: file layout, running tests locally, and the no-mocks rule.
8+
79
## Test Structure
810

911
Each function is tested within a structured Pester `Describe` block that follows this hierarchy:

0 commit comments

Comments
 (0)