zoukankan      html  css  js  c++  java
  • 21、uwp UI自动化测试(WinAppDriver)

    使用 UI自动化测试的好处就是在代码逻辑中写好 case 后,来实现 “一劳永逸” 的作用,并且自动化测试能够模拟人工达不到要求,比如快速切换页面、快速点击按钮等,对于提高软件的稳定性很有帮助。

    安装的软件:

    1、WinAppDriver

       github : https://github.com/microsoft/winappdriver

      上面有些 demo。Application Driver直接安装地址:https://github.com/Microsoft/WinAppDriver/releases

      安装完成后,默认在系统的:C:Program Files (x86)Windows Application DriverWinAppDriver.exe

      这个工具的作用是你写的测试工程,通过本地 localhost(127.0.0.1)以 json 方式与 WinAppDriver 进行通信,使 WinAppDriver调用 win32 api来模拟屏幕操作,如果鼠标点击、拖拽、触屏手势等,后续据说会支持 xbox 手柄、hololens 等操作。

    2、 inspect.exe

     这个工具是用来查看运行软件(uwp、win32、win form、wpf)的 UI 元素的 Name、ID、Text 等等。包含在 Windows SDK 中。

     安装完 Visual Studio2015后,可以在 C盘下找到:C:Program Files (x86)Windows Kits10inx64inspect.exe

     元素对照表:

    Client APILocator StrategyMatched AttributeExample
    FindElementByAccessibilityId accessibility id AutomationId AppNameTitle
    FindElementByClassName class name ClassName TextBlock
    FindElementById id RuntimeId (decimal) 42.333896.3.1
    FindElementByName name Name Calculator
    FindElementByTagName tag name LocalizedControlType (upper camel case) Text

    这里以爱奇艺uwp作为示例,大概描述一下使用方式:

    1、首先在启动 WinAppDriver.exe,运行界面:

      路径:C:Program Files (x86)Windows Application DriverWinAppDriver.exe

    如果不运行它的话,UI自动化工程在运行单元测试的时候,vs 会抛异常:

    /* 先启动 C:Program Files (x86)Windows Application DriverWinAppDriver.exe,否则会抛异常
      Unexpected error. System.Net.WebException: 无法连接到远程服务器 ---> System.Net.Sockets.SocketException: 由于目标计算机积极拒绝,无法连接。 127.0.0.1:4723
      在 System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
      在 System.Net.ServicePoint.ConnectSocketInternal(Boolean connectFailure, Socket s4, Socket s6, Socket& socket, IPAddress& address, ConnectSocketState state, IAsyncResult asyncResult, Exception& exception)
      --- 内部异常堆栈跟踪的结尾 ---
      在 OpenQA.Selenium.Appium.Service.AppiumCommandExecutor.Execute(Command commandToExecute)
      在 OpenQA.Selenium.Remote.RemoteWebDriver.Execute(String driverCommandToExecute, Dictionary`2 parameters)
    */
    

      

    2、使用 inspect.exe 工具,确定软件运行时,需要触发事件 UI元素的 ID/Name 

      路径:C:Program Files (x86)Windows Kits10inx64inspect.exe

      例如,在 xaml 中,添加两个 Button:

    第一个设置附加属性:AutomationProperties.AutomationId="button_1"

    第二个设置: x:Name=“button_2”

     <StackPanel Width="500" Height="500" Background="Blue" Grid.RowSpan="3">
         <StackPanel.Resources>
             <Style TargetType="Button">
                 <Setter Property="Margin" Value="10"/>
             </Style>
         </StackPanel.Resources>
         <Button AutomationProperties.AutomationId="button_1">AutomationId="button_1"</Button>
         <Button x:Name="button_2">x:Name="button_2"</Button>
     </StackPanel>

    用 inspect 观测:

    可以看出来,在 inspect 中 Name显示为 Button.Content 属性,如果是 TextBlock控件,Name则显示 TextBlock.Text 属性。

    3、创建测试工程

    1)创建普通的 C# 类库工程即可:

    2)通过 nuget 引用相关类库:

    3)获取 uwp 的启动 id,一个的方法右键点击 app 的快捷方式,选择属性:

    3)工程中添加两个类 QyClientTestBase 和 PlayerPageScenarios,实现启动 爱奇艺uwp,从首页随机点击一个视频,跳转到播放页,播放3秒后,拖拽进度条到中间位置,然后再随机播放选集视频,在播放页递归播放。

    public class QyClientTestBase
    {
        // Note: append /wd/hub to the URL if you're directing the test at Appium
        protected const string WindowsApplicationDriverUrl = "http://127.0.0.1:4723";
    
        protected static WindowsElement Hanburg;
    
        protected static WindowsElement BackButton;
        protected static WindowsDriver<WindowsElement> QyClientSession;
        protected static string OriginalCalculatorMode;
    
        public static void BaseSetup(TestContext context)
        {
            if (QyClientSession == null)
            {
                // 启动爱奇艺 app
                DesiredCapabilities appCapabilities = new DesiredCapabilities();
                appCapabilities.SetCapability("app", "0C72C7CD.Beta_atj5cpqqdhzyp!App");
                appCapabilities.SetCapability("deviceName", "WindowsPC");
                QyClientSession = new WindowsDriver<WindowsElement>(new Uri(WindowsApplicationDriverUrl), appCapabilities);
                Assert.IsNotNull(QyClientSession);
                QyClientSession.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(3));
                
                Hanburg = QyClientSession.FindElementByName("Menu");
    
                // 已经在播放页时
                //BackButton = QyClientSession.FindElementByAccessibilityId("Back");
            }
    
            // 在首页时,汉堡按钮显示;在播放页时,Back按钮显示
            Assert.IsNotNull(Hanburg);
        }
    
        public static void BaseTearDown()
        {
            if (QyClientSession != null)
            {
                Hanburg = null;
                QyClientSession.Dispose();
                QyClientSession = null;
            }
        }        
    }
     [TestClass]
        public class PlayerPageScenarios : QyClientTestBase  // 子类型需要设置为 public,否则“测试资源管理器”中看不到
        {
            [ClassInitialize] //每个单元测试方法执行前,调用的初始化方法
            public static void Setup(TestContext context)
            {
                BaseSetup(context);
            }
    
            [ClassCleanup] //每个单元测试方法执行完成后,调用的清理方法
            public static void TearDown()
            {
                BaseTearDown();
            }
    
            bool isPlaying = false;
    
            [TestMethod]
            public void SliderClick()
            {
    
                if (isPlaying == false)
                {
                    // 先从 app首页,随机播放一个视频,跳转到播放页
                    PlayBRandom();
                    
                    Thread.Sleep(TimeSpan.FromSeconds(3));
                    isPlaying = true;
                }
                
                ShowControls();
    
                //元素需要在页面中显示,如 Visibility="Collapsed" 则获取不到
                WindowsElement slider = QyClientSession.FindElementByAccessibilityId("slider_position"); //进度条
    
                Assert.IsNotNull(slider);
    
                //视频进度条拖动到中间位置
                QyClientSession.Mouse.MouseMove(slider.Coordinates, slider.Size.Width / 2, 0); 
                
                // seek进度
                slider.Click();
                Thread.Sleep(TimeSpan.FromSeconds(3));
    
                //随机播放页面中的一个视频
                PlayBRandom();
    
                Thread.Sleep(TimeSpan.FromSeconds(5));
    
                // 递归调用,在当前页面切换选集播放
                SliderClick();
            }
    
            /// <summary>
            /// 播放当前页面中的任意一个 B 对象
            /// </summary>
            void PlayBRandom()
            {
                var list = QyClientSession.FindElementsByName("QyClient._3._0.Model._B");
    
                if (list.Count > 0)
                {
                    int min = isPlaying ? 0 : 30; //在app首页时,播放 30以后的 B对象
    
                    int index = new Random().Next(min, list.Count - 1);
    
                    WindowsElement e = list.ElementAt(index);
                    e.Click();
                }
                Assert.AreNotEqual(list.Count, 0);
    
                Thread.Sleep(3000);
            }
    
            /// <summary>
            /// 显示播控栏,否则播控按钮获取不到
            /// </summary>
            void ShowControls()
            {
                WindowsElement win = QyClientSession.FindElementByAccessibilityId("mediaPlayer");
                win.Click();
                Thread.Sleep(500);
            }
        }

    4)在“测试资源管理器” 中可以运行和断点调试测试:

    5)运行测试,循环切换选集,播放视频

    示例工程代码

    相关参考:

    UI Testing: What's new with WinAppDriver:https://channel9.msdn.com/Events/Build/2017/P4084

    Improving App Quality with UI Automation:https://channel9.msdn.com/Events/Connect/2016/202?ocid=player

    Automate Windows And Mac Apps With The WebDriver Protocol - Dan Cuellar, FOODIt:https://www.youtube.com/watch?v=MgBRvQOZhec

    StarDriver Enterprise Appium to the Future | Jonathan Lipps:https://www.youtube.com/watch?v=e61OhZzbsEI

    github WinAppDriver: https://github.com/microsoft/winappdriver

    Modern Dev Practices: Unit Testing:https://channel9.msdn.com/Shows/Visual-Studio-Toolbox/Modern-Dev-Practices-Unit-Testing

    Inspect.exe: https://msdn.microsoft.com/en-us/library/windows/desktop/dd318521(v=vs.85).aspx

    Windows SDK and emulator archive : https://developer.microsoft.com/en-us/windows/downloads/sdk-archive

    Windows Automation API: UI Automation:https://msdn.microsoft.com/zh-cn/library/ms726294(vs.85).aspx

    AutomationID :https://docs.microsoft.com/en-us/dotnet/framework/ui-automation/use-the-automationid-property

    UI Automation Overview: 
    https://docs.microsoft.com/en-us/dotnet/framework/ui-automation/ui-automation-overview
    https://msdn.microsoft.com/zh-cn/library/ms728097(v=vs.85).aspx

  • 相关阅读:
    [oldboy-django][2深入django]老师管理--查看,添加,编辑
    全虚拟化和半虚拟化的区别 cpu的ring0~ring3又是什么概念?
    Ansible Jinja if 生成不同的MySQL文件
    Linux内核优化(未注释)
    CentOS7入门到精通实战课程课后习题
    基于sersync海量文件实时同步
    CentOS6系统优化
    lnmp架构实现动态php
    云计算与虚拟化KVM深度实践
    Linux6系统安装
  • 原文地址:https://www.cnblogs.com/hebeiDGL/p/7210293.html
Copyright © 2011-2022 走看看