我是pester测试的新手,我正试图测试我已经制作的自定义dsc资源,我正在测试的功能如下:
<#
.SYNOPSIS
Get parameters for Snmp configuration
.PARAMETER AgentSvcPhysical
Used as a boolean flag to set (True) or unset (False) the Physical
checkbox (Agent Tab, Service section)
.PARAMETER AgentSvcApplications
Used as a boolean flag to set (True) or unset (False) the
Applications checkbox (Agent Tab, Service section)
.PARAMETER AgentSvcDatalink
Used as a boolean flag to set (True) or unset (False) the Datalink
and subnetwork checkbox (Agent Tab, Service section)
.PARAMETER AgentSvcInternet
Used as a boolean flag to set (True) or unset (False) the Internet
checkbox (Agent Tab, Service section)
.PARAMETER AgentSvcEnd2End
Used as a boolean flag to set (True) or unset (False) the End-To-End
checkbox (Agent Tab, Service section)
.PARAMETER AgentContact
Used as a string to set (or unset) the name of the contact for SNMP,
leave blank to unset
.PARAMETER AgentLocation
Used as a string to set (or unset) the location for SNMP, leave
blank to unset
.PARAMETER SecSendTraps
Used as a boolean flag to set (True) or unset (False) the Send
authentication trap checkbox (Security Tab)
.PARAMETER SecCommName
Used as a string to set (or unset) the community name, leave blank
to remove
.PARAMETER SecCommRights
Used as a string to set (or unset) the community rights, USAGE:
"NONE", "NOTIFY", "READ ONLY", "READ WRITE" or "READ CREATE"
.PARAMETER SecAuthPackets
Used as a boolean flag to set (True) or unset (False) the value for
snmp packet acceptance (Security Tab). USAGE: True= "Accept packet from any
host", False="Accept packet from these hosts" (if set to false you need to
specify a value for the SecPacketsHost parameter)
.PARAMETER SecPacketsHost
Used as a string to set (or unset) the authorized hostname to send
SNMP packet to the host (can be a hostame or ip address), if you need to
enter more than one host use ; as separator. Ex:
10.0.0.1;10.0.0.2
#> function Get-TargetResource {
[CmdletBinding()]
[OutputType([Hashtable])]
param
(
[Parameter(Mandatory = $false)]
[ValidateSet("Present", "Absent")]
[string]$Ensure = "Absent",
[Parameter(Mandatory = $false)]
[bool]
$AgentSvcPhysical = $false,
[Parameter(Mandatory = $false)]
[bool]
$AgentSvcApplications = $false,
[Parameter(Mandatory = $false)]
[bool]
$AgentSvcDatalink = $false,
[Parameter(Mandatory = $false)]
[bool]
$AgentSvcInternet = $false,
[Parameter(Mandatory = $false)]
[bool]
$AgentSvcEnd2End = $false,
[Parameter(Mandatory = $false)]
[ValidateNotNull()]
[String]
[AllowEmptyString()]
$AgentContact = "",
[Parameter(Mandatory = $false)]
[ValidateNotNull()]
[String]
[AllowEmptyString()]
$AgentLocation = "",
[Parameter(Mandatory = $false)]
[bool]
$SecSendTraps = $false,
[Parameter(Mandatory = $true)]
[ValidateNotNull()]
[String]
[AllowEmptyString()]
$SecCommName = "",
[Parameter(Mandatory = $false)]
[ValidateSet('NONE', 'NOTIFY', 'READ ONLY', 'READ WRITE', 'READ CREATE')]
[String]
$SecCommRights = "NONE",
[Parameter(Mandatory = $false)]
[bool]
$SecAuthPackets = $false,
[Parameter(Mandatory = $false)]
[String]
$SecPacketsHost = "NotSet"
)
# Default values before runnning resource logic
$snmpResource = @{
SecCommName = $SecCommName
Ensure = 'Absent'
AgentSvcPhysical = $false
AgentSvcApplications = $false
AgentSvcDatalink = $false
AgentSvcInternet = $false
AgentSvcEnd2End = $false
AgentContact = $AgentContact
AgentLocation = $AgentLocation
SecSendTraps = $false
SecCommRights = $SecCommRights
SecAuthPackets = $false
SecPacketsHost = $SecPacketsHost
}
#key parameter to validate state
$SecComm_Key = "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SNMP\Parameters\ValidCommunities"
#Assigning values from user input if ($AgentSvcPhysical -eq $true) {
Write-Verbose -Message "AgentSvcPhysical value set to true"
$snmpResource['AgentSvcPhysical'] = $true } if ($AgentSvcApplications -eq $true) {
Write-Verbose -Message "AgentSvcApplications value set to true"
$snmpResource['AgentSvcApplications'] = $true }
if ($AgentSvcDatalink -eq $true) {
Write-Verbose -Message "AgentSvcDatalink value set to true"
$snmpResource['AgentSvcDatalink'] = $true }
if ($AgentSvcInternet -eq $true) {
Write-Verbose -Message "AgentSvcInternet value set to true"
$snmpResource['AgentSvcInternet'] = $true }
if ($AgentSvcEnd2End -eq $true) {
Write-Verbose -Message "AgentSvcEnd2End value set to true"
$snmpResource['AgentSvcEnd2End'] = $true }
if ($SecSendTraps -eq $true) {
Write-Verbose -Message "SecSendTraps value set to true"
$snmpResource['SecSendTraps'] = $true } if ($SecAuthPackets -eq $true) {
Write-Verbose -Message "SecAuthPackets value set to true"
$snmpResource['SecAuthPackets'] = $true } $valueNameSpecified= (-not [String]::IsNullOrEmpty($SecCommName)) if ($valueNameSpecified
-eq $true) {
$registryKey= Get-RegistryKey_HF -RegistryKeyPath $SecComm_Key -WriteAccessAllowed
if ($null -eq $registryKey) {
Write-Verbose -Message "Registry Key Does Not Exist"
}
else {
Write-Verbose -Message "Registry Key Exist"
$valueDisplayName = Get-RegistryKeyValueDisplayName_HF -RegistryKeyValueName $SecCommName
$snmpResource['SecCommName'] = $valueDisplayName
$registryKeyValue = Get-RegistryKeyValue_HF -RegistryKey $registryKey -RegistryKeyValueName $valueDisplayName
if ($null -eq $RegistryKeyValue) {
Write-Verbose -Message "Registry Key Value Does Not Exist"
}
else {
Write-Verbose -Message "Registry Key Value Does Exist"
#we determine the community security from user input
switch ($SecCommRights) {
"NONE" { $desiredValue = 1 }
"NOTIFY" { $desiredValue = 2 }
"READ ONLY" { $desiredValue = 4 }
"READ WRITE" { $desiredValue = 8 }
"READ CREATE" { $desiredValue = 16 }
}
$keyValuesMatch= Test-RegistryKeyValuesMatch_HF -ExpectedRegistryKeyValue $desiredValue -ActualRegistryKeyValue $registryKeyValue -RegistryKeyValueType 'DWord'
if ($keyValuesMatch -eq $true) {
Write-Verbose -Message "The registry key value match user input, state = Present"
$snmpResource['Ensure'] = 'Present'
}
}
} }
return $snmpResource }
当我在没有pester的情况下手动测试资源时,它会返回正确的结果,如下图所示:get-targetresource result
以下是我的测试代码:
<#
.SYNOPSIS
Snmp_Dsc Unit testing script
.DESCRIPTION
To Use:
1. Copy to \Tests\Unit\ folder and rename <ResourceName>.tests.ps1 (e.g. MSFT_xFirewall.tests.ps1)
2. Customize TODO sections.
3. Delete all template comments (TODOs, etc.)
.NOTES
There are multiple methods for writing unit tests. This template provides a few examples
which you are welcome to follow but depending on your resource, you may want to
design it differently. Read through our TestsGuidelines.md file for an intro on how to
write unit tests for DSC resources: https://github.com/PowerShell/DscResources/blob/master/TestsGuidelines.md
#>
#region HEADER
# Unit Test Template Version: 1.2.1
#Path to the ..\Tests folder
$script:testFolderPath = Split-Path -Path $PSScriptRoot -Parent
#Path to the ..\Tests\TestHelpers folder
$script:testHelpersPath = Join-Path -Path $script:testFolderPath -ChildPath 'TestHelpers'
$moduleRootFilePath = Split-Path -Path $script:testFolderPath -Parent
$snmpResourceModuleFilePath = Join-Path -Path $moduleRootFilePath -ChildPath 'Snmp_Dsc.psm1'
#We import the CommonTestHelper.psm1 module from the ..\Tests\TestHelpers folder
Import-Module -Name (Join-Path -Path $script:testHelpersPath -ChildPath 'CommonTestHelper.psm1')
#We import the MSFT_RegistryResource.TestHelper.psm1 module from the ..\Tests\TestHelpers folder
Import-Module -Name (Join-Path -Path $script:testHelpersPath -ChildPath 'MSFT_RegistryResource.TestHelper.psm1')
#We import the MSFT_ServiceResource.TestHelper.psm1 module from the ..\Tests\TestHelpers folder
Import-Module -Name (Join-Path -Path $script:testHelpersPath -ChildPath 'MSFT_ServiceResource.TestHelper.psm1')
# TODO: Insert the correct <ModuleName> and <ResourceName> for your resource
#endregion HEADER
function Invoke-TestSetup {
# TODO: Optional init code goes here...
}
function Invoke-TestCleanup {
Restore-TestEnvironment -TestEnvironment $TestEnvironment
# TODO: Other Optional Cleanup Code Goes Here...
}
# Begin Testing
try
{
Invoke-TestSetup
$script:registryKeyValueTypes = @( 'String', 'Binary', 'DWord', 'QWord', 'MultiString', 'ExpandString' )
$script:validRegistryDriveRoots = @( 'HKEY_CLASSES_ROOT', 'HKEY_CURRENT_USER', 'HKEY_LOCAL_MACHINE', 'HKEY_USERS', 'HKEY_CURRENT_CONFIG' )
$script:validRegistryDriveNames = @( 'HKCR', 'HKCU', 'HKLM', 'HKUS', 'HKCC' )
#Values for testing
$script:SecComm_Key = "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SNMP\Parameters\ValidCommunities"
$script:SecComm_KeyValue = "4"
$script:SecComm_KeyType = 'DWord'
# This registry key is used ONLY for its type (Microsoft.Win32.RegistryKey). It is not actually accessed in any way during these tests.
$script:testRegistryKey = [Microsoft.Win32.Registry]::CurrentConfig
Describe 'Snmp\Get-TargetResource' {
Copy-Item $snmpResourceModuleFilePath TestDrive:\Snmp_Dsc.ps1 -Force
Mock Export-ModuleMember {return $true}
. "TestDrive:\Snmp_Dsc.ps1"
Mock -CommandName 'Get-RegistryKey_HF' -MockWith { }
Context 'Key parameter (SecCommName) is set to public and SecCommRight is set to NONE' {
BeforeEach {
$path = "HKLM:\SYSTEM\CurrentControlSet\Services\SNMP\Parameters\ValidCommunities"
Remove-ItemProperty –Path $path –Name "public" -ErrorAction SilentlyContinue -Force
New-ItemProperty -Path $path -Name "public" -Value 1 -PropertyType "DWORD" -ErrorAction SilentlyContinue
}
$getTargetResourceParameters = @{
AgentSvcPhysical = $true
AgentSvcApplications = $true
AgentSvcDatalink = $true
AgentSvcInternet = $true
AgentSvcEnd2End = $true
SecSendTraps = $true
SecCommName = "public"
SecCommRights = "NONE"
SecAuthPackets = $true
}
It 'Should not throw' {
{ $null = Get-TargetResource @getTargetResourceParameters } | Should Not Throw
}
It 'Should retrieve the registry key' {
$getRegistryKeyParameterFilter = {
$registryKeyPathParameterCorrect = $RegistryKeyPath -eq $script:SecComm_Key
return $registryKeyPathParameterCorrect
}
Assert-MockCalled -CommandName 'Get-RegistryKey_HF' -ParameterFilter $getRegistryKeyParameterFilter -Times 1 -Scope 'Context'
}
$getTargetResourceResult = Get-TargetResource @getTargetResourceParameters
It 'Should return a hashtable' {
$getTargetResourceResult -is [Hashtable] | Should Be $true
}
It 'Should return 13 hashtable properties' {
$getTargetResourceResult.Keys.Count | Should Be 13
}
It 'Should return the AgentSvcPhysical property as True' {
$getTargetResourceResult.AgentSvcPhysical | Should Be $true
}
It 'Should return the AgentSvcApplications property as True' {
$getTargetResourceResult.AgentSvcApplications | Should Be $true
}
It 'Should return the AgentSvcDatalink property as True' {
$getTargetResourceResult.AgentSvcDatalink | Should Be $true
}
It 'Should return the AgentSvcInternet property as True' {
$getTargetResourceResult.AgentSvcInternet | Should Be $true
}
It 'Should return the AgentSvcEnd2End property as True' {
$getTargetResourceResult.AgentSvcEnd2End | Should Be $true
}
It 'Should return the Ensure property as Present' {
$getTargetResourceResult.Ensure | Should Be 'Present'
}
AfterEach {
$path = "HKLM:\SYSTEM\CurrentControlSet\Services\SNMP\Parameters\ValidCommunities"
Remove-ItemProperty –Path $path –Name "public" -ErrorAction SilentlyContinue -Force
}
}
}
# TODO: add more Describe blocks as needed
}
finally
{
Invoke-TestCleanup
}
这些测试非常简单,而且通常(我认为)它们都应该没有错误地通过,问题出在Ensure属性返回“Absent”时它应该返回“Present”,如下图所示:
它使用的是手动测试的相同数据,我真的不明白我在做错了什么?希望有人可以帮我解决这个问题。提前谢谢!
编辑: pester中的错误信息:
Describing Snmp\Get-TargetResource
Context Key parameter (SecCommName) is set to public and SecCommRight is
set to NONE
[+] Should not throw 262ms
[+] Should retrieve the registry key 139ms
[+] Should return a hashtable 84ms
[+] Should return 13 hashtable properties 16ms
[+] Should return the AgentSvcPhysical property as True 21ms
[+] Should return the AgentSvcApplications property as True 19ms
[+] Should return the AgentSvcDatalink property as True 25ms
[+] Should return the AgentSvcInternet property as True 24ms
[+] Should return the AgentSvcEnd2End property as True 17ms
[-] Should return the Ensure property as Present 179ms
Expected string length 7 but was 6. Strings differ at index 0.
Expected: {Present}
But was: {Absent}
-----------^
131: $getTargetResourceResult.Ensure | Should Be 'Present'
at <ScriptBlock>, C:\Utils\develop-snmpdsc-tests\DscResources\Snmp_Dsc\Tests\Unit\Snmp_Dsc.tests.ps1: line 131
[-] Error occurred in test script 'C:\Utils\develop-snmpdsc-tests\DscResources\Snmp_Dsc\Tests\Unit\Snmp_Dsc.tests.ps1'
125ms
CommandNotFoundException: The term 'Restore-TestEnvironment' is not recognized as the name of a cmdlet, function, scr
ipt file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correc
t and try again.
at Invoke-TestCleanup, C:\Utils\develop-snmpdsc-tests\DscResources\Snmp_Dsc\Tests\Unit\Snmp_Dsc.tests.ps1: line 47
at <ScriptBlock>, C:\Utils\develop-snmpdsc-tests\DscResources\Snmp_Dsc\Tests\Unit\Snmp_Dsc.tests.ps1: line 145
at <ScriptBlock>, C:\Program Files\WindowsPowerShell\Modules\Pester\3.4.0\Pester.psm1: line 297
at Invoke-Pester, C:\Program Files\WindowsPowerShell\Modules\Pester\3.4.0\Pester.psm1: line 310
at <ScriptBlock>, <No file>: line 1
注意:我做了一些测试,问题似乎与Testdrive有关..当我直接使用脚本(点源)时,我得到权利结果..这仍然是奇怪的,因为testdrive应该在测试后丢弃它的内容它似乎不是吗?