awesome-copilot/instructions/powershell-pester-5.instructions_ja.md

8.3 KiB
Raw Blame History

applyTo description
**/*.Tests.ps1 Pester v5規約に基づくPowerShell Pesterテストのベストプラクティス

PowerShell Pester v5 テストガイドライン

このガイドは、PowerShell Pester v5 モジュールを使用して自動化されたテストを作成するための PowerShell 固有の指示を提供します。一般的な PowerShell スクリプト作成のベストプラクティスについては、powershell.instructions.mdの PowerShell コマンドレット開発ガイドラインに従ってください。

ファイル命名と構造

  • ファイル規約: *.Tests.ps1命名パターンを使用
  • 配置: テスト対象のコードの隣または専用テストディレクトリにテストファイルを配置
  • インポートパターン: BeforeAll { . $PSScriptRoot/FunctionName.ps1 }を使用してテスト対象の関数をインポート
  • 直接コードなし: すべてのコードを Pester ブロック(BeforeAllDescribeContextItなど)内に配置

テスト構造の階層

BeforeAll { # テスト対象の関数をインポート }
Describe 'FunctionName' {
    Context 'When condition' {
        BeforeAll { # コンテキストのセットアップ }
        It 'Should behavior' { # 個別のテスト }
        AfterAll { # コンテキストのクリーンアップ }
    }
}

コアキーワード

  • Describe: トップレベルのグループ化、通常はテスト対象の関数名
  • Context: 特定のシナリオのための Describe 内のサブグループ
  • It: 個別のテストケース、説明的な名前を使用
  • Should: テスト検証のためのアサーションキーワード
  • BeforeAll/AfterAll: ブロックごとに一度だけセットアップ/ティアダウン
  • BeforeEach/AfterEach: 各テストの前後でセットアップ/ティアダウン

セットアップとティアダウン

  • BeforeAll: 含まれるブロックの開始時に一度実行、高コストな操作に使用
  • BeforeEach: ブロック内のすべてのItの前に実行、テスト固有のセットアップに使用
  • AfterEach: すべてのItの後に実行、テストが失敗しても保証される
  • AfterAll: ブロックの終了時に一度実行、クリーンアップに使用
  • 変数スコープ: BeforeAll変数は子ブロックで利用可能(読み取り専用)、BeforeEach/It/AfterEachは同じスコープを共有

アサーションShould

  • 基本比較: -Be, -BeExactly, -Not -Be
  • コレクション: -Contain, -BeIn, -HaveCount
  • 数値: -BeGreaterThan, -BeLessThan, -BeGreaterOrEqual
  • 文字列: -Match, -Like, -BeNullOrEmpty
  • : -BeOfType, -BeTrue, -BeFalse
  • ファイル: -Exist, -FileContentMatch
  • 例外: -Throw, -Not -Throw

モッキング

  • Mock CommandName { ScriptBlock }: コマンドの動作を置き換える
  • -ParameterFilter: パラメータが条件に一致する場合のみモック
  • -Verifiable: 検証が必要なモックとしてマーク
  • Should -Invoke: モックが特定の回数呼び出されたことを検証
  • Should -InvokeVerifiable: すべての検証可能なモックが呼び出されたことを検証
  • スコープ: モックはデフォルトで含まれるブロックスコープ
Mock Get-Service { @{ Status = 'Running' } } -ParameterFilter { $Name -eq 'TestService' }
Should -Invoke Get-Service -Exactly 1 -ParameterFilter { $Name -eq 'TestService' }

テストケース(データ駆動テスト)

パラメータ化されたテストには-TestCasesまたは-ForEachを使用:

It 'Should return <Expected> for <Input>' -TestCases @(
    @{ Input = 'value1'; Expected = 'result1' }
    @{ Input = 'value2'; Expected = 'result2' }
) {
    Get-Function $Input | Should -Be $Expected
}

データ駆動テスト

  • -ForEach: データから複数のテストを生成するためDescribeContextItで利用可能
  • -TestCases: Itブロックでの-ForEachの別名(後方互換性)
  • ハッシュテーブルデータ: 各項目はテストで利用可能な変数を定義(例:@{ Name = 'value'; Expected = 'result' }
  • 配列データ: 現在の項目に$_変数を使用
  • テンプレート: 動的展開のためにテスト名で<変数名>を使用
# ハッシュテーブルアプローチ
It 'Returns <Expected> for <Name>' -ForEach @(
    @{ Name = 'test1'; Expected = 'result1' }
    @{ Name = 'test2'; Expected = 'result2' }
) { Get-Function $Name | Should -Be $Expected }

# 配列アプローチ
It 'Contains <_>' -ForEach 'item1', 'item2' { Get-Collection | Should -Contain $_ }

タグ

  • 利用可能: DescribeContextItブロック
  • フィルタリング: Invoke-Pester-TagFilter-ExcludeTagFilterを使用
  • ワイルドカード: タグは柔軟なフィルタリングのため-likeワイルドカードをサポート
Describe 'Function' -Tag 'Unit' {
    It 'Should work' -Tag 'Fast', 'Stable' { }
    It 'Should be slow' -Tag 'Slow', 'Integration' { }
}

# 高速なユニットテストのみ実行
Invoke-Pester -TagFilter 'Unit' -ExcludeTagFilter 'Slow'

スキップ

  • -Skip: テストをスキップするためにDescribeContextItで利用可能
  • 条件付き: 動的スキップには-Skip:$conditionを使用
  • ランタイムスキップ: テスト実行中にSet-ItResult -Skippedを使用(セットアップ/ティアダウンは実行される)
It 'Should work on Windows' -Skip:(-not $IsWindows) { }
Context 'Integration tests' -Skip { }

エラーハンドリング

  • 失敗時継続: 複数の失敗を収集するためにShould.ErrorAction = 'Continue'を使用
  • 重要な箇所で停止: 前提条件に-ErrorAction Stopを使用
  • 例外のテスト: 例外テストには{ Code } | Should -Throwを使用

ベストプラクティス

  • 説明的な名前: 動作を説明する明確なテスト説明を使用
  • AAA パターン: 準備Arrange、実行Act、検証Assert
  • 分離されたテスト: 各テストは独立している必要がある
  • 別名を避ける: 完全なコマンドレット名を使用(?ではなくWhere-Object
  • 単一責任: 可能な場合はテストあたり一つのアサーション
  • テストファイルの構成: 関連するテストを Context ブロックでグループ化。Context ブロックはネスト可能

テストパターンの例

BeforeAll {
    . $PSScriptRoot/Get-UserInfo.ps1
}

Describe 'Get-UserInfo' {
    Context 'When user exists' {
        BeforeAll {
            Mock Get-ADUser { @{ Name = 'TestUser'; Enabled = $true } }
        }

        It 'Should return user object' {
            $result = Get-UserInfo -Username 'TestUser'
            $result | Should -Not -BeNullOrEmpty
            $result.Name | Should -Be 'TestUser'
        }

        It 'Should call Get-ADUser once' {
            Get-UserInfo -Username 'TestUser'
            Should -Invoke Get-ADUser -Exactly 1
        }
    }

    Context 'When user does not exist' {
        BeforeAll {
            Mock Get-ADUser { throw "User not found" }
        }

        It 'Should throw exception' {
            { Get-UserInfo -Username 'NonExistent' } | Should -Throw "*not found*"
        }
    }
}

構成

構成は実行動作を制御するためにInvoke-Pesterを呼び出す際にテストファイル外で定義されます。

# 構成を作成Pester 5.2以降)
$config = New-PesterConfiguration
$config.Run.Path = './Tests'
$config.Output.Verbosity = 'Detailed'
$config.TestResult.Enabled = $true
$config.TestResult.OutputFormat = 'NUnitXml'
$config.Should.ErrorAction = 'Continue'
Invoke-Pester -Configuration $config

主要セクション: RunPath、Exit、FilterTag、ExcludeTag、OutputVerbosity、TestResultEnabled、OutputFormat、CodeCoverageEnabled、Path、ShouldErrorAction、Debug