PowerShell Pester テストを使用してインフラストラクチャの変更を検証

PowerShell Pester テストを使用してインフラストラクチャの変更を検証

投稿者: Adam Bertram
投稿日: 2019年4月19 0 Comments

インフラストラクチャのどこかに変更があった場合、何かが改善されることも、逆に問題が生ずることもあります。変更管理は、ITインフラストラクチャ管理の中でも重要な要素です。変更を加えた場合、加えた変更が本当に正しかったか自信がありますか?行った変更が、意図せずに他の何かに悪影響を与えてしまうことがないことを確認していますか?

部門内の誰かが同時に変更を加えている可能性もあり、そうするとコンフリクトが発生します。変更後の状態が意図した通りになっていることをどう確認するのがいいでしょうか?1つの方法は、PowerShell のテストフレームワーク、Pester を使用することです。

Pester はもともと PowerShell スクリプトの単体テストを構築するために設計されたものですが、PowerShell で構築されたため、多くのシステム管理者が、ルーチンのチェックとして、大規模自動化スクリプトの一部として、そして、ソフトウェア開発に必要な環境に加えられた変更が意図した通りであるかを確認するために、といった様々な状況で統合テストまたはインフラストラクチャ・テストを実行できるよう調整を加えました。

インフラストラクチャ・テスト

インフラストラクチャ・テストとは、現在の状態と、想定している状態とを、比較してテストするために作成されたあらゆる種類のコードの総称です。たとえば、次のようなことをテストします。

  • サーバーに正しいソフトウェアがインストールされているか?
  • PowerShell スクリプトを実行すると、正しいユーザーアカウントが作成されるか?
  • ファイルサーバーは意図したフォルダー階層を持っているか?

インフラストラクチャ・テストは、Pester では、基本的に Pester PowerShell モジュールによって実行される PowerShell コードですが、想定している状態を記述し、状態をチェックして結果を比較するのに必要なコードを持った、ドメイン固有言語(domain-specific language、DSL)として知られる特定の方法で構築されています。

Pester テスト

Pester テストは主要コンポーネント、describe ブロックと it ブロックに分かれます。このブログは Pester の使い方を説明することを目的にはしていませんので、必要なら筆者の著書など、他のリソースをご参照ください。

では、Pester を使って簡単なインフラストラクチャ・テストを作成しましょう。

まず、何をテストするのかを明確にする必要があります。PowerShell で状態を確認できるものなら何でもよくて、実にたくさんのことが可能です。ここでは、最も単純な例として、Windows サービスを起動するだけの PowerShell スクリプトを考えます。その PowerShell スクリプトの実行が完了したときに想定することは、Windows サービスが起動状態にあることです。下は、リモートサーバー SRV1 からサービスを開始する PowerShell スクリプトの例です。

ご覧のとおり、スクリプトは極めて単純です。単一のアイテム、wuauserv Windows サーバー、の状態を、停止状態から起動状態に変更するだけです。これを StartSRV1Service.ps1 というスクリプトとして保存します。

Get-Service -ComputerName SRV1 -Name wuauserv | Start-Service

この単純なスクリプトの結果を Pester でテストすることにします。それにはまず、スクリプトを実行する前に、環境に関して、可能性があるすべての状態を定義する必要があります。この例では、wuauserv サービスは停止状態であることも起動状態であることもあり得ます。まずサービスが停止状態であるとしましょう。そして、describe ブロックと、サービスの状態をチェックするコードを含む it ブロックを使用して、簡単な Pester テストを作成します。完了したら、それが想定される状態にあることを確認するためにチェックを実行します。

describe 'The wuauserv service on SRV1' {

    $serverName = 'SRV1'

    context 'When the service is in a stopped state' {

        BeforeAll {
            ## Force the service to stop
            Get-Service -ComputerName $serverName -Name wuauserv | Stop-Service
        }

        ## Execute the script that makes the change
        & 'C:\StartSRV1Service.ps1'

        ## Check the state of the service after the script is done
        $serviceState = Get-Service -ComputerName $serverName -Name wuauserv

        it 'the wuauserv service should be started' {
            $serviceState.Status | should -Be 'Running'
        }
    }
}

実行したときにスクリプトがうまく機能しなかった場合は、エラーメッセージが表示されます。

Describing The wuauserv service on SRV1

  Context When the service is in a stopped state
    [-] the wuauserv service should be started 8ms
      Expected 'Running', but got Stopped.
      19:             $serviceState.Status | should -Be 'Running'

そこで、イニシャル状態のとき起動状態である場合の context ブロックを追加し、スクリプトが何らかの理由で不適切に停止しないようにすることができます。

describe 'The wuauserv service on SRV1' {

    $serverName = 'SRV1'

    context 'When the service is in a stopped state' {

        BeforeAll {
            ## Force the service to stop
            Get-Service -ComputerName $serverName -Name wuauserv | Stop-Service
        }

        ## Execute the script that makes the change
        & 'C:\StartSRV1Service.ps1'

        $serviceState = Get-Service -ComputerName $serverName -Name wuauserv

        it 'the wuauserv service should be started' {
            $serviceState.Status | should -Be 'Running'
        }
    }

    context 'When the service is in a started state' {

        BeforeAll {
            ## Force the service to start
            Get-Service -ComputerName $serverName -Name wuauserv | Start-Service
        }

        ## Execute the script that makes the change
        & 'C:\StartSRV1Service.ps1'

        $serviceState = Get-Service -ComputerName $serverName -Name wuauserv

        it 'the wuauserv service should be started' {
            $serviceState.Status | should -Be 'Running'
        }
    }
}

Describing The wuauserv service on SRV1

  Context When the service is in a stopped state
    [-] the wuauserv service should be started 11ms
      Expected 'Running', but got Stopped.
      18:             $serviceState.Status | should -Be 'Running'

  Context When the service is in a started state
    [+] the wuauserv service should be started 10ms

スクリプトはほとんど何もしていないことがわかると思います。サービスが停止状態であれば、スクリプトを実行してからテストしても何も変わりません(スクリプトで停止状態から起動状態に変更)。事前に、意図的にサービスを起動状態にしておいて、スクリプトを実行してテストすると、サービスはやはり起動状態になっています。スクリプトは何も変更しませんでした。

Pester テストは、ほとんど無限の数の状況に拡張することができ、考え得る限りのすべての状態変化についてテストすることができます。事前に何をテストするのかよく検討し、テストに必要なコードを捻出したら、実行する Pester テストを構築して、想定した状態と結果の状態を比較します。

Adam Bertram

Adam Bertram is a 20-year veteran of IT. He’s currently an automation engineer, blogger, independent consultant, freelance writer, author, and trainer. Adam focuses on DevOps, system management, and automation technologies as well as various cloud platforms. He is a Microsoft Cloud and Datacenter Management MVP and efficiency nerd that enjoys teaching others a better way to leverage automation.

コメント

Comments are disabled in preview mode.
トピック

Sitefinityトレーニングと認定を開始

クラス最高のSitefinityの機能を使って、魅力的なデジタル体験を提供する方法をエキスパートがお教えします。

さらに詳しく

より優れた業務アプリケーションやウェブサイトの開発に役立つ、ニュース、情報、チュートリアルをご案内します。

The specified form no longer exists or is currently unpublished.