Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle the case when the failure message contains an escape sequence #1426

Merged
merged 4 commits into from
Jan 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
20 changes: 20 additions & 0 deletions Functions/TestResults.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,26 @@ InModuleScope Pester {
$xmlTestCase.failure.'stack-trace' | Should -Be 'at line: 28 in C:\Pester\Result.Tests.ps1'
}

It "should write a failed test result when the failure message has an escape character" {
#create state
$TestResults = New-PesterState -Path TestDrive:\
$testResults.EnterTestGroup('Mocked Describe', 'Describe')
$time = [TimeSpan]25000000 #2.5 seconds
$escape = [string][char]27 # escape, also `e in PowerShell 6+
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JamesWTruher not 100% sure how to repro the error with escapes on my PowerShell 7, please verify the changes.

The cast to string here is unnecessary, but I kept it anyway to keep it same as in the code file. (There it is needed to force use of Replace(string, string) instead of Replace(char, char) which fails.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'll grant you that my test is quite artificial, but here's the way to see it:

PS> Get-Content /tmp/t1.tests.ps1
describe "a simple test" {
    it "can handle an error with an escape sequence" {
       throw  "`e[31m < < , > > `e[0m"
    }
}

when run as follows, you can see the error:

[Pester|master000+0?0] PS> invoke-pester /tmp/t1.tests.ps1 -OutputFile /tmp/xx.xml -OutputFormat NUnitXml
    ____            __
   / __ \___  _____/ /____  _____
  / /_/ / _ \/ ___/ __/ _ \/ ___/
 / ____/  __(__  ) /_/  __/ /
/_/    \___/____/\__/\___/_/
Pester v4.9.0
Executing all tests in '/tmp/t1.tests.ps1'

Executing script /tmp/t1.tests.ps1

  Describing a simple test
    [-] can handle an error with an escape sequence 1ms
      RuntimeException:  < < , > > 
      at <ScriptBlock>, /tmp/t1.tests.ps1: line 3
Tests completed in 24ms
Tests Passed: 0, Failed: 1, Skipped: 0, Pending: 0, Inconclusive: 0 
MethodInvocationException: /Users/jimtru/src/github/forks/JamesWTruher/Pester/Functions/TestResults.ps1
Line |
 591 |             $xmlWriter.WriteElementString('message', $TestResult.FailureMessage)
     |             ^ Exception calling "WriteElementString" with "2" argument(s): "', hexadecimal value 0x1B, is an invalid character."

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nohwnd - I probably should have put that in the test, but it seemed like too much.

$TestResults.AddTestResult("Failed testcase", 'Failed', $time, "Assert failed: ""Expected: $escape[34mTest$escape[0m. But was: Testing""", 'at line: 28 in C:\Pester\Result.Tests.ps1')

#export and validate the file
[String]$testFile = "$TestDrive{0}Results{0}Tests.xml" -f [System.IO.Path]::DirectorySeparatorChar
Export-XmlReport $testResults $testFile 'NUnitXml'
$xmlResult = [xml] (Get-Content $testFile)
$xmlTestCase = $xmlResult.'test-results'.'test-suite'.'results'.'test-suite'.'results'.'test-case'
$xmlTestCase.name | Should -Be "Mocked Describe.Failed testcase"
$xmlTestCase.result | Should -Be "Failure"
$xmlTestCase.time | Should -Be "2.5"
$xmlTestCase.failure.message | Should -Be 'Assert failed: "Expected: &27;[34mTest&27;[0m. But was: Testing"'
$xmlTestCase.failure.'stack-trace' | Should -Be 'at line: 28 in C:\Pester\Result.Tests.ps1'
}

It "should log the reason for a skipped test when provided" {
$message = "skipped for reasons"
$TestResults = New-PesterState -Path TestDrive:\
Expand Down
4 changes: 3 additions & 1 deletion Functions/TestResults.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -588,7 +588,9 @@ function Write-NUnitTestCaseAttributes($TestResult, [System.Xml.XmlWriter] $XmlW
$XmlWriter.WriteAttributeString('result', 'Failure')
$XmlWriter.WriteAttributeString('executed', 'True')
$XmlWriter.WriteStartElement('failure')
$xmlWriter.WriteElementString('message', $TestResult.FailureMessage)
# manually replace Escape character (escape meaning "Escape key", not escape sequence "`")
# with &27 to avoid breaking serialized output when error contains it
$xmlWriter.WriteElementString('message', $TestResult.FailureMessage.Replace([string][char]27,'&27;'))
$XmlWriter.WriteElementString('stack-trace', $TestResult.StackTrace)
$XmlWriter.WriteEndElement() # Close failure tag
break
Expand Down