Skip to content
Open
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
88a7666
Starting from AI slop
guimafelipe Sep 28, 2025
1c42580
Cleaning up AI slop
guimafelipe Sep 28, 2025
7ab8869
Deleting other folder
guimafelipe Sep 28, 2025
be3f0e4
Adding cmd file
guimafelipe Sep 28, 2025
263b4ac
Renaming outputFolder to output
guimafelipe Sep 29, 2025
8071b27
Removing mandatory false from arguments
guimafelipe Sep 29, 2025
8f45946
Defaulting to host machine archtecture
guimafelipe Sep 29, 2025
62fe6aa
Restricting to allowed values
guimafelipe Sep 29, 2025
1a8ab9a
Removing unecessarry parameter annotation
guimafelipe Sep 29, 2025
fb8a250
Adding building tests
guimafelipe Sep 29, 2025
e6268f4
Adding comments with better description
guimafelipe Sep 29, 2025
c8249c1
Moving msbuild path to inside function
guimafelipe Sep 29, 2025
f19cfd6
cleaning up the script
guimafelipe Sep 29, 2025
17c7b36
Setting build verbosity to minimal
guimafelipe Sep 29, 2025
012c0dd
Removing some lines
guimafelipe Sep 29, 2025
44fb939
Adding filters in parameters
guimafelipe Sep 30, 2025
40502cf
Adding more parameters
guimafelipe Sep 30, 2025
2b1bd8c
Fixing parameters and filtering
guimafelipe Sep 30, 2025
b6a213d
Fixing colors
guimafelipe Sep 30, 2025
268fdf6
Adding documentation and removing unnecessary parameters
guimafelipe Sep 30, 2025
c0a83cc
Small fix on documentation
guimafelipe Sep 30, 2025
4f3da2d
Adding module for test functions
guimafelipe Sep 30, 2025
5ab53e3
Changing TestAll.ps1 to use Tests.psm1 module
guimafelipe Sep 30, 2025
21837df
Fixing output path
guimafelipe Sep 30, 2025
fcfbfe7
Merge branch 'main' into user/felipeda/runtests
guimafelipe Sep 30, 2025
c50904e
Unifyting everything in testall.ps1
guimafelipe Oct 2, 2025
c9e4183
Removing run tests scripts
guimafelipe Oct 2, 2025
52d2185
Fix typo
guimafelipe Oct 2, 2025
ea45810
Adding configuration and platform to build function and parenthesis t…
guimafelipe Oct 2, 2025
3bf63ac
Fixing param to Wtt logging
guimafelipe Oct 2, 2025
8a5cb37
Changing name from filter tests to select tests
guimafelipe Oct 3, 2025
f34382d
Cleaning up the script a bit
guimafelipe Oct 3, 2025
4050fff
Simplifying parameters
guimafelipe Oct 3, 2025
63deae4
Moving fuctions back to TestAll.ps1
guimafelipe Oct 3, 2025
dc75b5c
Preserving original order of functions
guimafelipe Oct 3, 2025
7c56b3f
Removing module file
guimafelipe Oct 3, 2025
f5c457d
Fixing path building
guimafelipe Oct 3, 2025
37593d8
Merge branch 'main' into user/felipeda/runtests
guimafelipe Oct 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions tools/RunTests.cmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@echo off

powershell -ExecutionPolicy Unrestricted -NoLogo -NoProfile -File %~dp0\tools\RunTests.ps1 %*

exit /b %ERRORLEVEL%
242 changes: 242 additions & 0 deletions tools/RunTests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
<#
.SYNOPSIS
Copy link
Member

Choose a reason for hiding this comment

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

What's wrong with TestAll.ps1 (in root of the repository)?

If that lacks functionality (e.g. run explicit subset of tests) why not improve TestAll?

Or perhaps fork it to Test.cmd and tools\Test.ps1 and change \TestAll.cmd to run Test.cmd ...options for existing TestAll.cmd behavior...

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 used TestAll.ps1 as base to create this script. The idea for this one is to be a tool for developers to quickly iterate on testing based on what I was doing repetitively. I did not want this to merge with what TestAll.ps1 is doing as this later one is used on our build pipelines and requires way more stuff (log files and .wprp for example) than what is intended for a quick local test run to check if some changes broke anything.

My usual loop was to call MSBuild locally to build the tests, and then go to BuildOutput and run the tests. Now thinking back again, I realize it might be better to also include the test building in this script, as it makes sense we always would want to build and test together.

Copy link
Member

Choose a reason for hiding this comment

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

I realize it might be better to also include the test building in this script, as it makes sense we always would want to build and test together

I don't know about that. Depends if every test run requires build. I find that's more of a mixed bag. Sometimes I run a test multiple times between changing any code

Also, don't assume dev inner loop doesn't care about log files or .wprp.

Sounds like you're not reinventing TestAll.ps1 so much as BuildAll.ps1

