如何使用 selenium 或 webdriver 在测试自动化中处理文件上传

Posted

技术标签:

【中文标题】如何使用 selenium 或 webdriver 在测试自动化中处理文件上传【英文标题】:How to deal with file uploading in test automation using selenium or webdriver 【发布时间】:2011-09-01 23:04:29 【问题描述】:

我认为使用 Webdriver 进行测试自动化的每个人都必须意识到它在 Web 开发方面的巨大优势。

但是,如果文件上传是您网络流程的一部分,则会出现一个大问题。它不再是测试自动化。浏览器的安全限制(调用文件选择)实际上使得自动化测试变得不可能。

Afaik 唯一的选择是让 Webdriver 单击文件上传按钮,让线程休眠,让开发人员/测试人员手动选择文件,然后执行其余的网络流程。

如何解决这个问题,有解决方法吗?因为真的不能这样。这没有意义。

这是我所知道的唯一不适用浏览器安全限制的情况:

<script language=javascript>   
  function window.onload()   
          document.all.attachment.focus();   
          var WshShell=new ActiveXObject("WScript.Shell")   
          WshShell.sendKeys("D:\MyFile.doc")
     
</script>

【问题讨论】:

有趣的解决方法,从来没想过。 [我在这里发布了我的 python 解决方案][1]。它也可能适用于其他语言。 [1]:***.com/a/11872608/471376 【参考方案1】:

Webdriver 在 IE 和 Firefox 中可以很容易地处理这个问题。这是一个查找元素并输入元素的简单案例。

driver = webdriver.Firefox()
element = driver.find_element_by_id("fileUpload")
element.send_keys("myfile.txt")

上面的例子是用 Python 编写的,但你明白了

【讨论】:

嘿,你能详细说明一下吗?我不认为这是可能的。首先,什么是 myfile.txt ?它应该是文件系统上文件的路径吗?可以做到这一点的唯一方法是 Microsoft ActiveX 废话(请参阅我编辑的答案)afaik。尝试了你所说的,我得到了 Firefox 驱动程序的错误页面。 你是对的,它应该可以工作...... irc 频道上的人告诉我,没有办法这样做......太好了 :) 我想指出,虽然上面的代码 sn-p 有效,但它主要用于本地 WebDriver 实例。如果您使用 RemoteWebDriver、Grid2 或 SauceLabs,您可能需要添加更多代码才能使其工作。它成为远程/网格上的两步过程 - 文件从运行 Selenium 代码的位置(作为源位置)复制到(通过 Selenium 中的 JSONWireProtocol)到浏览器会话机器(远程/网格节点),然后从那里最终从节点机器上传到网站/应用程序。更多细节在我的下一条评论中,因为我的空间已经用完了。 仅供参考,在本地模式下,文件直接从本地主机/节点上传到网站/应用程序,没有中间文件传输步骤。有关远程/网格上传的信息,请参阅这些链接:sauceio.com/index.php/2012/03/…、groups.google.com/forum/#!topic/webdriver/OU2RxvTE7UY/…【参考方案2】:

如果您使用的是 Java,那么使用 AWT Robots 是一种选择。但这不是一个好的选择,它不是很可靠,而且根本不干净。 Look here

我使用 HttpClient 并在 Selenium 之外运行一些测试。这样更可靠、更干净。

请参阅下面的代码。您将需要更多的异常处理和条件来使其适合您的工作。

HttpClient c = new HttpClient();
String url = "http://" + cargoHost + ":" + cargoPort + contextPath + "/j_security_check";
PostMethod post = new PostMethod(url);
post.setParameter("j_username", username);
post.setParameter("j_password", password);
c.executeMethod(post);

url = "http://" + cargoHost + ":" + cargoPort + contextPath + "/myurl.html";
MultipartPostMethod mPost = new MultipartPostMethod(url);
String fileNameWithPath = this.getClass().getClassLoader().getResource(filename).getPath();
File f1 = new File(fileNameWithPath);
mPost.addParameter(elementName, f1);
mPost.addParameter("action", "upload");
mPost.addParameter("ajax", "true");

c.executeMethod(mPost);
mPost.getResponseBodyAsString();

【讨论】:

我已经尝试过 AWT,但它确实比更好更糟糕:-) 第二个选项。我正在使用的文件上传器列出了您选择的文件并在 javascript 中保持状态......这是测试的一部分......这真是该死的情况男人 HtmlUnit 对 Javascript 有一些支持。我还没有尝试过。并且 WebDriver 支持 HtmlUnitDriver。也许你可以试试看。 变量elementName,就像 ?【参考方案3】:

仅当启用文本框时,在文本框中输入内容的建议才有效。 出于显而易见的原因,相当多的应用程序会迫使您通过文件系统文件浏览器。 那你怎么办呢? 我不认为 WebDriver 专家只是想将键呈现到 KeyBoard 缓冲区中(在早期的自动化时代,这曾经是“不费吹灰之力”)

===

经过几天的短暂睡眠、撞头和拉头发后,我得到了这里(和其他地方)建议的一些基于机器人的解决方案。

我遇到的问题是使用正确的文件路径和名称填充的对话框文本框无法响应使用 VK_ENTER 终止文件名的 KeyPress/Release 事件,如下所示:

private final static int Enter = KeyEvent.VK_ENTER;
keyboard.keyPress(Enter);
keyboard.keyRelease(Enter);

发生的情况是文件路径和文件名输入正确,但对话框仍然打开 - 我一直希望并祈祷密钥模拟将终止它并由正在测试的应用程序处理。

有谁知道如何让这个机器人表现得更好一点?

【讨论】:

【参考方案4】:

只是想我会为作者使用 ActiveX 的原始帖子提供一个仅供参考。另一种解决方法是与桌面 GUI 自动化工具集成来完成这项工作。例如,谷歌“Selenium AutoIt”。如需更跨平台的解决方案,请考虑使用 Sikuli 等工具而不是 AutoIt。

这当然不是考虑 WebDriver 支持通过 SendKeys 在 IE 和 Firefox 上上传,或者考虑其他浏览器不支持该方法。

【讨论】:

【参考方案5】:

在解决这个问题太多小时后,我想与社区分享 Firefox 7.0.1 似乎与上面提到的 FirefoxDriver sendKeys() 实现存在问题(至少我无法得到它可以在我的 Windows 7 x64 机器上运行),我还没有找到解决方法,但更新到 Firefox 8.0.1 似乎已经解决了这个问题。对于那些想知道的人,也可以使用 Selenium RC 来解决这个问题(尽管您需要考虑所有目标操作系统以及与文件选择对话框交互所需的本机按键)。希望我必须解决的问题可以为其他人节省一些时间,总而言之:

https://gist.github.com/1511360

【讨论】:

【参考方案6】:

如果您使用的是网格,您可以打开测试文件的文件夹以供共享。

这样您可以选择上传输入字段并将其值设置为 \\pc-name\myTestFiles

如果不是,则应使用每个系统上的本地文件。

【讨论】:

以上是关于如何使用 selenium 或 webdriver 在测试自动化中处理文件上传的主要内容,如果未能解决你的问题,请参考以下文章

如何重新连接到 webdriver 使用 selenium 打开的浏览器?

Selenium Webdriver如何触发HTTP请求

如何使用Selenium WebDriver查找错误的链接?

如果站点使用 Ajax,如何检查 Selenium WebDriver?

如何使用Python中的Selenium WebDriver按照html选择复选框

如何使用Selenium Webdriver捕获特定元素而不是整个页面的屏幕截图?