Я пишу простой модуль модульного тестирования в PowerShell.
Я разработал модуль так, чтобы его функции assert принимали блок скрипта в качестве параметра, чтобы позволить программе выполнять код из функции assert и обрабатывать любые исключения. выбрасываются как сбой теста.
Если тесты не пройдены, я хочу вернуть строку в модульном тесте, в котором тест не пройден. Мой план состоял в том, чтобы сделать это путем использования трассировки стека (Get-PSCallStack) в начале каждого метода assert и использовать информацию для второго стекового фрейма, который, как я полагаю, должен соответствовать строке, где была вызвана функция assert.
На практике я обнаружил, что информация, которую вернул PowerShell, кажется неверной. Второй стековый фрейм относится к правильному файлу, как и ожидалось, но всегда дает номер строки, с которой я вызвал Get-PSCallStack в методе assert.
Это не функция утверждения , которую вы используете, это блок сценария утверждения , используемый как «функция-член». Но это все еще блок сценария.
Согласно этой сообщенной проблеме: https://connect.microsoft.com/PowerShell/feedback/details/531086/в зависимости от того, как вы вызываете скрипт, блокирует детали вызова, может не быть доступным -from-inside-the-script-block#
что-то не так с вызовом Get-PSCallStack
из блоков скриптов. Итак, ответ на ваш вопрос, вероятно, таков: да, это проблема PowerShell.
Я бы порекомендовал вам использовать функции. Я переработал ваши скрипты для использования функций (грязная версия, плохие имена и т. д.), и они работают, как и ожидалось:
#File 1 (Tester.ps1)
#Creates the tester object
function AssertTrue {
param($expression);
$stackFrame = (Get-PSCallStack)[1]
try{
$result = . $expression;
if($result -eq $true){
LogPass
}else{
LogFailure ("Evaluation Failed expected ""$true"" got ""$false""") $stackFrame
}
}catch [Exception]{
LogFailure "Unexpected exception encountered" $stackFrame
}
}
function LogPass {
#Do nothing
}
function LogFailure {
param($message, $stackFrame);
"Failure Encounterd";
"Command: $($stackFrame.Command)"
"Location: $($stackFrame.Location)";
"Message: $message";
}
And
#File 2 (TestCase.ps1)
#Runs the tests using the tester object
. (Resolve-Path "Tester.ps1");
function TestFailure {
$expression = {$false};
AssertTrue $expression
}
TestFailure