接口测试 接口测试之上传文件

daveze · 2016年05月20日 · 最后由 jennifer 回复于 2016年05月20日 · 4254 次阅读

背景:

在接口测试或者 web UI 自动化测试时,常会遇到需要上传文件的场景,此时在 UI 自动化测试过程中大多会采用 AutoIt 及其衍生的库来完成,但是这是一种操作 windows 窗口的方式,适用性不广(无法在没有 GUI 界面的机器上实现),稳定性也差(或许换一个尺寸或分辨率就 gg 了);所以这里建议通过接口上传文件。

目的:

使用 robot framework,通过接口上传文件

摸索:

通过抓包发现,在 web 页面上上传一个文件,其实是对某接口地址 Post 一个请求,如图:

上图中是该请求的头信息

  • 可以看到该接口地址和路径,形如:http://192.169.100.210/web/applicaton/*****;

  • 这里面附带了本次上传操作必要的鉴权信息,例如 cookies、token 等;

  • 值得注意的是,请求头中 Content-Type 是:multipart/form-data,代表我这次请求是要上传文件。

上图中是该 post 请求具体的内容:

  • 这里的信息会根据不同的产品和不同的接口都有差异,在这个例子中,有 2 段信息,分别是:name="id",值为 110,代表上传文件对应的 id 号 (该 id 号在数据库中会有其具体的意义),和 name="file",值为待上传文件的内容或其二进制信息,代表需要上传的文件和其在服务器上存储的字段名。

  • 这 2 段信息用 boundary 参数来分隔,就是上面的 “-----------------------------4459795128597301541214721262”,随机生成的。

  • 还有需要注意的是:post 内容里面文件的 content-type,我这里上传的是文本,所以为 text/plain,如果是 apk,则为 application/octet-stream,其它文件可以通过抓包来观察。

实现:

  • 摸索几遍之后,发现只要我们使用 content-type=multipart/form-data 请求并附上鉴权信息,再捎带必要的 post 信息和文件;

  • 因为用的 RF 框架,使用 RF 中的 RequestsLibrary,发现该库中的 post 关键字可以满足 post 文本信息的需求,但是满足 post 文件需求有点困难,感觉限制太大,干脆放弃,所以使用 python 自己写一个定制的方法吧。

  • python 中还是使用 python 的 requests 库,发现该库中已有的 post 方法可以直接满足需求,然后我再包装一下,如下:

    def postFile(
        self,
        url,
        headers=None,
        cookies=None,
        body_data=None,
        filepath=None,
        name=None,
        filename=None,
        contentType=None):
    """使用Content-Type为'multipart/form-data'上传文件
    :param url:接口地址,含路径
    :param headers:headers
    :param cookies:cookies
    :param body_data:跟随请求发送的参数,字典形式
    :param filepath:待上传的文件路径
    :param name:文件的key
    :param filename:文件名称
    :param contentType:该文件的内容类型
    :return:
    """
    files = {name:(filename, open(filepath, 'rb'), contentType)}
    request_data = body_data
    
    r = requests.post(url,cookies=cookies, headers=headers, data=request_data, files=files)
    status_code=r.status_code
    reponse=r.json()
    #headers=r.request.headers
    
    return status_code,reponse
    

在 RF 中调用如下:

*** Settings ***

Library           RequestsLibrary
Library           Collections
Library           XML
Library           OperatingSystem
Library           ArtisanCustomLibrary

*** Test Cases ***

upload_mapping
    ${data}    Create Dictionary    id=110

    ${cookies}    Create Dictionary    csrftoken=cursaAAPMeNsEnEGg9BhfrSbxtu16nna    sessionid=38bh6069nfwk8283r81h0j2yvwk1knwk

    ${headers}    Create Dictionary    Token=4debb41d64a043d8a887199943095ead    Connection=keep-alive    User-Agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:44.0) Gecko/20100101 Firefox/44.0

    ${response}    post file    http://192.169.100.210/web/version_mapping_file_upload/    ${headers}    ${cookies}    ${data}    /Users/OV/work/Crash-Analysis/test_crash_app/app_sp5_20160222/map.txt
    ...    file    ov_test.txt    text/plain

    log     ${response[0]}

效果:

如上通过自定义一个方法 postFile 并导入 RF 中作为 RF 系统关键字的方式,实现了通过接口上传 txt 文件的目的。


见解不同之处,欢迎指出~

搬运自本人Blog,转载请注明出处,非常感谢。

共收到 1 条回复 时间 点赞

上传文件这块一直都是在用 autoitlibrary 库,这下有可以试一下你的方法了,多谢分享!

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册