Puede hacer un poco de "trabajo manual" para obtener el resultado utilizando expresiones regulares en powershell.
El ejemplo es con XUnit. entonces lo que tienes que hacer es almacenar el resultado de dotnet test project.csproj
en una variable. entonces un ejemplo será como el siguiente
Test run for C:\Users\Tigrex\source\repos\ConsoleApp1\XUnitTestProject1\bin\Debug\netcoreapp2.2\XUnitTestProject1.dll(.NETCoreApp,Version=v2.2) Microsoft (R) Test Execution Command Line Tool Version 16.3.0 Copyright (c) Microsoft Corporation. All rights reserved. Starting test execution, please wait... A total of 1 test files matched the specified pattern. X XUnitTestProject1.UnitTest1.ThisIsAnotherFailedTestYesAgain [11ms] Error Message: Assert.Equal() Failure Expected: 2 Actual: 1 Stack Trace: at XUnitTestProject1.UnitTest1.ThisIsAnotherFailedTestYesAgain() in C:\Users\Tigrex\source\repos\ConsoleApp1\XUnitTestProject1\UnitTest1.cs:line 33 X XUnitTestProject1.UnitTest1.ThisIsAnotherFAiledTest [1ms] Error Message: Assert.Equal() Failure Expected: 2 Actual: 1 Stack Trace: at XUnitTestProject1.UnitTest1.ThisIsAnotherFAiledTest() in C:\Users\Tigrex\source\repos\ConsoleApp1\XUnitTestProject1\UnitTest1.cs:line 22 X XUnitTestProject1.UnitTest1.TestToFail [1ms] Error Message: Assert.Equal() Failure Expected: 2 Actual: 1 Stack Trace: at XUnitTestProject1.UnitTest1.TestToFail() in C:\Users\Tigrex\source\repos\ConsoleApp1\XUnitTestProject1\UnitTest1.cs:line 16 Total tests: 5 Passed: 2 Failed: 3 Total time: 1.2764 Seconds
Como puede ver, hay algunos patrones comunes que principalmente le Error Message
dan la pista de saber dónde buscar, en este caso, xUnit indica los errores porX testname [{time}ms] Error Message
si hace coincidir ese texto con una expresión regular, puede obtener la respuesta deseada: utilicé esta: X\s*(\S*)\s\[\d*ms\]\s*Error Message
estoy seguro de que se puede mejorar (no soy un maestro en expresiones regulares ) pero hace su trabajo. puedes eliminar Error Message
por ejemplo. de todos modos, sigo adelante.
una vez que coincida con el resultado, solo necesita obtener el grupo para cada resultado, que en este caso lo almacené TestName
. y llama aldotnet test ...
$result = dotnet test XUnitTestProject1/XUnitTestProject1.csproj
$regex = 'X\s*(?<TestName>\S*)\s\[\d*ms\]\s*'
$matches = [regex]::Matches($result, $regex)
Foreach ($failedTest IN $matches)
{
$failedTestName = $failedTest.Groups['TestName'].Value
dotnet test --filter "FullyQualifiedName=$failedTestName"
}
esta línea $failedTestName = $failedTest.Groups['TestName'].Value
es necesaria, si intenta pasar .Groups..
la FullyQualifiedName
cadena, PowerShell las entiende como una cadena literal.
debes hacer lo mismo para calcular los tiempos y el porcentaje.
También para la primera iteración es más fácil porque puedes ejecutar todas las pruebas de una vez, pero desde la segunda y lejos no puedes. es necesaria la lista necesaria (para mantener las pruebas que están fallando).
algo como esto hará el trabajo.
$times = 1
$result = dotnet test XUnitTestProject1/XUnitTestProject1.csproj
$regexFailedtests = 'X\s*(?<TestName>\S*)\s\[\d*ms\]\s*'
$FailedTestMatches = [regex]::Matches($result, $regexFailedtests)
$totalTestExecutedRegex = 'Total tests:\s*(?<TotalTest>\d*)'
$totalTests = [regex]::Matches($result, $totalTestExecutedRegex)[0].Groups['TotalTest'].Value -as [int]
$totalTesPassedRegex = 'Passed:\s*(?<Passed>\d*)'
$totalTestsPassed = [regex]::Matches($result, $totalTesPassedRegex)[0].Groups['Passed'].Value -as [int]
#convert the failed test into a list of string, so it can be looped.
$listFailedTest = New-Object Collections.Generic.List[string]
Foreach ($failedTest IN $FailedTestMatches)
{
$failedTestName = $failedTest.Groups['TestName'].Value
$listFailedTest.Add($failedTestName)
}
$percentage = ($totalTestsPassed*100)/$totalTests #Calculate the percentage
while($times -lt 5 -and $percentage -lt 70) {#5 loops or > 70% of test working
$listFailedTestInsideDo = New-Object Collections.Generic.List[string]
$listFailedTestInsideDo = $listFailedTest; #do a copy of the main list
$listFailedTest = New-Object Collections.Generic.List[string] ##empty the main list.
Foreach ($failedTestName IN $listFailedTestInsideDo)
{
$result2 = dotnet test --filter "FullyQualifiedName=$failedTestName"
if($result2 -match'Passed:\s*\d*') #if contains passed then it worked
{
totalTestsPassed++
}else{
$listFailedTest.Add($failedTestName) #add in new List for the new loop
}
}
$percentage = ($totalTestsPassed*100)/$totalTests
$times++
}