使用 FLAUI 等待应用程序启动而不使用 Thread.Sleep()
Wait for application launch without using Thread.Sleep() using FLAUI
我刚开始使用 FLAUI 和自动化测试,想用它来测试我的系统。目前我正在使用 Thread.Sleep() 等待应用程序启动然后找到登录文本框。有没有比使用 Thread.Sleep() 更有效的方法来做到这一点?
目前我启动应用程序并使用 Thread.sleep(10000) 等到应用程序完全启动并且可以找到登录文本框,然后单击控件输入密码以进入应用。但是我知道 Thread.Sleep 是告诉系统等待的最糟糕的方式,尤其是在自动化测试中。谁能提供任何其他我可以测试的东西?
您尝试过 this 解决方案吗?
public static void LaunchApplication(string exePath, string arguments, bool waitForExit, bool waitForStart, int waitForStartTimeout)
{
ProcessStartInfo thisProcessInfo = new ProcessStartInfo();
thisProcessInfo.CreateNoWindow = true;
thisProcessInfo.UseShellExecute = false;
thisProcessInfo.RedirectStandardOutput = false;
thisProcessInfo.FileName = exePath;
thisProcessInfo.Arguments = arguments;
using(Process thisProcess = Process.Start(thisProcessInfo))
{
if(waitForStart)
thisProcess.WaitForInputIdle(waitForStartTimeout);
if(waitForExit)
thisProcess.WaitForExit();
}
}
private void RunProc()
{
Process.Start("exeName");
}
public async Task StartProcessAsync()
{
var result= await Task.Run(()=>RunProc());
//optional
Task.Delay(new TimeSpan.FromSeconds(5));
}
始终最好使用重试机制并等到您的主要 window 加载和控件可见。例如,在调用 Application.Launch 后,您最多可以重试 30 秒,以找到 main window 和其中的 txtLogin:
Retry.WhileException(() =>
{
using (var automation = new UIA3Automation())
{
Window mainWindow = Application.GetMainWindow(automation, TimeSpan.FromSeconds(60));
Assert.IsNotNull(Mainwindow, "Main window is not found");
TextBox loginTextBox = mainWindow.FindFirstDescendant(x => x.ByAutomationId("txtLogin")).AsTextBox();
Assert.IsNotNull(loginTextBox, "txtLogin is not found");
}
}, TimeSpan.FromSeconds(30), null, true);
这个问题已经有了很好的答案,但我找到了另一种方法来等待任何元素(包括 main window),使用 FlaUI.Core.Tools.Retry class 中的 Retry class
[TestFixture]
public class SmokeTests
{
private Application _theApp;
private UIA3Automation _automation;
private Window _mainWindow;
private const int BigWaitTimeout = 3000;
private const int SmallWaitTimeout = 1000;
[SetUp]
public void Setup()
{
_theApp = FlaUI.Core.Application.Launch(new ProcessStartInfo("YOUR_APPLICATION.exe", "/quickStart"));
_automation = new UIA3Automation();
_mainWindow = _theApp.GetMainWindow(_automation);
}
[TearDown]
public void Teardown()
{
_automation?.Dispose();
_theApp?.Close();
}
[Test]
public void Foo()
{
// This will wait until the element is available, or timeout passed
var examplesWrapPanel = WaitForElement(() => _mainWindow.FindFirstDescendant(cf => cf.ByAutomationId("ExamplesWrapPanel")));
// This will wait for the child element or timeout
var exampleButton = WaitForElement(() => examplesWrapPanel?.FindFirstDescendant(cf => cf.ByAutomationId("Another Automation Id")).AsButton());
// Do something with your elements
exampleButton?.WaitUntilClickable();
exampleButton?.Invoke();
}
private T WaitForElement<T>(Func<T> getter)
{
var retry = Retry.WhileNull<T>(
() => getter(),
TimeSpan.FromMilliseconds(BigWaitTimeout));
if (!retry.Success)
{
Assert.Fail("Failed to get an element within a wait timeout");
}
return retry.Result;
}
}
}
我刚开始使用 FLAUI 和自动化测试,想用它来测试我的系统。目前我正在使用 Thread.Sleep() 等待应用程序启动然后找到登录文本框。有没有比使用 Thread.Sleep() 更有效的方法来做到这一点?
目前我启动应用程序并使用 Thread.sleep(10000) 等到应用程序完全启动并且可以找到登录文本框,然后单击控件输入密码以进入应用。但是我知道 Thread.Sleep 是告诉系统等待的最糟糕的方式,尤其是在自动化测试中。谁能提供任何其他我可以测试的东西?
您尝试过 this 解决方案吗?
public static void LaunchApplication(string exePath, string arguments, bool waitForExit, bool waitForStart, int waitForStartTimeout)
{
ProcessStartInfo thisProcessInfo = new ProcessStartInfo();
thisProcessInfo.CreateNoWindow = true;
thisProcessInfo.UseShellExecute = false;
thisProcessInfo.RedirectStandardOutput = false;
thisProcessInfo.FileName = exePath;
thisProcessInfo.Arguments = arguments;
using(Process thisProcess = Process.Start(thisProcessInfo))
{
if(waitForStart)
thisProcess.WaitForInputIdle(waitForStartTimeout);
if(waitForExit)
thisProcess.WaitForExit();
}
}
private void RunProc()
{
Process.Start("exeName");
}
public async Task StartProcessAsync()
{
var result= await Task.Run(()=>RunProc());
//optional
Task.Delay(new TimeSpan.FromSeconds(5));
}
始终最好使用重试机制并等到您的主要 window 加载和控件可见。例如,在调用 Application.Launch 后,您最多可以重试 30 秒,以找到 main window 和其中的 txtLogin:
Retry.WhileException(() =>
{
using (var automation = new UIA3Automation())
{
Window mainWindow = Application.GetMainWindow(automation, TimeSpan.FromSeconds(60));
Assert.IsNotNull(Mainwindow, "Main window is not found");
TextBox loginTextBox = mainWindow.FindFirstDescendant(x => x.ByAutomationId("txtLogin")).AsTextBox();
Assert.IsNotNull(loginTextBox, "txtLogin is not found");
}
}, TimeSpan.FromSeconds(30), null, true);
这个问题已经有了很好的答案,但我找到了另一种方法来等待任何元素(包括 main window),使用 FlaUI.Core.Tools.Retry class 中的 Retry class
[TestFixture]
public class SmokeTests
{
private Application _theApp;
private UIA3Automation _automation;
private Window _mainWindow;
private const int BigWaitTimeout = 3000;
private const int SmallWaitTimeout = 1000;
[SetUp]
public void Setup()
{
_theApp = FlaUI.Core.Application.Launch(new ProcessStartInfo("YOUR_APPLICATION.exe", "/quickStart"));
_automation = new UIA3Automation();
_mainWindow = _theApp.GetMainWindow(_automation);
}
[TearDown]
public void Teardown()
{
_automation?.Dispose();
_theApp?.Close();
}
[Test]
public void Foo()
{
// This will wait until the element is available, or timeout passed
var examplesWrapPanel = WaitForElement(() => _mainWindow.FindFirstDescendant(cf => cf.ByAutomationId("ExamplesWrapPanel")));
// This will wait for the child element or timeout
var exampleButton = WaitForElement(() => examplesWrapPanel?.FindFirstDescendant(cf => cf.ByAutomationId("Another Automation Id")).AsButton());
// Do something with your elements
exampleButton?.WaitUntilClickable();
exampleButton?.Invoke();
}
private T WaitForElement<T>(Func<T> getter)
{
var retry = Retry.WhileNull<T>(
() => getter(),
TimeSpan.FromMilliseconds(BigWaitTimeout));
if (!retry.Success)
{
Assert.Fail("Failed to get an element within a wait timeout");
}
return retry.Result;
}
}
}