私はpowershellで簡単なユニットテストハーネスを書いています
アサート関数がパラメーターとしてスクリプト ブロックを受け取り、ハーネスがアサート関数内からコードを実行し、スローされた例外をテストの失敗として処理できるように、ハーネスを設計しました。
テストが失敗した場合、テストが失敗した単体テストで行を返したいと思います。私の計画では、各アサート メソッドの開始時にスタック トレース (Get-PSCallStack) を取得し、アサート関数が呼び出された行に対応すると思われる 2 番目のスタック フレームの情報を使用してこれを行うことでした。
実際には、powershell が返した情報が間違っているように見えることがわかりました。2 番目のスタック フレームは、予想どおり正しいファイルを参照していますが、アサート メソッドで Get-PSCallStack を呼び出した行番号を常に示しています。この数は、指定されたファイルの行数よりも多い場合があります (つまり、場所は "ScriptFile.ps1 line 88" と指定されていますが、ファイルには 20 行しかありません)。
PowerShell のスタック トレースに問題がありますか、それともここで理解できないことがありますか?
編集
要求に応じて、同じ結果を生成する例を投稿しています
Tester.ps1
#File 1 (Tester.ps1)
#Creates the tester object
$tester = (New-Object PSObject);
$tester | Add-Member -MemberType ScriptMethod -Name AssertTrue -Value {
param($expression);
$stackFrame = (GEt-PSCallStack)[1];
try{
$result = &$expression;
if($result -eq $true){
$this.LogPass();
}else{
$this.LogFailure("Evaluation Failed expected ""$true"" got ""$false""", $stackFrame);
}
}catch [Exception]{
$this.LogFailure("Unexpected exception encountered", $stackFrame);
}
}
$tester | Add-Member -MemberType ScriptMethod -Name LogPass -Value {
#Do nothing
};
$tester | Add-Member -MemberType ScriptMethod -Name LogFailure -Value {
param($message, $stackFrame);
"Failure Encounterd";
"Command: $($stackFrame.Command)"
"Location: $($stackFrame.Location)";
"Message: $message";
}
return $tester;
TestCase.ps1
#File 2 (TestCase.ps1)
#Runs the tests using the tester object
$tester = &(Resolve-Path "Tester.ps1");
function TestFailure($tester){
$expression = {$false};
$tester.AssertTrue($expression);
}
TestFailure($tester);
Assert は TestCase.ps1 の 7 行目で呼び出され、コール スタックは Tester.ps1 の 9 行目でキャプチャされます。
これは印刷します
Failure Encounterd
Command: TestFailure
Location: Tester.ps1: Line 9
Message: Evaluation Failed expected "True" got "False"
コマンドは正しいが、ファイルと行の両方が間違っている
スタック トレースの次のフレームは、TestFailure() が呼び出された場所を正しく記述しており、その場所は "TestCase.ps1: Line 11" です。