Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

框架中集成文件上传功能 #169

Closed
debugtalk opened this issue Apr 16, 2018 · 19 comments
Closed

框架中集成文件上传功能 #169

debugtalk opened this issue Apr 16, 2018 · 19 comments
Labels
docs Need to add some docs

Comments

@debugtalk
Copy link
Member

debugtalk commented Apr 16, 2018

针对常见的文件上传场景,在框架中集成为内置功能。

#23 #103 #144

@debugtalk
Copy link
Member Author

在框架中内置 multipart_encodermultipart_content_type 函数,具体使用方式如需:

- config:
    name: test upload file with httpbin
    request:
        base_url: https://httpbin.org

- test:
    name: upload file
    variable_binds:
        - field_name: "file"
        - file_path: "LICENSE"
        - file_type: "text/html"
        - multipart_encoder: ${multipart_encoder($field_name, $file_path, $file_type)}
    request:
        url: /post
        method: POST
        headers:
            Content-Type: ${multipart_content_type($multipart_encoder)}
        data: $multipart_encoder
    validators:
        - eq: ["status_code", 200]
        - startswith: ["content.files.file", "MIT License"]

@julianmail
Copy link

julianmail commented May 8, 2018

使用上面代码,报错:multipart_encoder is not defined in bind @@@functions!是什么问题?
测试脚本如下:

- config:
    name: test upload file

- test:
    name: upload file
    variable_binds:
        - field_name: "xmlfile"
        - file_path: "D:\\Dev\\httprunner\\HttpRunner-master1.4.1\\HttpRunner-master\\examples"
        - file_type: "text/xml"
        - multipart_encoder: ${multipart_encoder($field_name, $file_path, $file_type)}
    request:
        url: http://jobws.push.mobile.xxxxxxxx.com/RefreshWeiXInTokenJob/RefreshService.asmx
        method: POST
        headers:
            Content-Type: ${multipart_content_type($multipart_encoder)}
        data: $multipart_encoder
    validators:
        - eq: ["status_code", 200]

@debugtalk
Copy link
Member Author

@julianmail 你用的版本是?

@julianmail
Copy link

现在用的是1.4.1的版本

@strayberry
Copy link

一个请求内上传两个文件的话data的写法应该是怎么样的呢

@jcuan
Copy link

jcuan commented Nov 1, 2018

其实可以直接使用request提供的文件上传功能

- test:
    name: file
    variables:
        - file_path: d:\code\python\worktest\test.py
        - mode: 'rb'
    request:
        url: /
        method: POST
        data: #表单数据
            name: jcuan
        files: #文件数据
            fileKey: 
                - test.html #文件名
                - ${open($file_path,$mode)}	#文件内容,通过open打开
                - text/html #content-type

@debugtalk
Copy link
Member Author

@jcuan 这种方式在解决 #418 之前是不行的。在解决之后我还没试过,你有测试过么?

@jcuan
Copy link

jcuan commented Nov 1, 2018

@debugtalk 原来是这样,我这边是正常的

win 10
python 3.7.1
httprunner 1,5.14

