0

I am writing PowerShell script for dotCover to generate coverage report using NUnit-console.exe After I run the script -

$testRunner="C:\Program Files (x86)\NUnit 2.6.2\bin\nunit-console.exe"
$testContainers="path/to/test1.dll","path/to/test2.dll"
$dotcover="D:\JetBrains.dotCover.CommandLineTools.2019.3.4\dotcover.exe"

foreach($test in $testContainers)
{
$testAssembly=Get-Item $test
$testName= $testAssembly.BaseName
&$dotcover cover /TargetExecutable=$testRunner /TargetArguments=$test /Output="D:\JetBrains.dotCover.CommandLineTools.2019.3.4\TestReport\$testName.dcvr"
}

$testReports=$testContainer|%{
$testAssembly=Get-Item $test
$name= $testAssembly.BaseName
return ("D:\JetBrains.dotCover.CommandLineTools.2019.3.4\TestReport\{0}.dcvr" -f $name)
}

$testReportArguments=[String]::Join(";",$testReports)
&$dotcover merge /Source="$testReportArguments" /Output="D:\JetBrains.dotCover.CommandLineTools.2019.3.4\TestReport\mergedReport.dcvr" /ReportType="DCVR"


&$dotcover report /Source="D:\JetBrains.dotCover.CommandLineTools.2019.3.4\TestReport\mergedReport.dcvr" /Output="D:\JetBrains.dotCover.CommandLineTools.2019.3.4\TestReport\mergedReport.html" /ReportType="HTML"

It is giving the following error-

Unhandled Exception:
System.UnauthorizedAccessException: Access to the path 'C:\Program Files (x86)\NUnit 2.6.2\bin\TestResult.xml' is denied.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String 
msgPath, Boolean bFromProxy)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options)
   at System.IO.StreamWriter..ctor(String path, Boolean append, Encoding encoding, Int32 bufferSize)
   at System.IO.StreamWriter..ctor(String path)
   at NUnit.ConsoleRunner.ConsoleUi.Execute(ConsoleOptions options)
   at NUnit.ConsoleRunner.Runner.Main(String[] args)

Even though that TestResult.xml file is not at that location it is at-

C:\Program Files (x86)\NUnit 2.6.2\doc\files\TestResult.xml

but I copied that file and put it to the bin folder but still the error persists. Is this problem related to rights or something? any way to get rid of this? and after this the execution is at halt neither failing nor passing.

NetSurfer
  • 103
  • 1
  • 9
  • You are not calling that XML file directly anywhere and it's not PowerShell that would know where it is, that would be dorCover (which I've read about but never used). Also, quoting and spacing, regarding how arguments are pass is important, when using external tools. crowding code can be an issue. See --- https://social.technet.microsoft.com/wiki/contents/articles/7703.powershell-running-executables.aspx --- https://blogs.technet.microsoft.com/josebda/2012/03/03/using-windows-powershell-to-run-old-command-line-tools-and-their-weirdest-parameters – postanote Mar 31 '20 at 00:12
  • @postanote can you please show me changes in the code? – NetSurfer Apr 01 '20 at 12:07

1 Answers1

0

Anytime you see 'Access Denied', then yes, it's a permissions / ACL problem. So, you do need to check that.

Honestly, I'd suggest adding those 'exe' paths to your Windows System Path or the PowerShell environment path. However, taking what you've shown thus far, as per the link I included in my comment:

PowerShell: Running Executables

  1. The Call Operator &

Why:

Used to treat a string as a SINGLE command. Useful for dealing with spaces. In PowerShell V2.0, if you are running 7z.exe (7-Zip.exe) or another command that starts with a number, you have to use the command invocation operator &. The PowerShell V3.0 parser do it now smarter, in this case you don’t need the & anymore.

Details:

Runs a command, script, or script block. The call operator, also known as the "invocation operator," lets you run commands that are stored in variables and represented by strings. Because the call operator does not parse the command, it cannot interpret command parameters

# Example:
& 'C:\Program Files\Windows Media Player\wmplayer.exe' "c:\videos\my home video.avi"  /fullscreen

Things can get tricky when an external command has a lot of parameters or there are spaces in the arguments or paths!

With spaces you have to nest Quotation marks and the result it is not always clear!

In this case it is better to separate everything like so:

$CMD  =  'SuperApp.exe'
$arg1 =  'filename1'
$arg2 =  '-someswitch'
$arg3 =  'C:\documents and settings\user\desktop\some other file.txt'
$arg4 =  '-yetanotherswitch'
& $CMD $arg1 $arg2 $arg3 $arg4

# or same like that:
$AllArgs =  @('filename1',  '-someswitch', 'C:\documents and settings\user\desktop\some other file.txt', '-yetanotherswitch')
& 'SuperApp.exe' $AllArgs

So, this change should get you going. Again, I don't use the tool, so no way to validate and thus you may need to tweak.

See also:

Implementing DotCover from Powershell

$testRunner     = 'C:\Program Files (x86)\NUnit 2.6.2\bin\nunit-console.exe'
$testContainers = 'path/to/test1.dll','path/to/test2.dll'
$dotcover       = 'D:\JetBrains.dotCover.CommandLineTools.2019.3.4\dotcover.exe'

foreach($test in $testContainers)
{
    $testAssembly = Get-Item $test
    $testName     = $testAssembly.BaseName

    $arg1 = 'cover'
    $arg2 = '/TargetExecutable = $testRunner'
    $arg3 = '/TargetArguments = $test'
    $arg4 = '/TargetExecutable = $testRunner'
    $arg5 = '/Output = "D:\JetBrains.dotCover.CommandLineTools.2019.3.4\TestReport\$testName.dcvr"'
    & $dotcover $arg1 $arg2 $arg3 $arg4 $arg5
}

$testReports  = $testContainer | 
%{
    $testAssembly = Get-Item $test
    $name = $testAssembly.BaseName
    return ('D:\JetBrains.dotCover.CommandLineTools.2019.3.4\TestReport\{0}.dcvr' -f $name)
}

$testReportArguments = [String]::Join(';',$testReports)

$arg1 = 'merge'
$arg2 = '/Source = $testReportArguments'
$arg3 = '/Output = "D:\JetBrains.dotCover.CommandLineTools.2019.3.4\TestReport\mergedReport.dcvr"'
$arg4 = '/ReportType = "DCVR"'
& $dotcover $arg1 $arg2 $arg3 $arg4


$arg1 = 'report'
$arg2 = '/Source = "D:\JetBrains.dotCover.CommandLineTools.2019.3.4\TestReport\mergedReport.dcvr"'
$arg3 = '/Output = "D:\JetBrains.dotCover.CommandLineTools.2019.3.4\TestReport\mergedReport.html"'
$arg4 = '/ReportType="HTML"'
& $dotcover $arg1 $arg2 $arg3 $arg4
postanote
  • 15,138
  • 2
  • 14
  • 25