Powershell NUnit控制台在通过Octopus/Powershell测试后似乎挂起了(Chrome驱动程序仍



在部署Octopus管道的步骤中运行PowerShell脚本时,我似乎遇到了问题。测试针对几个网站运行,每个网站都有一系列测试。这些只是我们环境中本地设置的网站。

测试次数最多的网站有大约100次测试,最小的网站大约有5次。该问题可能发生在5或100的网站上。这些是SpecFlow测试。

然后将结果导出到一个xml文件中。根据xml文件,它看起来确实运行了所有的测试,因为它显示了成功和失败的测试。这个问题似乎并不总是发生。尽管如果我把它留在夜间构建中,就会发生这种情况。如果我在章鱼上触发手动构建,它不会总是发生。

NUnit的版本是3.1.1

到目前为止,这是我在powershell中为NUnit控制台传递的一行示例。

param(
[string]$configurationDescription = $OctopusParameters['environment.Transform'] + " Env Test Run", 
[string]$site,
[string]$environmentName,
[string]$environmentSiteTag,
[string]$testDllName,
[string]$testDllFolder
)
$folderPath = $OctopusParameters['tests.rootFolder']
Set-Location $folderPath
$configurationDescription = $configurationDescription.Replace(" ", "-")
$testResultsFolderName = "testResults"
$testResultsPath = "$folderPath$testResultsFolderName$site"
$currentTimeFormatted = Get-Date -Format "dd-MM-yyyy_hh_mm_ss"
if(!(Test-Path -Path $testResultsPath))
{
New-Item -Path $testResultsPath -ItemType Directory
}
$testDllPath = $folderPath + "tests$testDllFolder$testDllName"
$environmentWipTag = $OctopusParameters["tests.environment.wipname"]
#Change the location of "binXXX" So it will pick up the respective dll file and use the respective App.XXX.config
$testResultsXmlPath = "$testResultsPathTestResult_$currentTimeFormatted.xml"
$args = "$testDllPath --where `"cat != $environmentWipTag && (cat == $environmentName && cat == $environmentSiteTag)`" --result=$testResultsXmlPath --framework=net-4.0 --timeout=20000"

# SECTION: Update Chrome driver
# Update Chrome Driver for testing to match the machine.
#1. Get the version of Chrome driver installed.
$chromeDriverOutputPath = $folderPath + "tests$testDllFolder"
# Store original preference to revert back later
$OriginalProgressPreference = $ProgressPreference;
# Increases the performance of downloading the ChromeDriver.
$ProgressPreference = 'SilentlyContinue';
try
{
$chromeVersion = (Get-Item (Get-ItemProperty 'HKLM:SOFTWAREMicrosoftWindowsCurrentVersionApp Pathschrome.exe').'(Default)').VersionInfo.FileVersion
$chromeVersion = $chromeVersion.Substring(0, $chromeVersion.LastIndexOf("."));
} catch
{
"Could not find Google Chrome in the registry."
}
#2. Get the latest version of chrome driver available.
$chromeDriverVersion = (Invoke-WebRequest "https://chromedriver.storage.googleapis.com/LATEST_RELEASE_$chromeVersion" -UseBasicParsing).Content;
Write-Host "Latest matching version of Chrome Driver is $chromeDriverVersion";
#3.Create a temp folder to store the chrome driver to be downloaded.
$tempFilePath = [System.IO.Path]::GetTempFileName();
$tempZipFilePath = $tempFilePath.Replace(".tmp", ".zip");
Rename-Item -Path $tempFilePath -NewName $tempZipFilePath;
$tempFileUnzipPath = $tempFilePath.Replace(".tmp", "");
# 4. Download correct chrome drive, unzip the archive and move the chromedriver to the correct location.
Invoke-WebRequest "https://chromedriver.storage.googleapis.com/$chromeDriverVersion/chromedriver_win32.zip" -OutFile $tempZipFilePath -UseBasicParsing;
Expand-Archive $tempZipFilePath -DestinationPath $tempFileUnzipPath;
Move-Item "$tempFileUnzipPath/chromedriver.exe" -Destination $chromeDriverOutputPath -Force; 
# 5. Clean up files.
Remove-Item $tempZipFilePath;
Remove-Item $tempFileUnzipPath -Recurse;
# Set back to default ProgressPreference.
$ProgressPreference = $OriginalProgressPreference
#END SECTION: Update Chrome driver
Write-Host "Chrome Driver now matches the version installed on the machine. Beginning Test run."
#Begin Test Run.
$nunitRunnerResult = (Start-Process -FilePath "$folderPathrunnernunit3-console.exe" -ArgumentList $args -PassThru -Wait).ExitCode
if(!(Test-Path -Path $testResultsXmlPath))
{
Write-Host "Args:$args FilePath:$folderPathrunnernunit3-console.exe"
Write-Error "Unable to find $testResultsXmlPath"
return;
}
$testsTestResultHtmlPagePath = "$testResultsPath$configurationDescription-$currentTimeFormattedExtentReport"
$args = "-i $testResultsXmlPath -o $testsTestResultHtmlPagePath -r html"
Start-Process -FilePath "$folderPathextentreportextent.exe" -ArgumentList $args -Wait
$extentReportPath = $testsTestResultHtmlPagePath + "index.html"
$extentSummaryPath =  $testsTestResultHtmlPagePath + "dashboard.html"
$testsTestResultPath = "$testResultsFolderNametestsTestResult-$currentTimeFormatted.xml"
$args = [string]::Format("-f=Features/ -o=$testResultsFolderName/{0}-{1}/PicklesReport -trfmt=nunit3 -df=dhtml -lr={2}", $configurationDescription, $currentTimeFormatted, $testsTestResultPath)

Exit 0

C#在每次测试后运行。

using BoDi;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System;
using System.Configuration;
using TechTalk.SpecFlow;
namespace MyTestFramework.Helpers
{
[Binding]
public sealed class Hooks
{
private readonly IObjectContainer _container;
private IWebDriver _webDriver = default;
public Hooks(IObjectContainer objectContainer)
{
_container = objectContainer;
}
[BeforeScenario]
public void BeforeTestRun()
{
InstantiateDriver();
}
[AfterScenario]
public void AfterScenario()
{
if (!(_webDriver is null))
{
//Close any additional tabs open and then delete all cookies when one tab is open
var tabs = _webDriver.WindowHandles;
int numberOfTabs = _webDriver.WindowHandles.Count;
while (numberOfTabs > 1)
{
_webDriver.SwitchTo().Window(tabs[numberOfTabs - 1]);
_webDriver.Close();
numberOfTabs = _webDriver.WindowHandles.Count;
_webDriver.SwitchTo().Window(tabs[numberOfTabs - 1]);
}
_webDriver.Manage().Cookies.DeleteAllCookies();
_webDriver.Close();
_webDriver.Quit();
_webDriver.Dispose();
}
}
[AfterTestRun]
public static void After()
{
}
private void InstantiateDriver()
{
var selectedDriver = ConfigurationManager.AppSettings.Get("selectedWebDriver");
if (string.IsNullOrEmpty(selectedDriver))
{
throw new ArgumentException(Constants.ExceptionMessages.SelectedWebdriverCouldNotBeFound, selectedDriver);
}
switch (selectedDriver)
{
case "Chrome":
_webDriver = new ChromeDriver();
break;
case "Chrome Headless":
var chromeOption = new ChromeOptions();
chromeOption.AddArguments("headless");
chromeOption.AddArguments("--window-size=1680,1050");
_webDriver = new ChromeDriver(chromeOption);
break;
default:
throw new ArgumentException("Webdriver could not be found", selectedDriver);
}
_webDriver.Manage().Window.Maximize();
_container.RegisterInstanceAs<IWebDriver>(_webDriver);
}
}
}

如果我关闭镀铬驱动器,它必须关闭所有东西,因为章鱼的步骤似乎失败了。同样值得注意的是,如果直接使用visualstudio,则不会发生这种情况。

更改-Wait-WaitProcess成功并修复了问题。

$testResults = (Start-Process -FilePath "$folderPathrunnernunit3-console.exe" -ArgumentList $args -PassThru)

Wait-Process -Id $testResults.Id $testExitCode = $testResults.ExitCode

@Greg Burghardt,你对僵尸进程的看法是对的,所以出于某种原因,我最终看了一下-等待的论点。我注意到还有另一个PowerShell参数名为-WaitProcess。在这种情况下似乎有区别。

与启动进程-等待不同,等待进程只等待已识别的进程。启动进程-等待进程树(进程及其所有子进程(,以便在返回控制之前退出

来源:https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.management/wait-process?view=powershell-7.2

我怀疑,由于这些chrome进程有时并没有真正结束,即使主进程已经结束,它也在等待所有其他进程退出。这将解释为什么我通过任务管理器手动关闭了所有进程,以便它在等待子进程结束时提前继续。

最新更新