桌面应用自动化WinAppDriver入门

关于winappdriver

介绍

  • WinAppDriver全称是Windows Application Driver,它提供了一些API,使得用户可以像selenium操作web一样来操作windows的应用程序
  • 它支持的系统是Windows 10 (Home and Pro) 和Windows Server 2016
  • 源码暂未开源
  • WinAppDriver可以独立运行,也可以作为appium的一个插件来使用

支持应用类型

  • UWP – Universal Windows Platform, also known as Universal Apps or Modern Apps, It’s Microsoft’s latest desktop application technology. It’s XAML based. Only runs on Windows 10 machines

  • WPF - also XAML based, much more mature, runs on any Windows version and has been around since 2006.

  • WinForms - one of the older technologies, now found mostly on legacy applications.

    WPF和WinForms 是两套界面渲染方式。一个是对传统windows界面元素的封装,通过gdi绘制。另一个是全新的dx渲染绘制的界面,也脱离了对传统windows控件的依赖,没有历史包袱,理论上可以展现更炫酷的界面。
    
  • MFC/Classic Windows - MFC is a UI library normally paired with Win32 applications. This option is normally chosen when more efficiency is needed with low-level C++ handling or when supporting non-Microsoft platforms.

资源

素材地址说明
FlaUInspecthttps://github.com/FlaUI/FlaUInspect/releases定位工具
WinAppDriverhttps://github.com/microsoft/WinAppDriver/releases/tag/v1.2.1
UIRecorderhttps://github.com/microsoft/WinAppDriver/tree/master/Tools/UIRecorder定位工具
inspect微软官方工具集成于 Windows SDK定位工具
  1. UIRecorder(下文不涉及,仅供参考与备忘)
  1. Open WinAppDriverUIRecorder.sln in Visual Studio
  2. Select Debug > Start Debugging or simply Run

支持的定位方式

Client APILocator StrategyMatched Attribute in inspect.exeExample
FindElementByAccessibilityIdaccessibility idAutomationIdAppNameTitle
FindElementByClassNameclass nameClassNameTextBlock
FindElementByIdidRuntimeId (decimal)42.333896.3.1
FindElementByNamenameNameCalculator
FindElementByTagNametag nameLocalizedControlType (upper camel case)Text
FindElementByXPathxpathAny//Button[0]

配置

开启windows的开发者模式

  • 你没看错,不是手机,windows也有
  • 第一步:搜开发者设置
  • 第二步:打开开发人员模式

  • 第三步:确认启用

启动winappdriver

  • 不开启开发人员模式的提示

    C:\Program Files (x86)\Windows Application Driver>WinAppDriver.exe
    Developer mode is not enabled. Enable it through Settings and restart Windows Application Driver
    Failed to initialize: 0x80004005
    
  • 开启后启动winappdriver

    C:\Program Files (x86)\Windows Application Driver>WinAppDriver.exe
    Windows Application Driver listening for requests at: http://127.0.0.1:4723/
    Press ENTER to exit.
    
  • 还可以这样启动

    WinAppDriver.exe 4727
    WinAppDriver.exe 10.0.0.10 4725
    WinAppDriver.exe 10.0.0.10 4723/wd/hub   # 推荐
    

实例

appium-python-client 版本不要用2.0+,此处是1.2.0

记事本

  • 比如记事本

    from appium import webdriver
    des_cap = {}
    des_cap['app'] = r'C:\Windows\System32\notepad.exe'
    driver = webdriver.Remote(command_executor='http://127.0.0.1:4723/wd/hub',
                              desired_capabilities=des_cap)
    driver.implicitly_wait(5)
    driver.find_element_by_name('文件(F)').click()
    from time import sleep
    sleep(2)
    driver.find_element_by_name('保存(S)	Ctrl+S').click()
    # driver.find_element_by_name('退出(X)').click()
    sleep(1)
    import pyautogui
    pyautogui.PAUSE = 0.5
    pyautogui.typewrite(r'D:\hello.txt')
    pyautogui.press('enter')
    
  • 这里的难点是保存(S) Ctrl+S的获取

  • 这里需要用到inspect.exe

计算器

  • 你可能会写这样的代码
from appium import webdriver
des_cap = {}
des_cap['app'] = r'C:\Windows\System32\calc.exe'
driver = webdriver.Remote(command_executor='http://127.0.0.1:4723/wd/hub',
                          desired_capabilities=des_cap)
driver.implicitly_wait(5)
  • 但会报错
Traceback (most recent call last):
  File "D:/demo_calc.py", line 5, in <module>
    desired_capabilities=des_cap)
  File "D:\Python37\lib\site-packages\appium\webdriver\webdriver.py", line 157, in __init__
    AppiumConnection(command_executor, keep_alive=keep_alive), desired_capabilities, browser_profile, proxy
  File "D:\Python37\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 157, in __init__
    self.start_session(capabilities, browser_profile)
  File "D:\Python37\lib\site-packages\appium\webdriver\webdriver.py", line 226, in start_session
    response = self.execute(RemoteCommand.NEW_SESSION, parameters)
  File "D:\Python37\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "D:\Python37\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.WebDriverException: Message: Failed to locate opened application window with appId: C:\Windows\System32\calc.exe, and processId: 4472

进程已结束,退出代码为 1

  • 打开计算器,然后在powershell中执行如下命令
Get-StartApps |Select-String "计算器"
# 输出
@{Name=计算器; AppID=Microsoft.WindowsCalculator_8wekyb3d8bbwe!App} # 你要的是这里的AppID # 同理,记事本你也可以得到其appid,并自动化
  • 代码
