编码的UI测试等待UI线程很慢 [英] Coded UI Test is slow waiting for UI thread
问题描述
我已经在Visual Studio 2013的ASP.NET MVC解决方案中添加了编码UI测试.在测试机器醒来并开始填写表单字段之前,每页最多要坐在那里一分钟或更长时间.
I've added Coded UI Tests to my ASP.NET MVC solution in Visual Studio 2013. I was dismayed to see how slowly the tests run; each page just sits there for up to a minute or more before the test machinery wakes up and starts filling in the form fields.
经过一些试验(包括关闭SmartMatch
),我发现只需调用
After some experimentation (including turning off SmartMatch
), I've discovered that simply calling
Playback.PlaybackSettings.WaitForReadyLevel = WaitForReadyLevel.Disabled;
解决了问题.但是,正如预期的那样,该测试经常失败,因为UI线程还没有准备好让测试机器与表单上的控件进行交互.
solves the problem. But, as expected, the test frequently fails because the UI thread isn't ready for the test machinery to interact with the controls on the form.
通话
Playback.PlaybackSettings.WaitForReadyLevel = WaitForReadyLevel.UIThreadOnly;
使测试运行可靠,即使速度很慢.
makes the test run reliably, if slowly.
有什么想法或建议吗?希望有人对"WaitForReady"机制中的魔术有所了解吗?除了WaitForReadyLevel
之外,我还有其他与WaitForReady相关的设置吗?
Any thoughts or suggestions? Any hope that someone might have some insight into the magic baked into the WaitForReady machinery? Are there any other settings related to WaitForReady that I can fiddle with besides WaitForReadyLevel
?
推荐答案
经过一些试验,我得出了似乎是设置组合的结果,这些设置可以使我的编码UI测试可靠地全速运行-比我手动与网站进行交互的速度更快.
After a bit of experimentation, I've worked out what appears to be a combination of settings that allows my Coded UI Tests to reliably run at full speed -- faster than I could interact with the website by hand.
注意:相关的文档"(如果您将博客称为文档")可以在以下位置找到:
Note: The relevant "documentation" (if you call a blog "documentation") can be found here:
- Playback configuration settings
- Retrying failed playback actions.
该技巧需要对默认播放设置进行一些修改:
The trick requires several modifications to the default playback settings:
-
设置
WaitForReadyLevel = WaitForReadyLevel.Disabled
可使测试全速运行.但是,它也禁用了(慢!)魔术,该魔术一直等待直到可以安全地与页面上的控件进行交互.
Setting
WaitForReadyLevel = WaitForReadyLevel.Disabled
allows the test to run at full speed. But it also disables the (slow!) magic that waits until it's safe to interact with controls on the page.
设置MaximumRetryCount
并附加错误处理程序可处理由于禁用等待就绪"魔术而导致的大多数错误.因为我已经将1秒Sleep
放入重试逻辑,所以该值实际上是我愿意等待页面加载并响应的秒数.
Setting a MaximumRetryCount
and attaching an error handler deals with most of the errors that result from disabling the "wait for ready" magic. Because I've baked a 1 second Sleep
into the retry logic, this value is effectively the number of seconds I'm willing to wait for the page to load and become responsive.
显然,未能找到被测控件不是错误处理程序/重试机制处理的错误之一.如果新页面的加载时间超过几秒钟,并且测试正在寻找直到新页面加载才存在的控件,则该测试将找不到该控件,并且该测试将失败.设置ShouldSearchFailFast = false
可以为您提供页面加载的完整超时时间,从而解决了该问题.
Apparently, failure to find the control under test is not one of the errors handled by the error handler/retry mechanism. If the new page takes more than a few seconds to load, and the test is looking for a control that doesn't exist until the new page loads, the test fails to find the control and the test fails. Setting ShouldSearchFailFast = false
solves that problem by giving you the full timeout time for your page to load.
设置DelayBetweenActions = 500
似乎可以解决一个问题,我偶尔会看到UI错过了页面加载后立即发生的按钮单击.测试设备似乎认为该按钮已被单击,但是网页没有响应.
Setting DelayBetweenActions = 500
appears to work around a problem that I see occasionally where the UI misses a button click that occurs immediately after a page has loaded. The test machinery seems to think that the button was clicked, but the web page doesn't respond to it.
文档"说默认搜索超时为3分钟,但实际上大于10分钟,因此我将SearchTimeout
显式设置为1秒(1000毫秒).
The "documentation" says that the default search timeout is 3 minutes, but it's actually something greater than 10 minutes, so I explicitly set SearchTimeout
to 1 second (1000 ms).
为了将所有代码都放在一个地方,我创建了一个类,其中包含所有测试使用的代码.我的每个测试类中的[TestInitialize]
方法都调用了MyCodedUITests.StartTest()
.
To keep all of the code in one place, I've created a class that contains code used by all of the tests. MyCodedUITests.StartTest()
is called by the [TestInitialize]
method in each of my test classes.
对于所有测试,该代码实际上应该只执行一次(而不是每个测试一次),但是我想不出一种方法来使Playback.PlaybackSettings
调用在[AssemblyInitialization]
或
This code really should be executed only once for all of the tests (rather than once per test), but I couldn't figure out a way to get the Playback.PlaybackSettings
calls to work in the [AssemblyInitialization]
or [ClassInitialization]
routines.
/// <summary> A class containing Coded UI Tests. </summary>
[CodedUITest]
public class UI_Tests
{
/// <summary> Common initialization for all of the tests in this class. </summary>
[TestInitialize]
public void TestInit()
{
// Call a common routine to set up the test
MyCodedUITests.StartTest();
}
/// <summary> Some test. </summary>
[TestMethod]
public void SomeTest()
{
this.UIMap.Assert_HomePageElements();
this.UIMap.Recorded_DoSomething();
this.UIMap.Assert_FinalPageElements();
}
}
/// <summary> Coded UI Test support routines. </summary>
class MyCodedUITests
{
/// <summary> Test startup. </summary>
public static void StartTest()
{
// Configure the playback engine
Playback.PlaybackSettings.WaitForReadyLevel = WaitForReadyLevel.Disabled;
Playback.PlaybackSettings.MaximumRetryCount = 10;
Playback.PlaybackSettings.ShouldSearchFailFast = false;
Playback.PlaybackSettings.DelayBetweenActions = 500;
Playback.PlaybackSettings.SearchTimeout = 1000;
// Add the error handler
Playback.PlaybackError -= Playback_PlaybackError; // Remove the handler if it's already added
Playback.PlaybackError += Playback_PlaybackError; // Ta dah...
}
/// <summary> PlaybackError event handler. </summary>
private static void Playback_PlaybackError(object sender, PlaybackErrorEventArgs e)
{
// Wait a second
System.Threading.Thread.Sleep(1000);
// Retry the failed test operation
e.Result = PlaybackErrorOptions.Retry;
}
}
这篇关于编码的UI测试等待UI线程很慢的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!