================== request details ==================
url              : 'http://127.0.0.1/'
method           : 'POST'
headers          : {'User-Agent': 'python-requests/2.18.4', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive', 'Host': 'jcuan.xyz', 'Content-Length': '1960', 'Content-Type': 'multipart/form-data; boundary=f9f42fe8911c4000bba3f5aee2057a62'}
start_timestamp  : 1541044111.9319515
verify           : False
data             : {'name': 'jcuan'}
files            : {'fileKey': ['test.html', <_io.BufferedReader name='d:\\code\\python\\worktest\\test.py'>, 'text/html']}

@debugtalk debugtalk added the docs Need to add some docs label Nov 2, 2018
@holysor
Copy link

holysor commented Nov 29, 2018

请问如何在上传文件,同时在data上加入参数
image

@huiCSDN
Copy link

huiCSDN commented Dec 28, 2018

请问如何在上传文件,同时在data上加入参数
image

您好,你这个上传文件时,再添加其他参数的问题解决了吗

@dreamer1314
Copy link

httprunner版本:2.0.5
执行上面的demo,报找不到
VariableNotFound: multipart_encoder is not found.
屏幕快照 2019-04-22 下午8 15 51

@xtander
Copy link

xtander commented May 24, 2019

和楼上一样的版本一样的问题,VariableNotFound: multipart_encoder is not found

@weigun
Copy link

weigun commented Jun 18, 2019

一个请求内上传两个文件的话data的写法应该是怎么样的呢

有解决方法了吗?我也需要上传多个文件呢

@ouylongzhou
Copy link

ouylongzhou commented Jun 19, 2019

@jcuan 麻烦问下,我的环境跟你的差不多,上传文件失败,files跟你的一样,但在前端查看请求files内容为空的
##########################打印的格式请求##########################
image

#######################前端页面操作的请求###########################
image

@jcuan
Copy link

jcuan commented Jun 19, 2019

@ouylongzhou 我刚刚又试了一下是可以的,你没有设置content-type吧(不能设置,否则会缺少boundary)?

- config:
    name: local test
    request:
        base_url: http://127.0.0.1:8000
        verify: false
        headers:
            User-Agent: python-requests/2.18.4


- test:
    name: file
    variables:
        - file_path: /Users/jcuan/code/python/httprunner/file.txt
        - mode: 'rb'
    request:
        url: /
        method: POST
        data: 
            name: jcuan
        files: 
            fileKey: 
                - fileRename.txt
                - ${open($file_path,$mode)}
                - text/plain

server收到的信息, 文本表单、文件、还有文件内容都是正常的

Array
(
    [name] => jcuan
)
Array
(
    [name] => fileRename.txt
    [type] => text/plain
    [tmp_name] => /private/var/folders/c8/9lrr5s1j3cdbxr2k7jlhtg2m0000gp/T/phpQ9wSqL
    [error] => 0
    [size] => 22
)

file content for test!

@hstart
Copy link

hstart commented Sep 19, 2019

1、jcuan 说的是正解。
2、从httprunner的源码来看,底层用的是requests.Session.request 这个来发送http请求。
3、而且 requests.Session.request 中参数恰好是 测试文件里面所配置的,换位dic格式 ,所以依据requests.Session.request 输入参数,可以直接在测试案例里面添加 files 这个字段。
4、使用的是注意的地方是 案例里面不要配置Content-type 字段,否则会出现问题。原因是如果是files参数,request会自动在header里面添加相关参数,不用人工添加。
5、以下是一个例子:

    request:
        headers:
            User-Agent:Android Client
        method: POST
        url: http://xxx.xx.xx.xx//upload
        files: 
            chnCode: 
                -
                - TEST
            fileDesc:
                -
                - HUAWEI NXT-AL10
            filecontent: 
                - $file_name
                - ${open(file.dat)}
                - application/octet-stream

6、例子说明:对于非文件参数,则第一个参数留空,第二参数才是值,对于json 格式 空用null字符代替。
7、files 的参数类型常用以下几种方式(详细参考: https://blog.csdn.net/qq_36502272/article/details/90675314 )。

{
 "field1": (名称, 值, 类型)
 "field1": (None, "字符串值")
 "field1": ("1.jpg", open("1.jpg"), "image/jpg")
}

@debugtalk
Copy link
Member Author

@hstart 使用 requests files 进行上传会存在问题,当上传文件非常大的时候,占用内容会非常高。

In the event you are posting a very large file as a multipart/form-data request, you may want to stream the request. By default, requests does not support this, but there is a separate package which does - requests-toolbelt. You should read the toolbelt’s documentation for more details about how to use it.

Requests has support for multipart uploads, but the API means that using that functionality to build exactly the Multipart upload you want can be difficult or impossible. Additionally, when using Requests’ Multipart upload functionality all the data must be read into memory before being sent to the server. In extreme cases, this can make it impossible to send a file as part of a multipart/form-data upload.

https://toolbelt.readthedocs.io/en/latest/uploading-data.html#streaming-multipart-data-encoder
https://2.python-requests.org//en/latest/user/quickstart/#post-a-multipart-encoded-file

@debugtalk debugtalk mentioned this issue Dec 12, 2019
@debugtalk
Copy link
Member Author

最终方案:https://docs.httprunner.org/prepare/upload-case/

对于上传文件类型的测试场景,HttpRunner 集成 requests_toolbelt 实现了上传功能。

在使用之前,确保已安装如下依赖库:

使用内置 upload 关键字,可轻松实现上传功能(适用版本:2.4.1+)。

- test:
    name: upload file
    request:
        url: http://httpbin.org/upload
        method: POST
        headers:
            Cookie: session=AAA-BBB-CCC
        upload:
            file: "data/file_to_upload"
            field1: "value1"
            field2: "value2"
    validate:
        - eq: ["status_code", 200]

同时,你也可以继续使用之前描述形式(适用版本:2.0+)。

- test:
    name: upload file
    variables:
        file: "data/file_to_upload"
        field1: "value1"
        field2: "value2"
        m_encoder: ${multipart_encoder(file=$file, field1=$field1, field2=$field2)}
    request:
        url: http://httpbin.org/upload
        method: POST
        headers:
            Content-Type: ${multipart_content_type($m_encoder)}
            Cookie: session=AAA-BBB-CCC
        data: $m_encoder
    validate:
        - eq: ["status_code", 200]

参考案例:httprunner/tests/httpbin/upload.v2.yml

@ycooperz
Copy link

ycooperz commented Mar 6, 2020

对于文件请求方式以PUT上传oss服务器,如何处理呢?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs Need to add some docs
Projects
None yet
Development

No branches or pull requests