from appium import webdriver
des_cap = {}
des_cap['app'] = r'Microsoft.WindowsCalculator_8wekyb3d8bbwe!App'
driver = webdriver.Remote(command_executor='http://127.0.0.1:4723/wd/hub',
                          desired_capabilities=des_cap)
driver.implicitly_wait(5)
driver.find_element_by_name('一').click() # 这些定位你仍然需要inspect
driver.find_element_by_name('二').click()
driver.find_element_by_name('加').click()
driver.find_element_by_name('三').click()
driver.find_element_by_name('四').click()
driver.find_element_by_name('等于').click()
# 通过inspect 获取 automationID 
print(driver.find_element_by_accessibility_id('CalculatorResults').text) # 得到的是   ·显示为 46·  你仍然要处理才能做测试

driver.quit()
  • 就写这么多了,你可以结合你的应用来尝试,封装。我就带到这里。

计算器测试(官网)

我没跑,仅供参考,你可以认为是为了增加篇幅

# https://raw.githubusercontent.com/microsoft/WinAppDriver/master/Samples/Python/calculatortest.py
import unittest
from appium import webdriver

class SimpleCalculatorTests(unittest.TestCase):

    @classmethod

    def setUpClass(self):
        #set up appium
        desired_caps = {}
        desired_caps["app"] = "Microsoft.WindowsCalculator_8wekyb3d8bbwe!App"
        self.driver = webdriver.Remote(
            command_executor='http://127.0.0.1:4723',
            desired_capabilities= desired_caps)

    @classmethod
    def tearDownClass(self):
        self.driver.quit()

    def getresults(self):
        displaytext = self.driver.find_element_by_accessibility_id("CalculatorResults").text
        displaytext = displaytext.strip("Display is " )
        displaytext = displaytext.rstrip(' ')
        displaytext = displaytext.lstrip(' ')
        return displaytext


    def test_initialize(self):
        self.driver.find_element_by_name("Clear").click()
        self.driver.find_element_by_name("Seven").click()
        self.assertEqual(self.getresults(),"7")
        self.driver.find_element_by_name("Clear").click()

    def test_addition(self):
        self.driver.find_element_by_name("One").click()
        self.driver.find_element_by_name("Plus").click()
        self.driver.find_element_by_name("Seven").click()
        self.driver.find_element_by_name("Equals").click()
        self.assertEqual(self.getresults(),"8")

    def test_combination(self):
        self.driver.find_element_by_name("Seven").click()
        self.driver.find_element_by_name("Multiply by").click()
        self.driver.find_element_by_name("Nine").click()
        self.driver.find_element_by_name("Plus").click()
        self.driver.find_element_by_name("One").click()
        self.driver.find_element_by_name("Equals").click()
        self.driver.find_element_by_name("Divide by").click()
        self.driver.find_element_by_name("Eight").click()
        self.driver.find_element_by_name("Equals").click()
        self.assertEqual(self.getresults(),"8")

    def test_division(self):
        self.driver.find_element_by_name("Eight").click()
        self.driver.find_element_by_name("Eight").click()
        self.driver.find_element_by_name("Divide by").click()
        self.driver.find_element_by_name("One").click()
        self.driver.find_element_by_name("One").click()
        self.driver.find_element_by_name("Equals").click()
        self.assertEqual(self.getresults(),"8")

    def test_multiplication(self):
        self.driver.find_element_by_name("Nine").click()
        self.driver.find_element_by_name("Multiply by").click()
        self.driver.find_element_by_name("Nine").click()
        self.driver.find_element_by_name("Equals").click()
        self.assertEqual(self.getresults(),"81") 

    def test_subtraction(self):
        self.driver.find_element_by_name("Nine").click()
        self.driver.find_element_by_name("Minus").click()
        self.driver.find_element_by_name("One").click()
        self.driver.find_element_by_name("Equals").click()
        self.assertEqual(self.getresults(),"8")

if __name__ == '__main__':
    suite = unittest.TestLoader().loadTestsFromTestCase(SimpleCalculatorTests)
    unittest.TextTestRunner(verbosity=2).run(suite)
  • 19
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Windows系统桌面应用自动化测试是指通过使用自动化测试工具或框架来模拟用户操作和验证应用程序的功能和性能。下面是一些常见的Windows系统桌面应用自动化测试的介绍: 1. 自动化测试工具:常见的自动化测试工具包括Selenium、AppiumWinAppDriver等。这些工具可以模拟用户的操作,如点击、输入、选择等,并可以验证应用程序的功能是否正常。 2. UI自动化测试:UI自动化测试是指通过模拟用户界面操作来验证应用程序的功能。它可以模拟用户在应用程序中的各种操作,如点击按钮、输入文本、选择下拉框等,并可以验证应用程序的响应是否符合预期。 3. 数据驱动测试:数据驱动测试是一种测试方法,它通过使用不同的测试数据来执行相同的测试用例。在Windows系统桌面应用自动化测试中,可以使用数据驱动测试来验证应用程序在不同输入数据下的行为和结果。 4. 性能测试:性能测试是指对应用程序进行压力和负载测试,以评估其在不同负载下的性能表现。在Windows系统桌面应用自动化测试中,可以使用性能测试工具来模拟多个用户同时操作应用程序,并监测其响应时间、资源占用等指标。 5. 集成测试:集成测试是指对应用程序的各个模块进行整体测试,以验证它们之间的交互和协作是否正常。在Windows系统桌面应用自动化测试中,可以使用集成测试工具来模拟不同模块之间的交互,并验证其功能和数据的正确性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wuxianfeng023

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值