我在powershell中编写一个简单的单元测试工具
我设计了线束,使其断言函数将脚本块作为参数,以允许线束从断言函数中运行代码,并将任何异常视为测试失败。
如果测试失败,我想在测试失败的单元测试中返回行。我的计划是通过在每个断言方法的开头采用堆栈跟踪(Get-PSCallStack)并使用第二个堆栈帧的信息来做到这一点,我假设它应该对应于调用断言函数的行。
在实践中,我发现powershell发回的信息似乎是错误的。第二个堆栈帧指的是正确的文件,但总是给出我在断言方法中调用Get-PSCallStack的行号。有时这个数字可能甚至高于给定文件中的行数(即,Location是“ScriptFile.ps1第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);
在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”
答案 0 :(得分:2)
它不是您使用的断言函数,它是用作“成员函数”的断言脚本块。但它仍然是一个脚本块。
从脚本块调用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";
}
和
#File 2 (TestCase.ps1)
#Runs the tests using the tester object
. (Resolve-Path "Tester.ps1");
function TestFailure {
$expression = {$false};
AssertTrue $expression
}
TestFailure