Skip to content

Commit

Permalink
Add the property 'CommandsMissed' to FunctionRecord objects
Browse files Browse the repository at this point in the history
  • Loading branch information
MathieuBuisson committed Jun 13, 2017
1 parent 83a3ca2 commit 9257ca5
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 21 deletions.
22 changes: 16 additions & 6 deletions PSCodeHealth/Private/Metrics/Get-FunctionTestCoverage.ps1
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
Function Get-FunctionTestCoverage {
<#
.SYNOPSIS
Gets the percentage of lines of code in the specified function that are tested by unit tests.
Gets test coverage information for the specified function.
.DESCRIPTION
Gets the percentage of lines of code in the specified function definition that are tested (executed) by unit tests.
Gets test coverage information for the specified function. This includes 2 pieces of information :
- Code coverage percentage (lines of code that are exercised by unit tests)
- Missed Commands (lines of codes or commands not being exercised by unit tests)
It uses Pester with its CodeCoverage parameter.
.PARAMETER FunctionDefinition
Expand All @@ -18,16 +21,16 @@ Function Get-FunctionTestCoverage {
.EXAMPLE
PS C:\> Get-FunctionTestCoverage -FunctionDefinition $MyFunctionAst -TestsPath $MyModule.ModuleBase
Gets the percentage of lines of code in the function $MyFunctionAst that are tested by all tests found in the module's parent directory.
Gets test coverage information for the function $MyFunctionAst given the tests found in the module's parent directory.
.OUTPUTS
System.Double
PSCodeHealth.Function.TestCoverageInfo
.NOTES
#>
[CmdletBinding()]
[OutputType([System.Double])]
[OutputType([PSCustomObject])]
Param (
[Parameter(Position=0, Mandatory)]
[System.Management.Automation.Language.FunctionDefinitionAst]$FunctionDefinition,
Expand Down Expand Up @@ -61,6 +64,13 @@ Function Get-FunctionTestCoverage {
Else {
[System.Double]$CodeCoveragePerCent = 0
}
return $CodeCoveragePerCent

$ObjectProperties = [ordered]@{
'CodeCoveragePerCent' = $CodeCoveragePerCent
'CommandsMissed' = $CodeCoverage.MissedCommands
}
$CustomObject = New-Object -TypeName PSObject -Property $ObjectProperties
$CustomObject.psobject.TypeNames.Insert(0, 'PSCodeHealth.Function.TestCoverageInfo')
return $CustomObject
}
}
7 changes: 5 additions & 2 deletions PSCodeHealth/Private/New-FunctionHealthRecord.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ Function New-FunctionHealthRecord {
[System.Management.Automation.Language.FunctionDefinitionAst]$FunctionDefinition,

[Parameter(Position=1, Mandatory)]
[System.Double]$FunctionTestCoverage
[AllowNull()]
[PSTypeName('PSCodeHealth.Function.TestCoverageInfo')]
[PSCustomObject]$FunctionTestCoverage
)

$ScriptAnalyzerResultDetails = Get-FunctionScriptAnalyzerResult -FunctionDefinition $FunctionDefinition
Expand All @@ -41,7 +43,8 @@ Function New-FunctionHealthRecord {
'ScriptAnalyzerFindings' = $ScriptAnalyzerResultDetails.Count
'ScriptAnalyzerResultDetails' = $ScriptAnalyzerResultDetails
'ContainsHelp' = Test-FunctionHelpCoverage -FunctionDefinition $FunctionDefinition
'TestCoverage' = $FunctionTestCoverage
'TestCoverage' = $FunctionTestCoverage.CodeCoveragePerCent
'CommandsMissed' = ($FunctionTestCoverage.CommandsMissed | Measure-Object).Count
'Complexity' = Measure-FunctionComplexity -FunctionDefinition $FunctionDefinition
'MaximumNestingDepth' = Measure-FunctionMaxNestingDepth -FunctionDefinition $FunctionDefinition
}
Expand Down
11 changes: 9 additions & 2 deletions Tests/TestData/MockObjects.json
Original file line number Diff line number Diff line change
Expand Up @@ -545,15 +545,19 @@
"1CommandAnalyzed": {
"CodeCoverage": {
"NumberOfCommandsAnalyzed": 1,
"NumberOfCommandsExecuted": 0
"NumberOfCommandsExecuted": 0,
"NumberOfCommandsMissed": 1,
"MissedCommands": "Mocked missed command"

}
}
},
{
"0CommandAnalyzed": {
"CodeCoverage": {
"NumberOfCommandsAnalyzed": 0,
"NumberOfCommandsExecuted": 1
"NumberOfCommandsExecuted": 1,
"NumberOfCommandsMissed": 0
}
}
},
Expand Down Expand Up @@ -728,6 +732,7 @@
"Complexity": 19,
"MaximumNestingDepth": 5,
"TestCoverage": 95,
"CommandsMissed": 3,
"ScriptAnalyzerResultDetails": [
{
"Severity": "Error"
Expand Down Expand Up @@ -769,6 +774,7 @@
"Complexity": 19,
"MaximumNestingDepth": 5,
"TestCoverage": 79,
"CommandsMissed": 12,
"ScriptAnalyzerResultDetails": [
{
"Severity": "Error"
Expand All @@ -788,6 +794,7 @@
"Complexity": 12,
"MaximumNestingDepth": 2,
"TestCoverage": 83,
"CommandsMissed": 11,
"ScriptAnalyzerResultDetails": [
{
"Severity": "Error"
Expand Down
32 changes: 23 additions & 9 deletions Tests/Unit/Private/Get-FunctionTestCoverage.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,33 @@ Describe 'Get-FunctionTestCoverage' {

Mock Invoke-Pester { $Mocks.'Invoke-Pester'.'1CommandAnalyzed' }

It 'Should return a [System.Double]' {
Get-FunctionTestCoverage -FunctionDefinition $FunctionDefinitions[0] |
Should BeOfType [System.Double]
It 'Should return an object of the type [PSCodeHealth.Function.TestCoverageInfo]' {
(Get-FunctionTestCoverage -FunctionDefinition $FunctionDefinitions[0] | Get-Member).TypeName[0] |
Should Be 'PSCodeHealth.Function.TestCoverageInfo'
}
}
Context "Pester doesn't find any command in the function" {

Mock Invoke-Pester { $Mocks.'Invoke-Pester'.'0CommandAnalyzed' }
$Result = Get-FunctionTestCoverage -FunctionDefinition $FunctionDefinitions[0]

It "Should return 0" {
Get-FunctionTestCoverage -FunctionDefinition $FunctionDefinitions[0] |
Should Be 0
It 'Should return an object with the expected property "CodeCoveragePerCent"' {
$Result.CodeCoveragePerCent | Should Be 0
}
It 'Should return an object with the expected property "CommandsMissed"' {
$Result.CommandsMissed | Should BeNullOrEmpty
}
}
Context 'Invoke-Pester returns nothing at all' {

Mock Invoke-Pester { }
$Result = Get-FunctionTestCoverage -FunctionDefinition $FunctionDefinitions[0]

It 'Should not throw but return $Null' {
Get-FunctionTestCoverage -FunctionDefinition $FunctionDefinitions[0] |
Should BeNullOrEmpty
It 'Should return an object with the expected property "CodeCoveragePerCent"' {
$Result.CodeCoveragePerCent | Should BeNullOrEmpty
}
It 'Should return an object with the expected property "CommandsMissed"' {
$Result.CommandsMissed | Should BeNullOrEmpty
}
}
Context 'TestsPath parameter' {
Expand All @@ -43,6 +49,8 @@ Describe 'Get-FunctionTestCoverage' {
Mock Invoke-Pester -ParameterFilter { $Script -eq 'TestDrive:\Module' } { $Mocks.'Invoke-Pester'.'1CommandAnalyzed' }
Mock Invoke-Pester -ParameterFilter { $Script -like '*\TestData' } { $Mocks.'Invoke-Pester'.'1CommandAnalyzed' }

$Result = Get-FunctionTestCoverage -FunctionDefinition $FunctionDefinitions[0] -TestsPath 'TestDrive:\Module\Module.Tests.ps1'

It 'Should call Invoke-Pester with the file path if TestsPath is a file' {
$Null = Get-FunctionTestCoverage -FunctionDefinition $FunctionDefinitions[0] -TestsPath 'TestDrive:\Module\Module.Tests.ps1'
Assert-MockCalled -CommandName Invoke-Pester -Scope It -ParameterFilter { $Script -eq 'TestDrive:\Module\Module.Tests.ps1' }
Expand All @@ -55,6 +63,12 @@ Describe 'Get-FunctionTestCoverage' {
$Null = Get-FunctionTestCoverage -FunctionDefinition $FunctionDefinitions[0]
Assert-MockCalled -CommandName Invoke-Pester -Scope It -ParameterFilter { $Script -like '*\TestData' }
}
It 'Should return an object with the expected property "CodeCoveragePerCent"' {
$Result.CodeCoveragePerCent | Should Be 0
}
It 'Should return an object with the expected property "CommandsMissed"' {
$Result.CommandsMissed | Should Be 'Mocked missed command'
}
}
}
}
8 changes: 6 additions & 2 deletions Tests/Unit/Private/New-FunctionHealthRecord.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ Describe 'New-FunctionHealthRecord' {

Context '1 PSScriptAnalyzer result is specified for ScriptAnalyzerResultDetails' {

$Result = New-FunctionHealthRecord -FunctionDefinition $Function -FunctionTestCoverage 91.54
$FunctionCodeCoverage = Get-FunctionTestCoverage -FunctionDefinition $Function -TestsPath "$PSScriptRoot\..\..\TestData"
$Result = New-FunctionHealthRecord -FunctionDefinition $Function -FunctionTestCoverage $FunctionCodeCoverage

It 'Should return an object of the type [PSCodeHealth.Function.HealthRecord]' {
$Result | Should BeOfType [PSCustomObject]
Expand All @@ -36,8 +37,11 @@ Describe 'New-FunctionHealthRecord' {
$Result.ContainsHelp | Should Be $True
}
It 'Should return an object with the expected property "TestCoverage"' {
$Result.TestCoverage | Should Be 91.54
$Result.TestCoverage | Should Be 0
}
It 'Should return an object with the expected property "CommandsMissed"' {
$Result.CommandsMissed | Should Be 1
}
It 'Should return an object with the expected property "Complexity"' {
$Result.Complexity | Should Be 1
}
Expand Down

0 comments on commit 9257ca5

Please sign in to comment.