Вы можете выполнить небольшую «ручную работу», чтобы получить результат с помощью регулярных выражений в powershell.
В примере используется XUnit. так что вам нужно сохранить результат dotnet test project.csproj
в переменной. таким образом, пример будет похож на следующий
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
, поскольку вы можете видеть, что есть некоторые общие модели, которые в основном Error Message
, которые дают вам подсказку, чтобы знать, где искать, в этом случае xUnit указывает ошибки на X testname [{time}ms] Error Message
, если вы сопоставите этот текст с регулярным выражением, вы можете получить желаемый ответ: я использовал этот: X\s*(\S*)\s\[\d*ms\]\s*Error Message
Я уверен, что это может быть улучшенный (я не мастер по регулярным выражениям), но он делает свою работу. вы можете удалить Error Message
например. в любом случае, я продолжаю.
как только вы сопоставите результат, вам нужно только получить группу для каждого результата, который в этом случае я сохранил в TestName
. и вызовите dotnet 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"
}
, эта строка $failedTestName = $failedTest.Groups['TestName'].Value
необходима, если вы попытаетесь передать .Groups..
в строку FullyQualifiedName
, PowerShell поймет их как строку литерала.
вам нужно сделать то же самое, чтобы рассчитать время и процент.
Также для первой итерации проще, потому что вы можете запустить все тесты за один go, но со второй и далеко вы не можете. так необходим необходимый список (чтобы сохранить неудачные тесты).
что-то вроде этого сделает работу.
$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++
}