• Ui自动化测试如何上传文件


    【软件测试面试突击班】如何逼自己一周刷完软件测试八股文教程,刷完面试就稳了,你也可以当高薪软件测试工程师(自动化测试)

    前言

    实施UI自动化测试的时候,经常会遇见上传文件的操作,那么对于上传文件你知道几种方法呢?今天我们就总结一下几种常用的上传文件的方法,并分析一下每个方法的优点和缺点以及哪种方法效率,稳定性更高

    被测HTML代码

    1. <!--upload_file.html-->
    2. <!DOCTYPE html>
    3. <html lang="en">
    4. <head>
    5. <meta charset="UTF-8">
    6. <title>上传文件</title>
    7. </head>
    8. <body>
    9. <input id="upload_file" type="file">
    10. </body>
    11. </html>

    第一种方法:使用webdriver api 提供的方法send_keys上传文件

    send_keys方法

    实例
    1. ------------------------------------
    2. @Time : 2019/7/17 19:03
    3. @Auth : linux超
    4. @File : upload_file_send_keys.py
    5. @IDE : PyCharm
    6. @Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error!
    7. @QQ : 28174043@qq.com
    8. @GROUP: 878565760
    9. ------------------------------------
    10. """
    11. from selenium import webdriver
    12. import time
    13. driver = webdriver.Firefox()
    14. driver.get(r'file:///e:/CnblogCode/upload_file.html')
    15. upload_element = driver.find_element_by_xpath('//*[@id="upload_file"]')
    16. time.sleep(3) # 为了看效果
    17. upload_element.send_keys(r'E:\CnblogCode\upload_file.html')
    执行过程

    可以看到执行过程很顺利,且代码实现简单,也没有报错

    但是往往现实是残酷的,因为有的网站的上传文件并不是采用 input标签来定义的上传文件按钮,所以就无法使用send_keys方法上传,这也是这个方法的限制

    AutoIt工具
    第二种方法是AutoIT工具,它是一个类似脚本语言的软件,利用此软件我们可以方便的实现模拟键盘、鼠标、窗口等操作,实现自动化

    安装
    官网地址:AutoIt Downloads - AutoIt

    安装完后可以找到如下一些工具

     

    使用
    1. 打开被测试的HTML页面,并点击上传文件,弹出上传文件窗口,并保持当前窗口

    2. 打开AutoIt Window Info(x86/x64)工具

    3. 点击工具中Finder Tool标签下的按钮,开始分别定位上传文件的【输入框】和【打开】按钮,并记录Title,Class,Instance(图中红色窗口中的信息)

    注意:不同的浏览器抓取的Title是不一样的(Firefox:文件上传,Chrome:打开,IE:选择要加载的文件)

    4. 打开 SciTE Script Editor

     

    工具开始编写脚本(注意脚本中的Edit1是class 和 instance 拼接的)

    ;first make sure the number of arguments passed into the scripts is more than 1
    If $CmdLine[0]<2 Then Exit EndIf ;if parmas num <2 ,then break
    ;$CmdLine[0] ;参数的数量
    ;$CmdLine[1] ;第一个参数 (脚本名称后面)
    ;$CmdLine[2] ;第二个参数
    ;都是从cmd传入参数
     handleUpload($CmdLine[1],$CmdLine[2])

    ;定义上传函数,有两个参数,第一个是浏览器名字,第二参数是文件路径
     Func handleUpload($browser, $uploadfile)
         Dim $title                          ;定义一个title变量
                ;根据弹窗的title来判断是什么浏览器
                If $browser="ie" Then                          ; 代表IE浏览器
                      $title="选择要加载的文件"
                ElseIf $browser="chrome" Then               ; 代表谷歌浏览器
                     $title="打开"
                ElseIf    $browser="firefox" Then             ; 代表火狐浏览器
                      $title="文件上传"
                EndIf

                if WinWait($title,"",4) Then ;等待弹出出现,最大等待时间是4秒
                       WinActivate($title)                  ;找到弹出窗口之后,激活当前窗口
                       ControlSetText($title,"","Edit1",$uploadfile)   ;把文件路径放入输入框,此”Edit1“是用FinderTool获取到的
                       ControlClick($title,"","Button1")                ;点击保存或者打开或者上传按钮,此“Button1”使用FinderTool获取到的
                Else
                Return False
                EndIf
     EndFunn

    5. 编译脚本为exe可执行文件

    编写完脚本之后,保存文件并打开Compile Script to .exe(x64/x86)工具 

     


    ,将保存后的脚本.au3文件转换为.exe可执行文件

    6. 执行转换后的脚本

    在执行脚本之前,先确保上传文件的窗口已经打开,接下来打开cmd执行exe程序  C:\Users\v-xug\Desktop>upload_file_new.exe firefox E:\CnblogCode\upload_file.html

    7. 执行效果

    8. 编写selenium脚本

    实例
    1. """
    2. ------------------------------------
    3. @Time : 2019/7/18 16:20
    4. @Auth : linux超
    5. @File : base.py
    6. @IDE : PyCharm
    7. @Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error!
    8. @QQ : 28174043@qq.com
    9. @GROUP: 878565760
    10. ------------------------------------
    11. """
    12. from selenium.webdriver.common.action_chains import ActionChains
    13. import os
    14. from selenium import webdriver
    15. import time
    16. class Base(object):
    17. @staticmethod
    18. def upload_file(exe, browser, filename):
    19. """
    20. 使用autoIt上传文件
    21. :param exe: 上传文件的exe程序所在目录
    22. :param browser: 浏览器类型: firefox chrome ie
    23. :param filename: 待上传文件路径
    24. :return: none
    25. """
    26. cmd = exe + ' ' + browser + ' ' + filename
    27. os.system(cmd)
    28. if __name__ == '__main__':
    29. driver = webdriver.Firefox()
    30. driver.get(r'file:///e:/CnblogCode/upload_file.html') # 打开被测html
    31. upload_element = driver.find_element_by_xpath('//*[@id="upload_file"]')
    32. action = ActionChains(driver)
    33. action.move_to_element(upload_element).click().perform() # 点击上传文件弹出上传文件窗口
    34. action.release()
    35. time.sleep(3) # 为了看效果
    36. Base.upload_file(r'E:\CnblogCode\upload_file_new.exe', 'firefox', r'E:\CnblogCode\upload_file.html') # 上传文件

     执行过程

    以上就是使用AutoId工具完成上传文件的过程,其实还是挺复杂的, 但是配置一次之后,以后就可以重复使用编译生成的exe文件了,执行效果还是不错的 没出什么错误,执行效率也还可以

    模拟键盘
    第三种方法:模拟键盘的粘贴与回车操作并结合剪切板的操作来完成上传文件,基本原理是向剪切板中发送文件(文件路径字符串),然后再从剪切板中获取到文件,最后通过模拟键盘的ctrl+v与enter键来完成文件上传

    这种方法需要第三方库的支持,安装pypiwin32库: pip install pypiwin32

    实例
    模拟键盘操作代码

    1. """
    2. ------------------------------------
    3. @Time : 2019/7/18 17:14
    4. @Auth : linux超
    5. @File : keyboard.py
    6. @IDE : PyCharm
    7. @Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error!
    8. @QQ : 28174043@qq.com
    9. @GROUP: 878565760
    10. ------------------------------------
    11. """
    12. import win32api
    13. import win32con
    14. import time
    15. class KeyBoard(object):
    16. """模拟按键"""
    17. # 键盘码
    18. vk_code = {
    19. 'enter' : 0x0D,
    20. 'ctrl' : 0x11,
    21. 'v' : 0x56
    22. }
    23. @staticmethod
    24. def keyDown(key_name):
    25. """按下键"""
    26. key_name = key_name.lower()
    27. try:
    28. win32api.keybd_event(KeyBoard.vk_code[key_name], 0, 0, 0)
    29. except Exception as e:
    30. print('未按下enter键')
    31. raise e
    32. @staticmethod
    33. def keyUp(key_name):
    34. """抬起键"""
    35. key_name = key_name.lower()
    36. win32api.keybd_event(KeyBoard.vk_code[key_name], 0, win32con.KEYEVENTF_KEYUP, 0)
    37. @staticmethod
    38. def oneKey(key):
    39. """模拟单个按键"""
    40. key = key.lower()
    41. KeyBoard.keyDown(key)
    42. time.sleep(2)
    43. KeyBoard.keyUp(key)
    44. @staticmethod
    45. def twoKeys(key1, key2):
    46. """模拟组合按键"""
    47. key1 = key1.lower()
    48. key2 = key2.lower()
    49. KeyBoard.keyDown(key1)
    50. KeyBoard.keyDown(key2)
    51. KeyBoard.keyUp(key1)
    52. KeyBoard.keyUp(key2)
    if __name__ == '__main__':
        pass

    剪切板操作代码

    1. """
    2. ------------------------------------
    3. @Time : 2019/7/18 17:18
    4. @Auth : linux超
    5. @File : clipboard.py
    6. @IDE : PyCharm
    7. @Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error!
    8. @QQ : 28174043@qq.com
    9. @GROUP: 878565760
    10. ------------------------------------
    11. """
    12. import win32con
    13. import win32clipboard as WC
    14. class ClipBoard(object):
    15. """设置剪切板内容和获取剪切板内容"""
    16. @staticmethod
    17. def getText():
    18. """获取剪切板的内容"""
    19. WC.OpenClipboard()
    20. value = WC.GetClipboardData(win32con.CF_TEXT)
    21. WC.CloseClipboard()
    22. return value
    23. @staticmethod
    24. def setText(value):
    25. """设置剪切板的内容"""
    26. WC.OpenClipboard()
    27. WC.EmptyClipboard()
    28. WC.SetClipboardData(win32con.CF_UNICODETEXT, value)
    29. WC.CloseClipboard()
    30. if __name__ == '__main__':
    31. pass

    上传文件代码

    1. """
    2. ------------------------------------
    3. @Time : 2019/7/18 17:20
    4. @Auth : linux超
    5. @File : upload_file_board.py
    6. @IDE : PyCharm
    7. @Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error!
    8. @QQ : 28174043@qq.com
    9. @GROUP: 878565760
    10. ------------------------------------
    11. """
    12. from clipboard import ClipBoard
    13. from keyboard import KeyBoard
    14. from selenium import webdriver
    15. import time
    16. from selenium.webdriver.common.action_chains import ActionChains
    17. if __name__ == '__main__':
    18. ClipBoard.setText(r'E:\CnblogCode\upload_file.html') # 待上传文件设置到剪切板
    19. driver = webdriver.Firefox()
    20. driver.get(r'file:///e:/CnblogCode/upload_file.html')
    21. upload_element = driver.find_element_by_xpath('//*[@id="upload_file"]')
    22. action = ActionChains(driver)
    23. action.move_to_element(upload_element).click().perform()
    24. action.release()
    25. time.sleep(3) # 为了看效果
    26. KeyBoard.twoKeys('ctrl', 'v')
    27. KeyBoard.oneKey('enter')
    执行过程

    失败

    可以看到第二个动画上传文件未成功,这也就这个方法的弊端,只要移动了鼠标就有可能就不会成功,毕竟模拟的是enter键,这个过程你点击了别的地方,那么enter的效果就变了,所以这种方法很不稳定,也不难发现,代码量也很多,而且需要掌握模拟键盘和剪切板的操作,最不推荐使用的就是这种方法

    之前我的实战项目里面,用到过这种方法, 当时我已经发现了这种方法的弊端, 但是为了掌握这种模拟键盘的方法,所以才使用的,当然模拟键盘操作用到一些特殊的情况还是能解决很多实际问题的

    WinSpy工具
    第四种方法:这个工具其实和AutoIt工具的元素定位方式一样,但是不需要生成exe文件,其实只是个辅助工具,主要用来获取windows窗口句柄,进而通过python脚本来控制

    WinSpy安装
    WinSpy download | SourceForge.net

    下载完直接解压打开WinSpy32(64).exe即可使用

    使用方法和autoId一样,请按照下图的步骤操作,记录winspy-Tree中红框信息

    编写代码之前,同样需要提前安装 pypiwin32库

    实例

     load_file_winspy.py

    执行过程

    此方法也比较稳定,只要通过传递不同的浏览器参数,即可完成不同浏览器中的上传文件操作,而且相比于AutoId而言,这种方法可以直接使用python编写代码且不需要编译成exe程序,可以随时对代码进行修改,易维护

    总结
    最后总结一下每个方法的优缺点

    1. send_keys(): 如果所遇见的上传文件使用的是input标签且属性type=file,均可使用,也最好采用此方法,方便,简单,执行效率高

    2. AutoId: 需编写VBS代码并编译为exe可执行文件,过程繁琐,编写selenium测试用例时无法随时调试内部代码,但send_keys()无法使用时,可以采用此方法,执行效率较高,稳定性也算可以

    3. 模拟键盘和剪切板: 此方法需要掌win32api,win32gui模块的使用,且代码编写繁琐,上传文件时如果鼠标点击其他地方会导致上传失败,脚本稳定性差,且效率低,但是如果用到一些特殊地方会起到比较好的效果

    4. WinSpay:windows窗口句柄抓取工具,不需要编译脚本为exe文件,且上传文件操作使用的脚本是python第三方库实现,易维护,执行效率也较高,推荐send_keys()不可使用时,首先考虑此方法

    下面是配套学习资料,对于做【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!

    软件测试面试小程序

    被百万人刷爆的软件测试题库!!!谁用谁知道!!!全网最全面试刷题小程序,手机就可以刷题,地铁上公交上,卷起来!

    涵盖以下这些面试题板块:

    1、软件测试基础理论 ,2、web,app,接口功能测试 ,3、网络 ,4、数据库 ,5、linux

    6、web,app,接口自动化 ,7、性能测试 ,8、编程基础,9、hr面试题 ,10、开放性测试题,11、安全测试,12、计算机基础

     

    文档获取方式:

    这份文档,对于想从事【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!

    以上均可以分享,只需要你搜索vx公众号:程序员雨果,即可免费领取

  • 相关阅读:
    程序员网上接单盛行,到底该怎样选择一个好用不坑的接单平台?
    常见池化技术:连接池、线程池和内存池等
    Python中的变量与注释
    【GDB】使用 GDB 自动画红黑树
    前端解决跨域 3 种方法 -对接读卡器时出现跨域问题
    【牛客 - 剑指offer】JZ15 二进制中1的个数 Java实现 | 原码、反码、补码
    LED灯实验--汇编
    前端下载文件重命名
    空气阻力对乒乓球运动轨迹的影响
    LA@二次型标准形@标准化问题介绍和合同对角化@二次型可标准化定理
  • 原文地址:https://blog.csdn.net/2301_77645834/article/details/133176209