Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/README.skills.md
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ See [CONTRIBUTING.md](../CONTRIBUTING.md#adding-skills) for guidelines on how to
| [pdftk-server](../skills/pdftk-server/SKILL.md)<br />`gh skills install github/awesome-copilot pdftk-server` | Skill for using the command-line tool pdftk (PDFtk Server) for working with PDF files. Use when asked to merge PDFs, split PDFs, rotate pages, encrypt or decrypt PDFs, fill PDF forms, apply watermarks, stamp overlays, extract metadata, burst documents into pages, repair corrupted PDFs, attach or extract files, or perform any PDF manipulation from the command line. | `references/download.md`<br />`references/pdftk-cli-examples.md`<br />`references/pdftk-man-page.md`<br />`references/pdftk-server-license.md`<br />`references/third-party-materials.md` |
| [penpot-uiux-design](../skills/penpot-uiux-design/SKILL.md)<br />`gh skills install github/awesome-copilot penpot-uiux-design` | Comprehensive guide for creating professional UI/UX designs in Penpot using MCP tools. Use this skill when: (1) Creating new UI/UX designs for web, mobile, or desktop applications, (2) Building design systems with components and tokens, (3) Designing dashboards, forms, navigation, or landing pages, (4) Applying accessibility standards and best practices, (5) Following platform guidelines (iOS, Android, Material Design), (6) Reviewing or improving existing Penpot designs for usability. Triggers: "design a UI", "create interface", "build layout", "design dashboard", "create form", "design landing page", "make it accessible", "design system", "component library". | `references/accessibility.md`<br />`references/component-patterns.md`<br />`references/platform-guidelines.md`<br />`references/setup-troubleshooting.md` |
| [performance-review-writer](../skills/performance-review-writer/SKILL.md)<br />`gh skills install github/awesome-copilot performance-review-writer` | Draft performance reviews, self-assessments, peer reviews, and upward feedback in your own voice. Analyzes your contributions, emails, and meeting history via WorkIQ, then produces honest, impact-focused drafts using the STAR format. USE FOR: write my performance review, draft self-assessment, peer review, 360 feedback, annual review, mid-year review, upward feedback, write review for colleague, performance appraisal. | None |
| [pester-migration](../skills/pester-migration/SKILL.md)<br />`gh skills install github/awesome-copilot pester-migration` | Experimental (preview) Pester migration skill for upgrading PowerShell Pester test suites across major versions — v3→v4, v4→v5, and v5→v6. The v5→v6 path tracks Pester 6, which is still a release candidate, so that guidance may change. Covers the Discovery/Run two-phase model, moving setup into BeforeAll, $PSScriptRoot vs $MyInvocation, mock changes (Assert-MockCalled → Should -Invoke, removed fall-through), Invoke-Pester parameters → PesterConfiguration, data-driven -ForEach/-TestCases, and the v6 breaking changes. Use when the user asks to upgrade, migrate, or modernize Pester tests, fix *.Tests.ps1 files that broke after bumping the Pester version, or convert legacy Should / Invoke-Pester syntax. | `references/v3-to-v4.md`<br />`references/v4-to-v5.md`<br />`references/v5-to-v6.md` |
| [phoenix-cli](../skills/phoenix-cli/SKILL.md)<br />`gh skills install github/awesome-copilot phoenix-cli` | Debug LLM applications using the Phoenix CLI. Fetch traces, analyze errors, structure trace review with open coding and axial coding, inspect datasets, review experiments, query annotation configs, and use the GraphQL API. Use whenever the user is analyzing traces or spans, investigating LLM/agent failures, deciding what to do after instrumenting an app, building failure taxonomies, choosing what evals to write, or asking "what's going wrong", "what kinds of mistakes", or "where do I focus" — even without naming a technique. | `references/axial-coding.md`<br />`references/open-coding.md` |
| [phoenix-evals](../skills/phoenix-evals/SKILL.md)<br />`gh skills install github/awesome-copilot phoenix-evals` | Build and run evaluators for AI/LLM applications using Phoenix. | `references/axial-coding.md`<br />`references/common-mistakes-python.md`<br />`references/error-analysis-multi-turn.md`<br />`references/error-analysis.md`<br />`references/evaluate-dataframe-python.md`<br />`references/evaluators-code-python.md`<br />`references/evaluators-code-typescript.md`<br />`references/evaluators-custom-templates.md`<br />`references/evaluators-llm-python.md`<br />`references/evaluators-llm-typescript.md`<br />`references/evaluators-overview.md`<br />`references/evaluators-pre-built.md`<br />`references/evaluators-rag.md`<br />`references/experiments-datasets-python.md`<br />`references/experiments-datasets-typescript.md`<br />`references/experiments-overview.md`<br />`references/experiments-running-python.md`<br />`references/experiments-running-typescript.md`<br />`references/experiments-synthetic-python.md`<br />`references/experiments-synthetic-typescript.md`<br />`references/fundamentals-anti-patterns.md`<br />`references/fundamentals-model-selection.md`<br />`references/fundamentals.md`<br />`references/observe-sampling-python.md`<br />`references/observe-sampling-typescript.md`<br />`references/observe-tracing-setup.md`<br />`references/production-continuous.md`<br />`references/production-guardrails.md`<br />`references/production-overview.md`<br />`references/setup-python.md`<br />`references/setup-typescript.md`<br />`references/validation-evaluators-python.md`<br />`references/validation-evaluators-typescript.md`<br />`references/validation.md` |
| [phoenix-tracing](../skills/phoenix-tracing/SKILL.md)<br />`gh skills install github/awesome-copilot phoenix-tracing` | OpenInference semantic conventions and instrumentation for Phoenix AI observability. Use when implementing LLM tracing, creating custom spans, or deploying to production. | `README.md`<br />`references/annotations-overview.md`<br />`references/annotations-python.md`<br />`references/annotations-typescript.md`<br />`references/fundamentals-flattening.md`<br />`references/fundamentals-overview.md`<br />`references/fundamentals-required-attributes.md`<br />`references/fundamentals-universal-attributes.md`<br />`references/instrumentation-auto-python.md`<br />`references/instrumentation-auto-typescript.md`<br />`references/instrumentation-manual-python.md`<br />`references/instrumentation-manual-typescript.md`<br />`references/metadata-python.md`<br />`references/metadata-typescript.md`<br />`references/production-python.md`<br />`references/production-typescript.md`<br />`references/projects-python.md`<br />`references/projects-typescript.md`<br />`references/sessions-python.md`<br />`references/sessions-typescript.md`<br />`references/setup-python.md`<br />`references/setup-typescript.md`<br />`references/span-agent.md`<br />`references/span-chain.md`<br />`references/span-embedding.md`<br />`references/span-evaluator.md`<br />`references/span-guardrail.md`<br />`references/span-llm.md`<br />`references/span-reranker.md`<br />`references/span-retriever.md`<br />`references/span-tool.md` |
Expand Down
153 changes: 153 additions & 0 deletions skills/pester-migration/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
---
name: pester-migration
description: 'Experimental (preview) Pester migration skill for upgrading PowerShell Pester test suites across major versions — v3→v4, v4→v5, and v5→v6. The v5→v6 path tracks Pester 6, which is still a release candidate, so that guidance may change. Covers the Discovery/Run two-phase model, moving setup into BeforeAll, $PSScriptRoot vs $MyInvocation, mock changes (Assert-MockCalled → Should -Invoke, removed fall-through), Invoke-Pester parameters → PesterConfiguration, data-driven -ForEach/-TestCases, and the v6 breaking changes. Use when the user asks to upgrade, migrate, or modernize Pester tests, fix *.Tests.ps1 files that broke after bumping the Pester version, or convert legacy Should / Invoke-Pester syntax.'
---

# Pester Migration

> **Experimental / preview.** The **v5→v6** guidance tracks Pester 6 while it is a release
> candidate and may change; verify against the current
> [release notes](https://github.com/pester/Pester/releases). v3→v4 and v4→v5 cover stable releases.

Pester is the test framework for PowerShell. Test files end in `*.Tests.ps1` and use
`Describe` / `Context` / `It` blocks with `Should` assertions. This skill upgrades an existing
suite from one major Pester version to the next and gets it green again.

> **Mental model:** each major jump has a different character. **v3→v4** is mostly a syntax
> rename. **v4→v5** is a *fundamental runtime change* (the Discovery/Run split) and is the hard
> one. **v5→v6** is largely backwards-compatible — a handful of previously-deprecated things now
> throw. Migrate **one major at a time**; never skip a version.

Detailed, symptom-driven guides live in `references/` — load the one(s) for the jump you are doing.

## References

| Reference | When to load |
|---|---|
| [v3-to-v4.md](references/v3-to-v4.md) | `Should Be` → `Should -Be`, `Contain` → `FileContentMatch`, `Assert-VerifiableMocks` → `Assert-VerifiableMock`, array-assertion edge cases. |
| [v4-to-v5.md](references/v4-to-v5.md) | The big one. Discovery/Run phases, `BeforeAll` setup, `$PSScriptRoot`, `BeforeDiscovery`, `-ForEach`, mock scoping, `Should -Throw` wildcards, `Invoke-Pester` → `New-PesterConfiguration`. |
| [v5-to-v6.md](references/v5-to-v6.md) | PowerShell 5.1/7.4+ only, per-file discovery+run, empty `-ForEach` throws, duplicate setup blocks throw, name `<...>` templates evaluate, `Assert-MockCalled` removed, mocks no longer fall through, code-coverage tracer, legacy `Invoke-Pester` params removed. |

Canonical source: the official migration guides at https://pester.dev/docs/migrations/ — this skill
mirrors them. When in doubt, prefer the website.

## Step 0 — Detect where you are and where you're going

Find the installed version(s) and the version the **tests** were written for. These can differ.

```powershell
# Installed Pester version(s) on this machine
Get-Module Pester -ListAvailable | Select-Object Name, Version, Path

# Version currently imported in the session
(Get-Module Pester).Version
```

Tell the source version from the **test code** with these heuristics:

| You see in `*.Tests.ps1` / build scripts | Suite was written for |
|---|---|
| `Should Be` / `Should Contain` (no dash) | v3 or earlier → start at [v3-to-v4](references/v3-to-v4.md) |
| `$MyInvocation.MyCommand.Path` + dot-source at the **top** of the file; arbitrary code directly under `Describe` | v4 → [v4-to-v5](references/v4-to-v5.md) |
| `Assert-MockCalled`, `Assert-VerifiableMock`, `Set-ItResult -Pending` | v4 / early-v5 (these are **removed in v6**) |
| `Invoke-Pester -Script … -OutputFile … -CodeCoverage …` (legacy params) | v4 invocation → map to config |
| `BeforeAll { . $PSScriptRoot/… }`, `New-PesterConfiguration`, `Should -Invoke` | already v5-style → [v5-to-v6](references/v5-to-v6.md) |

Install the target version when ready:

```powershell
# Latest stable v5 — pin the major so this keeps installing v5 even after v6 goes GA
Install-Module Pester -MaximumVersion 5.99.99 -Force

# Pester 6 (currently a release candidate — needs -AllowPrerelease)
Install-Module Pester -AllowPrerelease -Force
```

> On **Windows PowerShell 5.1** the OS ships a Microsoft-signed built-in Pester 3 that PowerShellGet
> won't overwrite with the differently-signed newer Pester — add `-SkipPublisherCheck` there to
> install side-by-side. Not needed on PowerShell 7+. See
> https://pester.dev/docs/introduction/installation.

## Migration workflow

Run this loop for each major jump. **Do not jump two majors at once** — go v4→v5, then v5→v6.

1. **Baseline.** Run the suite on the **current** version first and record pass/fail. You need a
known-good (or known) starting point so you can tell migration regressions apart from
pre-existing failures.
```powershell
# Bare Invoke-Pester works on every major; exact parameters differ
# (v3/v4: -Script/-OutputFile; v5+/v6: -Path/-Output).
Invoke-Pester
```
2. **Read the reference** for this jump (table above) so you know the full scope before editing.
3. **Edit file by file.** Apply the mechanical changes (see per-jump cheat sheets below and in the
reference). Keep changes small and reviewable — one file or one concern at a time.
4. **Switch versions** with `Install-Module` (Step 0), then re-import: `Remove-Module Pester;
Import-Module Pester` (or start a fresh session).
5. **Run and fix.** Re-run with `-Output Detailed`; use `-Output Diagnostic` (v4→v5) or read the
explicit v6 error messages to locate problems. Match each failure to the **symptom → fix**
tables in the reference.
6. **Green, diff, commit.** Re-run until the result matches the baseline (or better). Review the
diff, then commit. Migrating in small commits makes regressions trivial to bisect.

## What actually changes (scope per jump)

| Jump | Difficulty | Nature |
|---|---|---|
| v3 → v4 | Low | Assertion-syntax rename (`Should -Be`). Largely script-automatable. |
| v4 → v5 | **High** | New two-phase runtime. Test **structure** changes: setup must move into `BeforeAll`, discovery-time code into `BeforeDiscovery`, file location via `$PSScriptRoot`. Not a pure find-replace. |
| v5 → v6 | Low–Medium | Backwards-compatible runtime; deprecated features now throw. Mostly small, targeted fixes. Your `Should -Be` assertions keep working unchanged. |

## Quick cheat sheets

### v4 → v5 (most common fixes)
```powershell
# 1. Move file import into BeforeAll, use $PSScriptRoot (NOT $MyInvocation.MyCommand.Path)
# BEFORE
$here = Split-Path -Parent $MyInvocation.MyCommand.Path
. "$here\Get-Thing.ps1"
# AFTER
BeforeAll { . $PSScriptRoot/Get-Thing.ps1 }

# 2. Any code that DISCOVERS/generates tests must be in BeforeDiscovery
BeforeDiscovery { $cases = Get-Content $PSScriptRoot/cases.json | ConvertFrom-Json }

# 3. Should -Throw matches with -like wildcards, not .Contains
{ throw 'a long message' } | Should -Throw '*long*'

# 4. Invoke-Pester legacy params → New-PesterConfiguration (see reference for full map)
```
Full details, scoping rules, and the parameter→config table: [references/v4-to-v5.md](references/v4-to-v5.md).

### v5 → v6 (most common fixes)
```powershell
# 1. Mock assertions: removed verbs — rename (old -> new):
# Assert-MockCalled -> Should -Invoke
# Assert-VerifiableMock -> Should -InvokeVerifiable
Should -Invoke Get-Thing -Times 1 -Exactly
Should -InvokeVerifiable

# 2. Add a default mock — unmatched calls no longer run the real command
Mock Get-Thing { 'default' }
Mock Get-Thing -ParameterFilter { $Name -eq 'a' } -MockWith { 'a' }

# 3. Empty/$null -ForEach now throws; allow it only where empty is expected
Describe 'Optional' -ForEach $cases -AllowNullOrEmptyForEach { }

# 4. Combine duplicate BeforeAll/BeforeEach/AfterAll/AfterEach in the same block into one
```
Full breaking-change list with symptoms and fixes: [references/v5-to-v6.md](references/v5-to-v6.md).

## Safety rules

- **Tests are the spec.** Migration must not change what a test asserts — only how the suite is
structured and invoked. If a test starts passing/failing differently for any reason other than a
documented breaking change, investigate before accepting it.
- **Automated migration scripts produce false positives.** The community scripts (linked in the
references) help with `Should` syntax and dot-sourcing, but always review the diff and re-run the
suite afterward. Never bulk-edit and commit unchecked.
- **Mind file encoding** when scripting replacements over `*.Tests.ps1` — preserve the original
encoding (UTF-8 vs ASCII) so you don't mangle non-ASCII test names.
- **Work on a branch, commit per file/concern.** Small commits keep `git bisect` useful if a
migrated test goes red later.
92 changes: 92 additions & 0 deletions skills/pester-migration/references/v3-to-v4.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# Migrating Pester v3 → v4

This is the smallest jump — mostly an assertion-syntax rename. Many suites need only minor changes,
some need none. It is largely script-automatable, but always review the diff and re-run the suite.

Official guide: https://pester.dev/docs/migrations/v3-to-v4

> Heads-up: if your goal is a modern Pester (5 or 6), v3→v4 is only the first step. Do it, get
> green, then continue with [v4-to-v5.md](v4-to-v5.md) and [v5-to-v6.md](v5-to-v6.md).

---

## Change 1 — Dashed `Should` assertion syntax

v4 introduced the parameter-style `Should` syntax. The bareword form still ran in v4 but is
**removed in v5**, so converting now saves a later migration.

```powershell
# v3 (bareword)
It 'checks something' { 10 | Should Be 10 }

# v4+ (dashed)
It 'checks something' { 10 | Should -Be 10 }
```

The rename applies to every operator: `Be`, `BeExactly`, `Match`, `Throw`, `BeNullOrEmpty`,
`Contain`, etc. → `-Be`, `-BeExactly`, `-Match`, `-Throw`, `-BeNullOrEmpty`, …

There is a well-known AST-based converter, `Update-PesterTest` (Chris Dent / Wojciech Sciesinski),
that inserts the dashes safely by parsing the file rather than regexing it:
https://gist.github.com/indented-automation/aeb14825e39dd8849beee44f681fbab3 — it's also reproduced
in the official v3→v4 guide. Review its output, especially for non-UTF-8/ASCII files, where it can
change encoding.

---

## Change 2 — `Contain` → `FileContentMatch`

The `Contain` assertion was renamed to `FileContentMatch` (it tests file **contents**, which the
old name made ambiguous against collection containment).

```powershell
# Should Contain -> Should -FileContentMatch
# Should Not Contain -> Should -Not -FileContentMatch
'app.config' | Should -FileContentMatch 'setting'
'app.config' | Should -Not -FileContentMatch 'secret'
```

A simple regex-based migration script from the official guide (verify results — it can produce
false positives):

```powershell
$content = Get-Content -Path $file -Encoding $encoding
$content = $content -replace 'Should\s+\-?Contain', 'Should -FileContentMatch'
$content = $content -replace 'Should\s+\-?Not\s*-?Contain', 'Should -Not -FileContentMatch'
$content = $content -replace 'Assert-VerifiableMocks', 'Assert-VerifiableMock'
$content | Set-Content -Path $file -Encoding $encoding
```

---

## Change 3 — `Assert-VerifiableMocks` → `Assert-VerifiableMock`

The cmdlet was renamed (dropped the trailing `s`). Rename all occurrences.

> In Pester 5 this is *deprecated* and in Pester 6 it is *removed* — when you continue past v4,
> switch to `Should -InvokeVerifiable`. See [v5-to-v6.md](v5-to-v6.md).

---

## Change 4 — Array assertions (watch for edge cases)

`Should` gained array assertions in v4. This is transparent for most tests, but there are edge
cases where an array test that passed under v3 fails under v4. If an array-related test changes
result after the rename, inspect it manually rather than forcing it to pass. Background:
https://github.com/pester/Pester/issues/873.

Mocking also shifted subtly when Pester moved from functions to aliases; there are no required
changes, but if mocked-command behavior looks off, see
https://github.com/pester/Pester/issues/810 and https://github.com/pester/Pester/issues/812.

---

## v3 → v4 checklist

- [ ] Suite runs on v3 first (baseline).
- [ ] All `Should <Operator>` converted to `Should -<Operator>` (prefer the AST converter).
- [ ] `Should Contain` → `Should -FileContentMatch` (and the `-Not` form).
- [ ] `Assert-VerifiableMocks` → `Assert-VerifiableMock`.
- [ ] Array-assertion behavior changes reviewed manually.
- [ ] File encoding preserved by any scripted replacement.
- [ ] Suite green on v4; diff reviewed; committed.
Loading
Loading