Skip to content

Commit d15f697

Browse files
🩹 [Patch]: Add static code analysis use case test (#35)
## Description - Add static code analysis use case test ## Type of change <!-- Use the check-boxes [x] on the options that are relevant. --> - [ ] 📖 [Docs] - [ ] 🪲 [Fix] - [x] 🩹 [Patch] - [ ] ⚠️ [Security fix] - [ ] 🚀 [Feature] - [ ] 🌟 [Breaking change] ## Checklist <!-- Use the check-boxes [x] on the options that are relevant. --> - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas
1 parent f03f932 commit d15f697

29 files changed

+706
-82
lines changed

.github/workflows/Action-Test.yml

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,40 @@ jobs:
1111
strategy:
1212
fail-fast: false
1313
matrix:
14-
shell: [pwsh]
15-
os: [ubuntu-latest, macos-latest, windows-latest]
1614
include:
17-
- shell: powershell
18-
os: windows-latest
19-
name: Action-Test - [${{ matrix.os }}@${{ matrix.shell }}]
15+
- os: ubuntu-latest
16+
shell: pwsh
17+
path: tests/src
18+
testtype: SourceCode
19+
- os: ubuntu-latest
20+
shell: pwsh
21+
path: tests/outputs/modules
22+
testtype: Module
23+
- os: macos-latest
24+
shell: pwsh
25+
path: tests/src
26+
testtype: sourcecode
27+
- os: macos-latest
28+
shell: pwsh
29+
path: tests/outputs/modules
30+
testtype: module
31+
- os: windows-latest
32+
shell: pwsh
33+
path: tests/src
34+
testtype: sourcecode
35+
- os: windows-latest
36+
shell: pwsh
37+
path: tests/outputs/modules
38+
testtype: module
39+
- os: windows-latest
40+
shell: powershell
41+
path: tests/src
42+
testtype: sourcecode
43+
- os: windows-latest
44+
shell: powershell
45+
path: tests/outputs/modules
46+
testtype: module
47+
name: Action-Test - [${{ matrix.os }}@${{ matrix.shell }}] - [${{ matrix.path }}]
2048
runs-on: ${{ matrix.os }}
2149
steps:
2250
- name: Checkout repo
@@ -33,5 +61,6 @@ jobs:
3361
GITHUB_TOKEN: ${{ github.token }}
3462
with:
3563
Name: PSModuleTest
36-
Path: tests/outputs/modules
64+
Path: ${{ matrix.path }}
3765
Shell: ${{ matrix.shell }}
66+
TestType: ${{ matrix.TestType }}

README.md

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ This GitHub Action is a part of the [PSModule framework](https://github.com/PSMo
66

77
## Specifications and practices
88

9-
Test-PSModule follows:
9+
Test-PSModule enables:
1010

1111
- [Test-Driven Development](https://testdriven.io/test-driven-development/) using [Pester](https://pester.dev) and [PSScriptAnalyzer](https://learn.microsoft.com/en-us/powershell/utility-modules/psscriptanalyzer/overview?view=ps-modules)
1212

@@ -15,15 +15,53 @@ Test-PSModule follows:
1515
The action runs the following the Pester test framework:
1616
- [PSScriptAnalyzer tests](https://learn.microsoft.com/en-us/powershell/utility-modules/psscriptanalyzer/rules/readme?view=ps-modules)
1717
- [PSModule framework tests](#psmodule-tests)
18-
- If `RunModuleTests` is set to `true`:
19-
- Custom module tests from the `tests` directory in the module repository.
20-
- Module manifest tests using [Test-ModuleManifest](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/test-modulemanifest)
18+
- If `TestType` is set to `Module`:
19+
- The module manifest is:
20+
- tested using [Test-ModuleManifest](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/test-modulemanifest).
21+
- temporarily altered to version `999.0.0` to avoid version conflicts when running for dependencies of the framework.
22+
- The module is imported.
23+
- Custom module tests from the `tests` directory in the module repository are run.
24+
- CodeCoverage is calculated.
25+
- The following reports are calculated and uploaded as artifacts:
26+
- Test suite results.
27+
- Code coverage results.
28+
- If `TestType` is set to `SourceCode`:
29+
- The source code is tested with:
30+
- `PSScriptAnalyzer` for best practices, using custom settings.
31+
- `PSModule.SourceCode` for other PSModule standards.
2132

2233
The action fails if any of the tests fail or it fails to run the tests.
2334

2435
## How to use it
2536

2637
To use the action, create a new file in the `.github/workflows` directory of the module repository and add the following content.
38+
<details>
39+
<summary>Workflow suggestion - before module is built</summary>
40+
41+
```yaml
42+
name: Test-PSModule
43+
44+
on: [push]
45+
46+
jobs:
47+
Test-PSModule:
48+
name: Test-PSModule
49+
runs-on: ubuntu-latest
50+
steps:
51+
- name: Checkout repo
52+
uses: actions/checkout@v4
53+
54+
- name: Initialize environment
55+
uses: PSModule/Initialize-PSModule@main
56+
57+
- name: Test-PSModule
58+
uses: PSModule/Test-PSModule@main
59+
with:
60+
Path: src
61+
TestType: SourceCode
62+
63+
```
64+
</details>
2765

2866
<details>
2967
<summary>Workflow suggestion - after module is built</summary>
@@ -47,8 +85,8 @@ jobs:
4785
- name: Test-PSModule
4886
uses: PSModule/Test-PSModule@main
4987
with:
50-
Name: PSModule
5188
Path: outputs/modules
89+
TestType: Module
5290

5391
```
5492
</details>
@@ -59,9 +97,9 @@ jobs:
5997

6098
| Name | Description | Required | Default |
6199
| ---- | ----------- | -------- | ------- |
62-
| `Name` | The name of the module to test. The name of the repository is used if not specified. | `false` | |
63100
| `Path` | The path to the module to test. | `true` | |
64-
| `RunModuleTests` | Run the module tests. | `false` | `true` |
101+
| `TestType` | The type of tests to run. Can be either `Module` or `SourceCode`. | `true` | |
102+
| `Name` | The name of the module to test. The name of the repository is used if not specified. | `false` | |
65103
| `Shell` | The shell to use for running the tests. | `false` | `pwsh` |
66104

67105
## PSModule tests

action.yml

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,9 @@ inputs:
1212
Path:
1313
description: The path to the module to test.
1414
required: true
15-
RunModuleTests:
16-
description: Run the module tests.
17-
required: false
18-
default: 'true'
15+
TestType:
16+
description: The type of tests to run. Can be either 'Module' or 'SourceCode'.
17+
required: true
1918
Shell:
2019
description: The shell to use for running the tests.
2120
required: false
@@ -29,7 +28,21 @@ runs:
2928
env:
3029
GITHUB_ACTION_INPUT_Name: ${{ inputs.Name }}
3130
GITHUB_ACTION_INPUT_Path: ${{ inputs.Path }}
32-
GITHUB_ACTION_INPUT_RunModuleTests: ${{ inputs.RunModuleTests }}
31+
GITHUB_ACTION_INPUT_TestType: ${{ inputs.TestType }}
3332
run: |
3433
# Test-PSModule
3534
. "$env:GITHUB_ACTION_PATH\scripts\main.ps1" -Verbose
35+
36+
- name: Upload test results
37+
uses: actions/upload-artifact@v4
38+
if: ${{ inputs.TestType == 'Module' }}
39+
with:
40+
name: ${{ runner.os }}-${{ inputs.Shell }}-Test-Report
41+
path: ${{ github.workspace }}/outputs/Test-Report.xml
42+
43+
- name: Upload code coverage report
44+
uses: actions/upload-artifact@v4
45+
if: ${{ inputs.TestType == 'Module' }}
46+
with:
47+
name: ${{ runner.os }}-${{ inputs.Shell }}-CodeCoverage-Report
48+
path: ${{ github.workspace }}/outputs/CodeCoverage-Report.xml

scripts/helpers/Test-PSModule.ps1

Lines changed: 59 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -14,32 +14,19 @@ function Test-PSModule {
1414

1515
# Run module tests.
1616
[Parameter()]
17-
[switch] $RunModuleTests
17+
[ValidateSet('SourceCode', 'Module')]
18+
[string] $TestType = 'SourceCode'
1819
)
1920

2021
$moduleName = Split-Path -Path $Path -Leaf
21-
22-
#region Test Module Manifest
23-
Start-LogGroup 'Test Module Manifest'
24-
$moduleManifestPath = Join-Path -Path $Path -ChildPath "$moduleName.psd1"
25-
if (Test-Path -Path $moduleManifestPath) {
26-
try {
27-
$status = Test-ModuleManifest -Path $moduleManifestPath
28-
} catch {
29-
Write-Warning "⚠️ Test-ModuleManifest failed: $moduleManifestPath"
30-
throw $_.Exception.Message
31-
}
32-
Write-Verbose ($status | Format-List | Out-String) -Verbose
33-
} else {
34-
Write-Warning "⚠️ Module manifest not found: $moduleManifestPath"
35-
}
36-
Stop-LogGroup
37-
#endregion
22+
$testSourceCode = $TestType -eq 'SourceCode'
23+
$testModule = $TestType -eq 'Module'
24+
$moduleTestsPath = Join-Path $env:GITHUB_WORKSPACE 'tests'
3825

3926
#region Get test kit versions
4027
Start-LogGroup 'Get test kit versions'
41-
$PSSAModule = Get-PSResource -Name PSScriptAnalyzer | Sort-Object Version -Descending | Select-Object -First 1
42-
$pesterModule = Get-PSResource -Name Pester | Sort-Object Version -Descending | Select-Object -First 1
28+
$PSSAModule = Get-PSResource -Name PSScriptAnalyzer -Verbose:$false | Sort-Object Version -Descending | Select-Object -First 1
29+
$pesterModule = Get-PSResource -Name Pester -Verbose:$false | Sort-Object Version -Descending | Select-Object -First 1
4330

4431
Write-Verbose 'Testing with:'
4532
Write-Verbose " PowerShell $($PSVersionTable.PSVersion.ToString())"
@@ -57,6 +44,7 @@ function Test-PSModule {
5744
Data = @{
5845
Path = $Path
5946
SettingsFilePath = Join-Path $PSSATestsPath 'PSScriptAnalyzer.Tests.psd1'
47+
Verbose = $true
6048
}
6149
}
6250
Write-Verbose 'ContainerParams:'
@@ -67,11 +55,11 @@ function Test-PSModule {
6755

6856
#region Add test - Common - PSModule
6957
Start-LogGroup 'Add test - Common - PSModule'
70-
$PSModuleTestsPath = Join-Path -Path $env:GITHUB_ACTION_PATH -ChildPath 'scripts\tests\PSModule'
7158
$containerParams = @{
72-
Path = $PSModuleTestsPath
59+
Path = Join-Path -Path $env:GITHUB_ACTION_PATH -ChildPath 'scripts\tests\PSModule\Common.Tests.ps1'
7360
Data = @{
74-
Path = $Path
61+
Path = $Path
62+
Verbose = $true
7563
}
7664
}
7765
Write-Verbose 'ContainerParams:'
@@ -80,15 +68,49 @@ function Test-PSModule {
8068
Stop-LogGroup
8169
#endregion
8270

83-
#region Add test - Specific - $moduleName
84-
if ($RunModuleTests) {
85-
$moduleTestsPath = Join-Path $env:GITHUB_WORKSPACE 'tests'
71+
#region Add test - Module - PSModule
72+
if ($testModule) {
73+
Start-LogGroup 'Add test - Module - PSModule'
74+
$containerParams = @{
75+
Path = Join-Path -Path $env:GITHUB_ACTION_PATH -ChildPath 'scripts\tests\PSModule\Module.Tests.ps1'
76+
Data = @{
77+
Path = $Path
78+
Verbose = $true
79+
}
80+
}
81+
Write-Verbose 'ContainerParams:'
82+
Write-Verbose "$($containerParams | ConvertTo-Json)"
83+
$containers += New-PesterContainer @containerParams
84+
Stop-LogGroup
85+
}
86+
#endregion
87+
88+
#region Add test - SourceCode - PSModule
89+
if ($testSourceCode) {
90+
Start-LogGroup 'Add test - SourceCode - PSModule'
91+
$containerParams = @{
92+
Path = Join-Path -Path $env:GITHUB_ACTION_PATH -ChildPath 'scripts\tests\PSModule\SourceCode.Tests.ps1'
93+
Data = @{
94+
Path = $Path
95+
Verbose = $true
96+
}
97+
}
98+
Write-Verbose 'ContainerParams:'
99+
Write-Verbose "$($containerParams | ConvertTo-Json)"
100+
$containers += New-PesterContainer @containerParams
101+
Stop-LogGroup
102+
}
103+
#endregion
104+
105+
#region Add test - Module - $moduleName
106+
if ($testModule) {
86107
if (Test-Path -Path $moduleTestsPath) {
87-
Start-LogGroup "Add test - Specific - $moduleName"
108+
Start-LogGroup "Add test - Module - $moduleName"
88109
$containerParams = @{
89110
Path = $moduleTestsPath
90111
Data = @{
91-
Path = $Path
112+
Path = $Path
113+
Verbose = $true
92114
}
93115
}
94116
Write-Verbose 'ContainerParams:'
@@ -98,17 +120,17 @@ function Test-PSModule {
98120
} else {
99121
Write-Warning "⚠️ No tests found - [$moduleTestsPath]"
100122
}
101-
} else {
102-
Write-Warning "⚠️ Module tests are disabled - [$moduleName]"
103123
}
104124
#endregion
105125

106126
#region Import module
107-
if ((Test-Path -Path $moduleTestsPath) -and $RunModuleTests) {
127+
if ((Test-Path -Path $moduleTestsPath) -and $testModule) {
108128
Start-LogGroup "Importing module: $moduleName"
129+
$moduleManifestPath = Join-Path -Path $Path -ChildPath "$moduleName.psd1"
130+
Set-ModuleManifest -Path $moduleManifestPath -ModuleVersion '999.0.0'
109131
Add-PSModulePath -Path (Split-Path $Path -Parent)
110132
Get-Module -Name $moduleName -ListAvailable | Remove-Module -Force
111-
Import-Module -Name $moduleName -Force -RequiredVersion 999.0.0 -Global
133+
Import-Module -Name $moduleName -Force -RequiredVersion '999.0.0' -Global
112134
Stop-LogGroup
113135
}
114136
#endregion
@@ -123,14 +145,14 @@ function Test-PSModule {
123145
PassThru = $true
124146
}
125147
TestResult = @{
126-
Enabled = $true
148+
Enabled = $testModule
127149
OutputFormat = 'NUnitXml'
128-
OutputPath = '.\outputs\PSModuleTest.Results.xml'
129-
TestSuiteName = 'PSModule Tests'
150+
OutputPath = Join-Path -Path $env:GITHUB_WORKSPACE -ChildPath 'outputs\Test-Report.xml'
151+
TestSuiteName = 'Unit tests'
130152
}
131153
CodeCoverage = @{
132-
Enabled = $true
133-
OutputPath = '.\outputs\CodeCoverage.xml'
154+
Enabled = $testModule
155+
OutputPath = Join-Path -Path $env:GITHUB_WORKSPACE -ChildPath 'outputs\CodeCoverage-Report.xml'
134156
OutputFormat = 'JaCoCo'
135157
OutputEncoding = 'UTF8'
136158
CoveragePercentTarget = 75

scripts/main.ps1

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,13 @@ Write-Verbose "Code to test: [$codeToTest]"
1717
if (-not (Test-Path -Path $codeToTest)) {
1818
throw "Path [$codeToTest] does not exist."
1919
}
20-
$runModuleTests = $env:GITHUB_ACTION_INPUT_RunModuleTests -eq 'true'
21-
Write-Verbose "Run module tests: [$runModuleTests]"
20+
Write-Verbose "Test type to run: [$env:GITHUB_ACTION_INPUT_TestType]"
2221

2322
Stop-LogGroup
2423

2524
$params = @{
26-
Path = $codeToTest
27-
RunModuleTests = $runModuleTests
25+
Path = $codeToTest
26+
TestType = $env:GITHUB_ACTION_INPUT_TestType
2827
}
2928
$results = Test-PSModule @params
3029

scripts/tests/PSModule/CodingStyle.Tests.ps1

Lines changed: 0 additions & 5 deletions
This file was deleted.

0 commit comments

Comments
 (0)