It would be better to enhance those, or perhaps refactor the underlying plumbing from those with lots of options for dev inner-loop use (DoBuild.ps1, DoTest.ps1) and change those to call the new scripts with options to preserve their current behavior

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 changed the script to receive more parameters and filtering based on the .testdef properties. Also, made the build step optional.

For making the TestAll.ps1 and the BuildAll.ps1 scripts to share code with this one, it felt it should come in a separate pull request as this one would be way too much. I would like to hear your opinions on this and if it is better to proceed with this one being a separated change after some clean up.

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 refactored the test code into a Tests.psm1 module and now TestAll.ps1 is using it

Build and run tests from a specific .testdef file

.DESCRIPTION
The BuildAndRunTests script takes a testdef filename (without extension) and build then runs
the tests defined in that specific .testdef file. This is useful for development when you want
to run tests for a specific component rather than all tests.

The script searches for the specified .testdef file in the test directory structure and
builds the associated test project. It then finds the .testdef file in the output directory,
lists the tests defined in the .testdef file and executes the tests according to the testdef configuration.

.PARAMETER TestDef
The name of the .testdef file to run (without the .testdef extension)
Example: "Deployment" to run "Deployment.testdef"

.PARAMETER Output
Set the base folder for the script to look for testdefs. Default: BuildOutput

.PARAMETER Platform
Only run tests for the selected platform (x86, x64, arm64). Default: the current architecture

.PARAMETER Configuration
Only run tests for the selected configuration (Debug, Release). Default: Release

.PARAMETER RunDisabled
If set, will run tests that are marked as "Disabled" in the testdef file. Default: false

.EXAMPLE
.\RunTests.ps1 -TestDef "DeploymentTests"

.EXAMPLE
.\RunTests.ps1 -TestDef "Deployment" -Platform "x86" -Configuration "Debug"
#>

param(
[Parameter(Mandatory=$true)]
[string]$TestDef,
Copy link
Member

Choose a reason for hiding this comment

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

Can this be a filespec or pattern? e.g. RunTests -TestDef *xyx*.testdef to run all files found recursively matching xyz.testdef

Copy link
Member

Choose a reason for hiding this comment

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

P.S. Parameter name suggestions:

  • TestDef
  • Test
  • Path
  • File

I think Path most closely matches common Powershell use

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 think we can change this to be a pattern. I first went for simplicity following the loop I had with testing locally, and usually I wanted to test everything under a .testdef file to check for regressions or tests breaking. But sometimes we want to test specific tests, so a parameter would be good to have and could override the parameters defined in the .testdef file.

Copy link
Member

Choose a reason for hiding this comment

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

-Path ==> Get-ChildItem -Recurse $path

-Blah ==> For any .testdef found via -Path only run it if the blah property in the .testdef matches
there's no 'name' property in a testdef but could do this for the meaningful properties as a regex value e.g.

-Property:Description "Package.*Test.Add" would only run this one case in test\packagemanagerapi\test.testdef

        {
            "Description": "PackageManagerTests.Add* tests for feature PackageManager (arm64 not currently enabled)",
            "Filename": "PackageManagerTests.dll",
            "Parameters": "/name=Test::PackageManager::Tests::PackageDeploymentManagerTests_Add*",
            "Architectures": ["x86", "x64"],
            "Status": "Enabled"
        },

as in if ($PropertyDescription -match $DescriptionFromParsedTestDefJson)

Copy link
Member

Choose a reason for hiding this comment

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

BTW take a look at test\packagemanager\api\Test.testdef for an example of a .testdef with multiple Tests. One should be able to easily run a subset of Tests in a .testdef

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 think the current version of the script supports these scenarios.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed the RunTests.ps1 script completely and refactored TestAll.ps1


[string]$Output = "BuildOutput",

[ValidateSet("x86", "x64", "arm64", IgnoreCase=$true)]
[string]$Platform = "$($env:PROCESSOR_ARCHITECTURE)",

[ValidateSet("Release", "Debug", IgnoreCase=$true)]
[string]$Configuration = "Release",

[switch]$RunDisabled = $false
)

function Find-TestDefFile
{
param(
$testDefName,
$baseFolder
)

$outputFolderPath = Join-Path $baseFolder $configPlat
$testDefFileName = "$testDefName.testdef"
$testDefFile = Get-ChildItem -Recurse -Filter $testDefFileName $outputFolderPath -ErrorAction SilentlyContinue | Select-Object -First 1

if ($null -eq $testDefFile)
{
Write-Error "Could not find testdef file '$testDefFileName' in '$outputFolderPath'"
Exit 1
}

Write-Host "Found testdef file: $($testDefFile.FullName)"
return $testDefFile
}

