diff --git a/docs/README.instructions.md b/docs/README.instructions.md index c4546df9..2b142e6f 100644 --- a/docs/README.instructions.md +++ b/docs/README.instructions.md @@ -166,7 +166,7 @@ See [CONTRIBUTING.md](../CONTRIBUTING.md#adding-instructions) for guidelines on | [Power Platform Connectors Schema Development Instructions](../instructions/power-platform-connector.instructions.md)
[![Install in VS Code](https://img.shields.io/badge/VS_Code-Install-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](https://aka.ms/awesome-copilot/install/instructions?url=vscode%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fpower-platform-connector.instructions.md)
[![Install in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Install-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](https://aka.ms/awesome-copilot/install/instructions?url=vscode-insiders%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fpower-platform-connector.instructions.md) | Comprehensive development guidelines for Power Platform Custom Connectors using JSON Schema definitions. Covers API definitions (Swagger 2.0), API properties, and settings configuration with Microsoft extensions. | | [Power Platform MCP Custom Connector Development](../instructions/power-platform-mcp-development.instructions.md)
[![Install in VS Code](https://img.shields.io/badge/VS_Code-Install-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](https://aka.ms/awesome-copilot/install/instructions?url=vscode%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fpower-platform-mcp-development.instructions.md)
[![Install in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Install-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](https://aka.ms/awesome-copilot/install/instructions?url=vscode-insiders%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fpower-platform-mcp-development.instructions.md) | Instructions for developing Power Platform custom connectors with Model Context Protocol (MCP) integration for Microsoft Copilot Studio | | [PowerShell Cmdlet Development Guidelines](../instructions/powershell.instructions.md)
[![Install in VS Code](https://img.shields.io/badge/VS_Code-Install-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](https://aka.ms/awesome-copilot/install/instructions?url=vscode%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fpowershell.instructions.md)
[![Install in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Install-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](https://aka.ms/awesome-copilot/install/instructions?url=vscode-insiders%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fpowershell.instructions.md) | PowerShell cmdlet and scripting best practices based on Microsoft guidelines | -| [PowerShell Pester v5 Testing Guidelines](../instructions/powershell-pester-5.instructions.md)
[![Install in VS Code](https://img.shields.io/badge/VS_Code-Install-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](https://aka.ms/awesome-copilot/install/instructions?url=vscode%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fpowershell-pester-5.instructions.md)
[![Install in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Install-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](https://aka.ms/awesome-copilot/install/instructions?url=vscode-insiders%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fpowershell-pester-5.instructions.md) | PowerShell Pester testing best practices based on Pester v5 conventions | +| [PowerShell Pester v6 Testing Guidelines](../instructions/powershell-pester-6.instructions.md)
[![Install in VS Code](https://img.shields.io/badge/VS_Code-Install-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](https://aka.ms/awesome-copilot/install/instructions?url=vscode%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fpowershell-pester-6.instructions.md)
[![Install in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Install-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](https://aka.ms/awesome-copilot/install/instructions?url=vscode-insiders%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fpowershell-pester-6.instructions.md) | PowerShell Pester testing best practices based on Pester v6 conventions | | [Project Context](../instructions/moodle.instructions.md)
[![Install in VS Code](https://img.shields.io/badge/VS_Code-Install-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](https://aka.ms/awesome-copilot/install/instructions?url=vscode%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fmoodle.instructions.md)
[![Install in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Install-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](https://aka.ms/awesome-copilot/install/instructions?url=vscode-insiders%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fmoodle.instructions.md) | Instructions for GitHub Copilot to generate code in a Moodle project context. | | [Python MCP Server Development](../instructions/python-mcp-server.instructions.md)
[![Install in VS Code](https://img.shields.io/badge/VS_Code-Install-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](https://aka.ms/awesome-copilot/install/instructions?url=vscode%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fpython-mcp-server.instructions.md)
[![Install in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Install-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](https://aka.ms/awesome-copilot/install/instructions?url=vscode-insiders%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fpython-mcp-server.instructions.md) | Instructions for building Model Context Protocol (MCP) servers using the Python SDK | | [QA Engineering Best Practices](../instructions/qa-engineering-best-practices.instructions.md)
[![Install in VS Code](https://img.shields.io/badge/VS_Code-Install-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](https://aka.ms/awesome-copilot/install/instructions?url=vscode%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fqa-engineering-best-practices.instructions.md)
[![Install in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Install-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](https://aka.ms/awesome-copilot/install/instructions?url=vscode-insiders%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fqa-engineering-best-practices.instructions.md) | Comprehensive QA engineering best practices covering test strategy, test pyramid, naming conventions, assertion patterns, bug reporting, and automation guidelines for modern software projects. | diff --git a/instructions/powershell-pester-5.instructions.md b/instructions/powershell-pester-6.instructions.md similarity index 68% rename from instructions/powershell-pester-5.instructions.md rename to instructions/powershell-pester-6.instructions.md index 821ae34d..49839fbd 100644 --- a/instructions/powershell-pester-5.instructions.md +++ b/instructions/powershell-pester-6.instructions.md @@ -1,11 +1,13 @@ --- applyTo: '**/*.Tests.ps1' -description: 'PowerShell Pester testing best practices based on Pester v5 conventions' +description: 'PowerShell Pester testing best practices based on Pester v6 conventions' --- -# PowerShell Pester v5 Testing Guidelines +# PowerShell Pester v6 Testing Guidelines -This guide provides PowerShell-specific instructions for creating automated tests using PowerShell Pester v5 module. Follow PowerShell cmdlet development guidelines in [powershell.instructions.md](./powershell.instructions.md) for general PowerShell scripting best practices. +This guide provides PowerShell-specific instructions for creating automated tests with the PowerShell Pester v6 module. Pester v6 runs on Windows PowerShell 5.1 and PowerShell 7.4+. Follow the general PowerShell scripting guidance in [powershell.instructions.md](./powershell.instructions.md). + +Pester v6 is largely compatible with v5, but it makes several previously deprecated behaviours fail fast. Keep each test file self-contained and run the suite with the same PowerShell and Pester versions used by CI. ## File Naming and Structure @@ -27,12 +29,33 @@ Describe 'FunctionName' { } ``` +## Discovery and Run + +- Pester v6 discovers and runs one file at a time. Do not rely on discovery-time side effects from another test file (for example, a global variable, current directory, or imported module). +- Use `BeforeDiscovery` for data needed to construct tests and `BeforeAll` to import modules or initialise runtime state for the file. +- Keep every test file independently runnable; place shared setup in a Pester configuration (`Run.BeforeContainer`) or a repository `Pester.BeforeContainer.ps1` when it truly applies to all files. + +```powershell +BeforeDiscovery { + $cases = Get-Content "$PSScriptRoot/cases.json" | ConvertFrom-Json +} + +BeforeAll { + Import-Module "$PSScriptRoot/MyModule.psm1" +} + +Describe 'MyModule' { + It 'handles ' -ForEach $cases { Invoke-Thing $Name | Should -Be 'ok' } +} +``` + ## Core Keywords - **`Describe`**: Top-level grouping, typically named after function being tested - **`Context`**: Sub-grouping within Describe for specific scenarios - **`It`**: Individual test cases, use descriptive names -- **`Should`**: Assertion keyword for test validation +- **`Should`**: Classic assertion command (`Should -Be`, `Should -Throw`, etc.); existing v5 syntax remains supported +- **`Should-*`**: New v6 assertion commands (`Should-Be`, `Should-Throw`, etc.); adopt them deliberately, not as a required rename - **`BeforeAll/AfterAll`**: Setup/teardown once per block - **`BeforeEach/AfterEach`**: Setup/teardown before/after each test @@ -42,7 +65,8 @@ Describe 'FunctionName' { - **`BeforeEach`**: Runs before every `It` in block, use for test-specific setup - **`AfterEach`**: Runs after every `It`, guaranteed even if test fails - **`AfterAll`**: Runs once at end of block, use for cleanup -- **Variable Scoping**: `BeforeAll` variables available to child blocks (read-only), `BeforeEach/It/AfterEach` share same scope +- **Variable Scoping**: `BeforeAll` variables are available to child blocks (read-only); `BeforeEach`, `It`, and `AfterEach` share their block scope +- **One hook of each type**: A block may contain only one `BeforeAll`, `BeforeEach`, `AfterAll`, or `AfterEach`; combine setup when necessary ## Assertions (Should) @@ -63,6 +87,8 @@ Describe 'FunctionName' { - **`Should -InvokeVerifiable`**: Verify all verifiable mocks were called - **Scope**: Mocks default to containing block scope +Pester v6 removes `Assert-MockCalled` and `Assert-VerifiableMock`; replace them with the `Should -Invoke` forms. Calls that miss every `-ParameterFilter` no longer fall through to the real command, so add a default mock whenever unmatched calls are valid. + ```powershell Mock Get-Service { @{ Status = 'Running' } } -ParameterFilter { $Name -eq 'TestService' } Should -Invoke Get-Service -Exactly 1 -ParameterFilter { $Name -eq 'TestService' } @@ -70,7 +96,7 @@ Should -Invoke Get-Service -Exactly 1 -ParameterFilter { $Name -eq 'TestService' ## Test Cases (Data-Driven Tests) -Use `-TestCases` or `-ForEach` for parameterized tests: +Use `-TestCases` or `-ForEach` for parameterized tests. In Pester v6, `$null` or an empty array throws instead of silently skipping; fix the data source or opt in to an empty case with `-AllowNullOrEmptyForEach` on the specific block. ```powershell It 'Should return for ' -TestCases @( @@ -100,10 +126,12 @@ It 'Returns for ' -ForEach @( It 'Contains <_>' -ForEach 'item1', 'item2' { Get-Collection | Should -Contain $_ } ``` +When a test name contains `<...>`, Pester v6 evaluates the token as a PowerShell expression. Backtick-escape the opening `<` when the text should remain literal. + ## Tags - **Available on**: `Describe`, `Context`, and `It` blocks -- **Filtering**: Use `-TagFilter` and `-ExcludeTagFilter` with `Invoke-Pester` +- **Filtering**: Use `-Tag` and `-ExcludeTag` with `Invoke-Pester`, or set `Filter.Tag` and `Filter.ExcludeTag` in `New-PesterConfiguration` - **Wildcards**: Tags support `-like` wildcards for flexible filtering ```powershell @@ -113,14 +141,14 @@ Describe 'Function' -Tag 'Unit' { } # Run only fast unit tests -Invoke-Pester -TagFilter 'Unit' -ExcludeTagFilter 'Slow' +Invoke-Pester -Tag 'Unit' -ExcludeTag 'Slow' ``` ## Skip - **`-Skip`**: Available on `Describe`, `Context`, and `It` to skip tests - **Conditional**: Use `-Skip:$condition` for dynamic skipping -- **Runtime Skip**: Use `Set-ItResult -Skipped` during test execution (setup/teardown still run) +- **Runtime Skip**: Use `Set-ItResult -Skipped` or `Set-ItResult -Inconclusive` during test execution (setup/teardown still run) - **Ends the test body**: `Set-ItResult -Skipped`/`-Inconclusive` throws internally to end the `It` block, so code after it does not run; a trailing `return` is unreachable and should not be added ```powershell @@ -133,6 +161,7 @@ Context 'Integration tests' -Skip { } - **Continue on Failure**: Use `Should.ErrorAction = 'Continue'` to collect multiple failures - **Stop on Critical**: Use `-ErrorAction Stop` for pre-conditions - **Test Exceptions**: Use `{ Code } | Should -Throw` for exception testing +- **Pending tests**: `Set-ItResult -Pending` was removed; use `-Inconclusive`, `-Skipped`, or `It -Skip` ## Best Practices @@ -185,7 +214,7 @@ Describe 'Get-UserInfo' { Configuration is defined **outside** test files when calling `Invoke-Pester` to control execution behavior. ```powershell -# Create configuration (Pester 5.2+) +# Create configuration (Pester v6) $config = New-PesterConfiguration $config.Run.Path = './Tests' $config.Output.Verbosity = 'Detailed'