0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

PowerShell(Pester 5.3)によるテストの雛形

Posted at

はじめに...

調査した内容を時系列にまとめた資料なので、その点ご了承ください。

目次

  1. 実行環境
  2. 実現したいこと
  3. 作業の流れ
  4. 例題
  5. (i) フォルダを作成する
  6. (ii) テスト対象のコードを準備する
  7. (iii) テストコードを作成する
  8. (iv) テスト実行コードを作成する
  9. (v) テスト
  10. まとめ
  11. 参考リンク

1. 実行環境

項目 情報
OS macOS 11.6
HW MacBook Air (11-inch, Mid 2013)
pwsh 7.2.0
pester 5.3.3
MDM環境 microsoft intune

2. 実現したいこと

  • powershell でユニットテストを実施したい

3. 作業の流れ

以下の流れを元に例題を定めて実践する

i. フォルダ構成を検討する
ii. テスト対象のコードを準備する

  • テスト項目毎にfunctionを分けてコードを作る
    iii. テストコードを作成する
    iv. テスト実行コードを作成する
    v. テスト

4. 例題

割り算を行うfunctionのテストを行う

5. (i) フォルダを作成する

今回はテストを実行するにあたり、テスト対象のスクリプトとテストコードを分離して管理する。
分離するためにフォルダは以下の4つで構成した。
また、命名規則を定めることで分離した際の負荷を軽減する。

# フォルダ名 ファイル名 役割
1 src <コード名>.ps1 テスト対象コード
2 test-src <コード名>.ps1 テストコード
3 test-exec <コード名>.Test-Exec.ps1 テスト実行コード
4 test-result <コード名>.Test-Exec.ps1 テスト結果(4の結果出力される)
テスト対象コード-Division.ps1
  • 今回の構成
# フォルダ名 ファイル名 役割
1 src Division.ps1 テスト対象コード
2 test-src Division.test.ps1 テストコード
3 test-exec Division.test-exec.ps1 テスト実行コード
4 test-result Division.test-result.xml テスト結果(4の結果出力される)

6. (ii) テスト対象のコードを準備する

テスト対象のコードは以下の通り、定数1000を引数で割る関数。

Division.ps1
function SampleFunction001{
    param([int]$i)
        1000/$i
}

7. (iii) テストコードを作成する

テストコードの構成は以下の通り、Itが実際のテスト内容を記述する箇所となる。
テスト内容を分類するためにDescribe(説明) > Context(環境)という順序で分類する。

