我正尝试通过UI自动化(主要使用 TestStack.White
提供友好的界面; 它使用 System.Windows.Automation
作为后端)对我的应用程序进行自动化测试。 我有一个包含~200行的表格需要测试值(实际上我只想测试前几行和最后几行)。 我已经发现,仅使用COM-interop UIAutomationCore,可以在几秒钟内枚举行,但前提是我不使用White或 System.Windows.Automation
。 一旦 System.Windows.Automation
初始化,未来用于枚举行的UI自动化操作就会变慢:
First COM run: it took 0.04 seconds to get 102 rows!
First System.Windows.Automation run: it took 7.18 seconds to get 102 rows!
Second COM run: it took 7.87 seconds to get 102 rows!
我创建了一个简单的WinForms测试应用程序(TableTest.exe
),以验证它与我的应用程序无关,而是与System.Windows.Automation
有关:
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var form = new Form() { Text = "TableTest", WindowState = FormWindowState.Maximized };
var dgv = new DataGridView() { Name = "DGV", Dock = DockStyle.Fill, AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill };
dgv.Columns.Add("i", "i");
dgv.Columns.Add("2i", "2i");
dgv.Columns.Add("i^2", "i^2");
dgv.Columns.Add("i^i", "i^i");
for (int i = 0; i < 100; ++i)
dgv.Rows.Add(i, i * 2, i * i, Math.Pow(i, i));
form.Controls.Add(dgv);
Application.Run(form);
}
然后我创建了另一个测试应用程序来测试第一个应用程序。它可以作为控制台应用程序或WinForms应用程序运行。首先我使用COM自动化进行测试,然后使用System.Windows.Automation进行测试,最后再次使用COM自动化进行测试。正如您从上面引述的输出中所看到的那样,第一个块执行非常快,接下来的两个块执行非常缓慢。如果我注释掉System.Windows.Automation
代码块,那么两个COM块都会快速执行。
using UIA = Interop.UIAutomationCore;
static void Main(string[] args)
{
var process = System.Diagnostics.Process.Start("TableTest.exe");
System.Threading.Thread.Sleep(500);
var uia = new UIA.CUIAutomation();
var rootCom = uia.GetRootElement();
var windowCom = rootCom.FindFirst(UIA.TreeScope.TreeScope_Children, uia.CreatePropertyCondition(UIA.UIA_PropertyIds.UIA_NamePropertyId, "TableTest"));
var dgvCom = windowCom.FindFirst(UIA.TreeScope.TreeScope_Descendants, uia.CreatePropertyCondition(UIA.UIA_PropertyIds.UIA_AutomationIdPropertyId, "DGV"));
var start = DateTime.Now;
var rowCount = dgvCom.FindAll(UIA.TreeScope.TreeScope_Children, uia.CreatePropertyCondition(UIA.UIA_PropertyIds.UIA_ControlTypePropertyId, UIA.UIA_ControlTypeIds.UIA_CustomControlTypeId)).Length;
var elapsed = (DateTime.Now - start).TotalSeconds;
Console.WriteLine(String.Format("It took {0} seconds to get {1} rows!", elapsed.ToString("f2"), rowCount));
process.Kill();
process = System.Diagnostics.Process.Start("TableTest.exe");
System.Threading.Thread.Sleep(500);
var root = AutomationElement.RootElement;
var window = root.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.NameProperty, "TableTest"));
var dgv = window.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.AutomationIdProperty, "DGV"));
start = DateTime.Now;
rowCount = dgv.FindAll(TreeScope.Children, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Custom)).Count;
elapsed = (DateTime.Now - start).TotalSeconds;
Console.WriteLine(String.Format("It took {0} seconds to get {1} rows!", elapsed.ToString("f2"), rowCount));
process.Kill();
process = System.Diagnostics.Process.Start("TableTest.exe");
System.Threading.Thread.Sleep(500);
uia = new UIA.CUIAutomation();
rootCom = uia.GetRootElement();
windowCom = rootCom.FindFirst(UIA.TreeScope.TreeScope_Children, uia.CreatePropertyCondition(UIA.UIA_PropertyIds.UIA_NamePropertyId, "TableTest"));
dgvCom = windowCom.FindFirst(UIA.TreeScope.TreeScope_Descendants, uia.CreatePropertyCondition(UIA.UIA_PropertyIds.UIA_AutomationIdPropertyId, "DGV"));
start = DateTime.Now;
rowCount = dgvCom.FindAll(UIA.TreeScope.TreeScope_Children, uia.CreatePropertyCondition(UIA.UIA_PropertyIds.UIA_ControlTypePropertyId, UIA.UIA_ControlTypeIds.UIA_CustomControlTypeId)).Length;
elapsed = (DateTime.Now - start).TotalSeconds;
Console.WriteLine(String.Format("It took {0} seconds to get {1} rows!", elapsed.ToString("f2"), rowCount));
process.Kill();
}
究竟是什么让 System.Windows.Automation
影响了 UI 自动化的性能?我查看了 White 的源代码,但没有发现明显的问题。我无法对 System.Windows.Automation 进行性能分析,因为找不到任何 PDB 文件。我对 UI 自动化不是很熟悉,也许对其他人来说很明显。White 版本是:0.13.0.0
,我正在测试 64 位 Windows 7。
System.Windows.Automation
,并发现问题出在那里,而不是在使用 COM 接口的 White 上。也就是说,当使用System.Windows.Automation
时,第一行枚举与第二行一样慢。也许这有助于缩小问题范围? - Matt Chambers