使用 UI Automation 实现自动化测试--4.3

来源:互联网 发布:java maven 命令 编辑:程序博客网 时间:2024/05/23 10:17
InvokePattern

InvokePattern是UIA中最常用的Pattern之一,WPF和Winform中的button控件都支持InvokePattern。

对InvokePattern的Invoke()方法的调用应立即返回,没有出现阻止情况。但是,此行为完全依赖于 Microsoft UI 自动化提供程序实现。在调用 Invoke() 会引起阻止问题(如Winform中的模式对话框,但是WPF中的对话框的处理方式和winform不同,所以可以使用Invoke()方法来操作WPF中的模式对话框,因为WPF中的模式对话框不会出现阻止的问题)的情况下,要调用此方法,则需要另起线程来操作。
  1. using System;
  2. using System.Text;
  3. using System.Diagnostics;
  4. using System.Threading;
  5. using System.Windows.Automation;

  6. namespace UIATest
  7. {
  8.     class Program
  9.     {
  10.         static void Main(string[] args)
  11.         {
  12.             Process process = Process.Start(@"F:\CSharpDotNet\AutomationTest\ATP\WpfApp\bin\Debug\WpfApp.exe");
  13.             int processId = process.Id;
  14.             AutomationElement element = FindElementById(processId, "button1");
  15.             InvokePattern currentPattern = GetInvokePattern(element);
  16.             currentPattern.Invoke();
  17.         }

  18.         /// <summary>
  19.         /// Get the automation elemention of current form.
  20.         /// </summary>
  21.         /// <param name="processId">Process Id</param>
  22.         /// <returns>Target element</returns>
  23.         public static AutomationElement FindWindowByProcessId(int processId)
  24.         {
  25.             AutomationElement targetWindow = null;
  26.             int count = 0;
  27.             try
  28.             {
  29.                 Process p = Process.GetProcessById(processId);
  30.                 targetWindow = AutomationElement.FromHandle(p.MainWindowHandle);
  31.                 return targetWindow;
  32.             }
  33.             catch (Exception ex)
  34.             {
  35.                 count++;
  36.                 StringBuilder sb = new StringBuilder();
  37.                 string message = sb.AppendLine(string.Format("Target window is not existing.try #{0}", count)).ToString();
  38.                 if (count > 5)
  39.                 {
  40.                     throw new InvalidProgramException(message, ex);
  41.                 }
  42.                 else
  43.                 {
  44.                     return FindWindowByProcessId(processId);
  45.                 }
  46.             }
  47.         }


  48.         /// <summary>
  49.         /// Get the automation element by automation Id.
  50.         /// </summary>
  51.         /// <param name="windowName">Window name</param>
  52.         /// <param name="automationId">Control automation Id</param>
  53.         /// <returns>Automatin element searched by automation Id</returns>
  54.         public static AutomationElement FindElementById(int processId, string automationId)
  55.         {
  56.             AutomationElement aeForm = FindWindowByProcessId(processId);
  57.             AutomationElement tarFindElement = aeForm.FindFirst(TreeScope.Descendants,
  58.             new PropertyCondition(AutomationElement.AutomationIdProperty, automationId));
  59.             return tarFindElement;
  60.         }

  61.         #region InvokePattern helper
  62.         /// <summary>
  63.         /// Get InvokePattern
  64.         /// </summary>
  65.         /// <param name="element">AutomationElement instance</param>
  66.         /// <returns>InvokePattern instance</returns>
  67.         public static InvokePattern GetInvokePattern(AutomationElement element)
  68.         {
  69.             object currentPattern;
  70.             if (!element.TryGetCurrentPattern(InvokePattern.Pattern, out currentPattern))
  71.             {
  72.                 throw new Exception(string.Format("Element with AutomationId '{0}' and Name '{1}' does not support the InvokePattern.",
  73.                     element.Current.AutomationId, element.Current.Name));
  74.             }
  75.             return currentPattern as InvokePattern;
  76.         }

  77.         #endregion
  78.     }
  79. }



被测程序xaml代码如下:

  1. <Window x:Class="WpfApp.Window1"
  2.     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.     Title="Window1" Height="219" Width="353">
  5.     <Grid>
  6.         <Button Height="23" HorizontalAlignment="Left" Click="button1_Click" Margin="50,0,0,62" Name="button1" VerticalAlignment="Bottom" Width="75">Button</Button>
  7.     </Grid>
  8. </Window>
复制代码
对应的cs文件:
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Windows;
  6. using System.Windows.Controls;
  7. using System.Windows.Data;
  8. using System.Windows.Documents;
  9. using System.Windows.Input;
  10. using System.Windows.Media;
  11. using System.Windows.Media.Imaging;
  12. using System.Windows.Navigation;
  13. using System.Windows.Shapes;

  14. namespace WpfApp
  15. {
  16.     /// <summary>
  17.     /// Interaction logic for Window1.xaml
  18.     /// </summary>
  19.     public partial class Window1 : Window
  20.     {
  21.         public Window1()
  22.         {
  23.             InitializeComponent();
  24.         }

  25.         private void button1_Click(object sender, RoutedEventArgs e)
  26.         {
  27.             MessageBox.Show("Use InvokePattern invoke button.");
  28.         }
  29.     }
  30. }
复制代码
本文主要针对InvokePattern的Invoke方法来操作button控件。(文/开着拖拉机
0 0