## ContextをまとめるDescribe
Describe "<Describeの説明>" {
    ## 全てのContextが実行される前に1回だけ実行されるBeforeAll
    BeforeAll {
    }

    ## テスト(It)をまとめる Context
    Context "<Contextの説明>"{
        # 実際のテスト内容(It)
        It "<Itの説明>"{
            # 実際のテスト内容
    
        It "<Itの説明>"{
            # 実際のテスト内容
        }
    }

    ## 全てのContextが実行された後1回だけ実行されるBeforeAll
    AfterAll {
    }
}
テストコード-Division.Test.ps1
```console Describe "Function-001" { BeforeAll { # テスト開始時の処理を記載する # テスト対象のコードをロードする # $PSCommandPathを用いてテスト対象コードの名前を指定 Write-Verbose "BeforeAll"; $BasePath = Join-Path $(Split-Path $(Split-Path $PSCommandPath -Parent) -Parent) "src"; $TargetCode = Join-Path "${BasePath}" $(Split-Path -Leaf $PSCommandPath).Replace(".Test",""); . $TargetCode; Write-Verbose "LoadFunction ${TargetCode}"
}

# 正常系のテスト
Context "正常系"{
    # 1000 を 100で割ったら10
    It "[SampleFunction001]-N--[001]" {
        SampleFunction001 -i 100| Should -Be 10
    }

    # 1000 を 200で割ったら5
    It "[SampleFunction001]-N--[002]" {
        SampleFunction001 -i 200| Should -Be 5
    }

}

# 異常系のテスト
Context "異常"{
    It "[SampleFunction001]-AN-[001]" {
        # 1000 を 0で割ったら Throw ※{}で囲む
        {SampleFunction001 -i 0}| Should -Throw
    }

    It "[SampleFunction001]-AN-[002]" {
        # 引数の指定が無かったら Throw
        {SampleFunction001 }| Should -Throw
    }
}

AfterAll{
    # テスト終了時の処理を記載する
    Write-Verbose "AfterAll";
}

}

</div>
</detials>

### 8.  (iv) テスト実行コードを作成する

テスト実行コードの構成は以下の通り。
実際には、Invoke-Pesterコマンドだけで実行可能だが、今回はテストコードのファイル名を$PSCommandPathを元に生成したり、実行時の出力内容を指定しているため、長めとなっている。

<details><summary>テスト実行コード-Division.Test-Exec.ps1</summary><div>
```console
$BasePath = $(Split-Path $(Split-Path $PSCommandPath  -Parent) -Parent)

# $PSCommandPathを用いてテストコードのファイル名を指定
$TargetCode = Join-Path "${BasePath}" "test-src" $(Split-Path -Leaf $PSCommandPath).Replace("-Exec","");
# $PSCommandPathを用いてテスト結果(xml)のファイル名を指定
$Result = Join-Path "${BasePath}" "test-result" $(Split-Path -Leaf $PSCommandPath).Replace("-Result","").Replace(".ps1",".xml");

# 詳細ログを出力する場合には、Continueを指定 
$VerbosePreference = "SilentlyContinue"

# Pesterの設定値を指定
$PesterPreference = [PesterConfiguration]::Default
$PesterPreference.Output.Verbosity = 'Detailed'

# Invoke-Pesterでテストコードを実行した上で、実行結果をJUnit形式に変換し、ファイル出力
Invoke-Pester $TargetCode -PassThru | ConvertTo-JUnitReport -AsString |Out-File $Result

9. (v) テスト

テストは、Division.Test-Exec.ps1 を実行する。
実行結果は、コンソール出力と同時にtest-resultフォルダにxmlで出力される

テスト実行結果(Console)

Pester v5.3.3

Starting discovery in 1 files.
Discovery found 4 tests in 19ms.
Running tests.

Running tests from '/Users/<username>/Documents/powershell/pester/test-src/Division.Test.ps1'
Describing Function-001
 Context 正常系
   [+] [SampleFunction001]-N--[001] 16ms (5ms|11ms)
   [+] [SampleFunction001]-N--[002] 18ms (9ms|9ms)
 Context 異常
   [+] [SampleFunction001]-AN-[001] 26ms (24ms|2ms)
   [+] [SampleFunction001]-AN-[002] 42ms (22ms|20ms)
Tests completed in 228ms
Tests Passed: 4, Failed: 0, Skipped: 0 NotRun: 0
テスト実行結果-Division.Test-Exec.xml
<?xml version="1.0" encoding="utf-16" standalone="no"?>
<testsuites xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="junit_schema_4.xsd" name="Pester" tests="4" errors="0" failures="0" disabled="0" time="0.228">
  <testsuite name="/Users/<username>/Documents/powershell/pester/test-src/Division.Test.ps1" tests="4" errors="0" failures="0" hostname="<machie-name>" id="0" skipped="0" disabled="0" package="/Users/<username>/Documents/powershell/pester/test-src/Division.Test.ps1" time="0.228">
    <properties>
      <property name="machine-name" value="<machie-name>" />
      <property name="user" value="tatt" />
      <property name="user-domain" value="" />
      <property name="cwd" value="/Users/<username>/Documents/powershell/pester/test-exec" />
      <property name="os-version" value="20.6.0" />
      <property name="junit-version" value="4" />
      <property name="platform" value="Darwin" />
      <property name="clr-version" value="Unknown" />
    </properties>
    <testcase name="Function-001.正常系.[SampleFunction001]-N--[001]" status="Passed" classname="/Users/<username>/Documents/powershell/pester/test-src/Division.Test.ps1" assertions="0" time="0.020" />
    <testcase name="Function-001.正常系.[SampleFunction001]-N--[002]" status="Passed" classname="/Users/<username>/Documents/powershell/pester/test-src/Division.Test.ps1" assertions="0" time="0.021" />
    <testcase name="Function-001.異常.[SampleFunction001]-AN-[001]" status="Passed" classname="/Users/<username>/Documents/powershell/pester/test-src/Division.Test.ps1" assertions="0" time="0.032" />
    <testcase name="Function-001.異常.[SampleFunction001]-AN-[002]" status="Passed" classname="/Users/<username>/Documents/powershell/pester/test-src/Division.Test.ps1" assertions="0" time="0.063" />
  </testsuite>
</testsuites>

10. まとめ

  • pesterを使ってテストコードの作成からテスト実行までの流れを記載できた
  • 今後、Describe内で利用できる関数やShouldで指定できる内容を記載したい

11. 参考リンク

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?