问题
在进行web端UI自动化测试时,时常会遇到文件上传,本人也经历了类似问题,将实现的两种方式做了下总结。

解决方案

第一种:type=file的上传文件,类似如下:

autoit和python配合 python调用autoit_自动化


使用元素定位代码就可以完成,比较简单:

# 支持上传单个文件
# 文件的绝对路径
fail = r'C:\Users\test_file\test_02.rvt'
driver.find_element(By.XPATH, '//*[@id="file"]').send_keys(fail)
# 上传多个文件
root_path = r'C:\Users\test_file'
for root, dirs, files in os.walk(root_path, topdown=False):
    for name in files:
        print(os.path.join(root, name))
        driver.find_element(By.XPATH, '//*[@id="file"]').send_keys(os.path.join(root, name))

前言:
关于非input文件上传,点上传按钮后,这个弹出的windows的控件了,已经跳出三界之外了,不属于selenium的管辖范围(selenium不是万能的,只能操作web上元素)。autoit工具处理windows的控件窗口是专业的,所以这个需借助AutoIt来解决了。

第二种:实现起来较为麻烦,这里用到了autoit,aotoit下载安装,这里不做解释,网上大把教程。

大致步骤如下:

1.下载并安装autoit,之后在开始菜单可以看到如下

autoit和python配合 python调用autoit_python_02

  • AutoIt Windows Info 用于识别Windows控件信息
  • Compile Script to.exe 用于将AutoIt生成 exe 执行文件
  • Run Script 用于执行AutoIt脚本
  • SciTE Script Editor 用于编写AutoIt脚本

2.元素定位,Find Tool 查看元素属性,用鼠标按住Find Tool下的图标,然后拖拽到你想定位的元素上

autoit和python配合 python调用autoit_selenium_03


3.上传弹窗打开后就不要操作了;

查看title,title即AutoIt Window Info识别出的Title字段

识别元素,主要是上图中的文件名输入框和打开按钮,使用AutoIt Windows Info完成,记录结果如下:

文件名输入框的class 为“Edit”,Instance为“1”

autoit和python配合 python调用autoit_控件_04


4.打开 SciTE Script Editor编辑器,开始写脚本,代码非常简单只有四行

;识别windows窗口
ControlFocus("打开","","Edit1")
;窗口等待十秒
WinWait("[CLASS:#32770]","",10)
;想输入框中输入需要上传的地址
ControlSetText("打开", "", "Edit1", "C:\pycharm\test_file\test_01.rvt")
Sleep(200)
;点击[打开】按钮
ControlClick("打开", "","Button1");

autoit和python配合 python调用autoit_自动化_05


上述代码中特别需要注意“打开”字样是你点击上传按钮之后弹出的对话框的title,可能每个系统会不一样

5.验证脚本
编辑完成后执行,tools>go ;或者按f5执行,执行完之后就能看到图片上传成功了。

autoit几个常用的语法:

  • WinActivate(“title”) 聚焦到指定活动窗口
  • ControlFocus ( “title”, “窗口文本”, controlID) 设置输入焦点到指定窗口的某个控件上;
  • WinWait ( “title” , “窗口文本” , 超时时间 ) 暂停脚本的执行直至指定窗口存在(出现)为止;
  • ControlSetText ( “title”, “窗口文本”, controlID, “新文本” ) 修改指定控件的文本;
  • Sleep ( 延迟 ) 使脚本暂停指定时间,单位是毫秒;
  • ControlClick ( “title”, “窗口文本”, 控件ID , 按钮 , 点击次数 ) 向指定控件发送鼠标点击命令;

6.打开Compile Script to.exe工具,将其生成为exe可执行文件,接下来用python去执行这个.exe文件就能实现文件上传了

7.python脚本中调用
python调用dos,用这个方法os.system(“需执行的指令”)

# aotoIT 文件上传
driver.find_element(By.XPATH, '//div[@class="uploadPage___1rPiQ"]/div/button').click()
sleep(1)
# exe文件路径
os.system(r'C:\upload_exe\upload_exe.au3.exe')

autoit命令行参数
1.上面打包的exe文件把上传文件的路径给写死了,每次只能传固定的那个图片,我们实际测试时候希望传不同的图片,这样就需要参数化文件路径了。
想要参数化传入的参数,可以通过autoit的命令行参数:

myProg.exe param1 “This is a string parameter” 99

在脚本中,可用以下变量获取命令行参数:

$CmdLine[0] ; = 3
$CmdLine[1] ; = param1
$CmdLine[2] ; = "This is a string parameter"
$CmdLine[3] ; = 99
$CmdLineRaw ; = 'param1 "This is a string parameter" 99'

autoit和python配合 python调用autoit_控件_06CmdLine[0]=3
autoit和python配合 python调用autoit_控件_07CmdLine[63] 获取的是命令行参数第1到第63位,这个方式最多只能获取63个参数,不过正常情况下是足够用的
$CmdLineRaw 获取的是未拆分的所有参数,是一个长字符串,这种情况下不局限与63个参数

WinActivate("文件上传");
ControlSetText("文件上传", "", "Edit1", $CmdLine[1] );
Sleep(2000);
ControlClick("文件上传", "", "Button1");

其他
其实还有其他的解决方法,比如还可以利用Python pywin32库,识别对话框句柄,进而操作,不过本人目前还没研究明白。