function Build-Tests
{
param(
$testDefFile,
$msbuildPath
)

$testFolder = Split-Path -parent $testDefFile
Write-Host "Building tests in folder: $testFolder"
$projFile = Get-ChildItem -Filter "*.vcxproj" -Path $testFolder | Select-Object -First 1

if ($null -eq $projFile)
{
Write-Error "Could not find a .vcxproj file in $testFolder"
Exit 1
}

Write-Host "Found project file: $projFile"

& $msbuildPath $projFile.FullName /p:Configuration=$Configuration /p:Platform=$Platform
}

function Get-Tests
{
param($testDefFile)

$tests = @()
$testJson = Get-Content -Raw $testDefFile.FullName | ConvertFrom-Json

$count = 0
$baseId = $testDefFile.BaseName
foreach ($testConfig in $testJson.Tests)
{
$testConfig | Write-Host
if ($testConfig -contains 'Type')
{
$testType = $testConfig.Type
}
else
{
$testType = 'TAEF'
}

$id = $baseId + "-Test$count"
$t = [PSCustomObject]@{}
$t | Add-Member -MemberType NoteProperty -Name 'Test' -Value $id
$t | Add-Member -MemberType NoteProperty -Name 'Description' -Value $testConfig.Description
$t | Add-Member -MemberType NoteProperty -Name 'Filename' -Value $testConfig.Filename
$t | Add-Member -MemberType NoteProperty -Name 'Parameters' -Value $testConfig.Parameters
$t | Add-Member -MemberType NoteProperty -Name 'Architectures' -Value $testConfig.Architectures
$t | Add-Member -MemberType NoteProperty -Name 'Status' -Value $testConfig.Status
$t | Add-Member -MemberType NoteProperty -Name 'TestDef' -Value $testDefFile.FullName
$t | Add-Member -MemberType NoteProperty -Name 'Type' -Value $testType

$tests += $t
$count += 1
}

$tests
}

function List-Tests
{
param($testDefFile)

$tests = Get-Tests $testDefFile
Write-Host "Tests in $($testDefFile.Name):"
$tests | Sort-Object -Property Test | Format-Table Test,Description,Type,Filename,Parameters,Architectures,Status -AutoSize | Out-String -Width 512
}

function Run-TaefTest
{
param($test)

$testFolder = Split-Path -parent $test.TestDef
$tePath = Join-Path $testFolder "te.exe"
$dllFile = Join-Path $testFolder $test.Filename

& $tePath $dllFile $test.Parameters
}

function Run-Tests
{
param($testDefFile)

$tests = Get-Tests $testDefFile
Write-Host "Running tests from $($testDefFile.Name)..."

foreach ($test in $tests)
{
Write-Host ""
Write-Host "$($test.Filename) - $($test.Description)"
Write-Host ""

$validPlatform = $test.Architectures.Contains($Platform)
$testEnabled = $test.Status -eq "Enabled"

if ($validPlatform -and ($testEnabled -or $RunDisabled))
{
Write-Host "Running test for platform $Platform..."
if ($test.Type -eq 'TAEF')
{
Run-TaefTest $test
}
elseif ($test.Type -eq 'Powershell')
{
Write-Host "Powershell tests not supported."
Exit 1
}
else
{
Write-Host "Unknown test type '$($test.Type)'. Not running."
Exit 1
}
}
elseif (-not($validPlatform))
{
Write-Host "$Platform not listed in supported architectures: $($test.Architectures -join ', ')"
}
elseif (-not($testEnabled))
{
Write-Host "Test is disabled. Not running."
}
}
}

if ($Platform -eq "AMD64")
{
$Platform = "x64"
}

$scriptParent = Split-Path -parent $PSScriptRoot

Write-Host "Building tests from testdef: $TestDef"

$VCToolsInstallDir = . "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" -latest -prerelease -requires Microsoft.Component.MSBuild -property installationPath
Write-Host "VCToolsInstallDir: $VCToolsInstallDir"

$msbuildPath = Join-Path $VCToolsInstallDir "MSBuild\Current\Bin\msbuild.exe"
Write-Host "MSBuild Path: $msbuildPath"

$testsSourceFolder = Join-Path $scriptParent "test"
Write-Host "Tests source folder: $testsSourceFolder"

$sourceTestDefFile = Find-TestDefFile $TestDef $testsSourceFolder

Build-Tests $sourceTestDefFile $msbuildPath

Write-Host ""
Write-Host "RunTests.ps1 - Running tests for testdef: $TestDef"
Write-Host "Configuration: $Configuration, Platform: $Platform"
Write-Host ""


$StartTime = Get-Date

# Find the testdef file
$configPlat = Join-Path $Configuration $Platform
$outputFolder = Join-Path $scriptParent $Output

$testDefFile = Find-TestDefFile $TestDef $outputFolder

List-Tests $testDefFile
Run-Tests $testDefFile

$TotalTime = (Get-Date)-$StartTime
$TotalMinutes = $TotalTime.Minutes
$TotalSeconds = $TotalTime.Seconds
Write-Host ""
Write-Host "Total Running Time: $TotalMinutes minutes and $TotalSeconds seconds"