Python 接口测试之处理转义字符的参数和编码问题

引言

笔者,在非常繁忙的工作之余,决定抽时间记录一下在测试接口时所遇到的问题,以便日后参考,也可以提供给那些正在学习的接口测试的伙伴参考,避免走弯路。如果对您有帮忙,点个赞,谢谢。

今天这篇文章主要是讲接口测试中请求参数包含转义字符的和返回参数包含转义字符的处理,之前关于接口测试方法

处理入参有转义字符的接口

1、首先,看一下我的接口中入参的数据样式:

 这个body中的参数有两个“body”和“method”,整个data变量是一个字典,但是“body”是个字符串,并且是包含转义字符,整个就是一个转义字符串。这种参数写代码里面是没问题的,但是作为接口请求时,有时候无法被json解析,最终导致接口请求失败。

这种参数,不处理,直接去请求,就像下图所示:

 2、目标已经确定,接下来就是处理了,我先将data数据反转义,其实很简单,用的是json的一个方法loads(),如图:

在用这个方法时,还要提前处理一下data,因为该方法支持类型有限制,如:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

def loads(s, *, encoding=None, cls=None, object_hook=None, parse_float=None,

        parse_int=None, parse_constant=None, object_pairs_hook=None, **kw):

    """Deserialize ``s`` (a ``str``, ``bytes`` or ``bytearray`` instance

    containing a JSON document) to a Python object.

    ``object_hook`` is an optional function that will be called with the

    result of any object literal decode (a ``dict``). The return value of

    ``object_hook`` will be used instead of the ``dict``. This feature

    can be used to implement custom decoders (e.g. JSON-RPC class hinting).

    ``object_pairs_hook`` is an optional function that will be called with the

    result of any object literal decoded with an ordered list of pairs.  The

    return value of ``object_pairs_hook`` will be used instead of the ``dict``.

    This feature can be used to implement custom decoders that rely on the

    order that the key and value pairs are decoded (for example,

    collections.OrderedDict will remember the order of insertion). If

    ``object_hook`` is also defined, the ``object_pairs_hook`` takes priority.

    ``parse_float``, if specified, will be called with the string

    of every JSON float to be decoded. By default this is equivalent to

    float(num_str). This can be used to use another datatype or parser

    for JSON floats (e.g. decimal.Decimal).

    ``parse_int``, if specified, will be called with the string

    of every JSON int to be decoded. By default this is equivalent to

    int(num_str). This can be used to use another datatype or parser

    for JSON integers (e.g. float).

    ``parse_constant``, if specified, will be called with one of the

    following strings: -Infinity, Infinity, NaN.

    This can be used to raise an exception if invalid JSON numbers

    are encountered.

    To use a custom ``JSONDecoder`` subclass, specify it with the ``cls``

    kwarg; otherwise ``JSONDecoder`` is used.

    The ``encoding`` argument is ignored and deprecated.

    """

我先将data转成str,如图:

之所以贴个报错的截图,这里有个知识点,教给大家。

python字符串是有层次的,比如使用''' '''和" "和‘ ’,所以不能像上图那样使用两个" "。

修改之后,执行调用接口程序:

 这个返回结果就是我想要的。

入参的转义讲完,那么出参的呢? 留给大家思考。

编码处理

很多时候返回的数据中,有中文和二进制数据,先看一下接口返回的未处理的数据,显示如下:

 这种数据,第一不方便查看,第二很难找到自己想要的值。

1

print(r2.content.decode(),end=' ')

运行脚本:

1

UnicodeEncodeError: 'gbk' codec can't encode character '\xe2' in position 15788: illegal multibyte sequence

这句话说的是gbk无法encode编码,但是我代码编码是utf-8,显然不是代码问题。错误位置在'\xe2'是无法被解码。加一下标准输出代码:

1

2

3

import io

import sys

sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='gb18030')         #改变标准输出的默认编码

再次执行程序,结果显示成功:

 需要注意的是,如果gb18030不行的话,就用utf-8,如:

1

sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='utf8') #改变标准输出的默认编码

还可以改成:

1

sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='gbk')

下面是一些中文对应的编码表格:

编码名称用途
utf8所有语言
gbk简体中文
gb2312简体中文
gb18030简体中文
big5繁体中文
big5hkscs繁体中文

原因说明:对于Unicode字符,需要print出来的话,由于本地系统是Windows中的cmd,默认codepage是CP936,即GBK的编码,所以python解释器需要先将上述的Unicode字符编码为GBK,然后再在cmd中显示出来。但是由于该Unicode字符串中包含一些GBK中无法显示的字符,导致此时提示“’gbk’ codec can’t encode”的错误的。其实print()函数的局限就是Python默认编码的局限,因为系统是windows的,python的默认编码不是'utf-8',改一下python的默认编码成'utf-8'就行了。

  接口请求方式

引言中已经说过,如果对requests请求不了解,可以参考我的这篇文章Python 接口测试requests.post方法中data与json参数区别。这篇文章讲过post请求的两种数据类型data和json,那么针对body数据中有转义字符的数据,如何同时使用这两种参数类型请求呢?在讲之前,先复习一下知识点:

1

2

3

4

5

6

7

resp.text返回的是Unicode型的数据。

resp.content返回的是bytes型的数据。

resp.json()返回的是json格式数据

#备注:

#如果你想取文本,可以通过r.text。

#如果想取图片,文件,则可以通过r.content。

#如果想要dict类型的数据,则可以通过r.json()。

具体脚本:

结果如下:

不管你选择data类型和json类型,只要传参的类型对应上就完全没问题。这里没有直接贴脚本代码,也是让初学者自己动手敲,不能直接Copy用,这样对自己编码提升会有阻碍。

提取报文中参数

如何取出返回结果中的key对应的values,比如这个接口我是要获取warehouseName这个字段的值,如图:

从数据上看,返回的数据类型是字典,而我要获取的字典warehouseName是在字典中data里,data 是字典,里面还有个列表,列表中也有个字典,等于嵌套了4层,如何取出4层的中里面值呢?这要分两步操作,具体请看代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

# 取出字典中的key对应的值

a = r.json()

b =a['data']['wimslist']

# print(type(dict(b)))

c = json.dumps(b, ensure_ascii=False)

# 方法1

for item in b:print (item['warehouseName'],end=' ')

# 方法2

# 获取list中字典的key值

list_result = []

for in b:

    list_result.append(i['warehouseName'])

print(list_result)

from common.loggers import Log

loggger = Log()

输出结果如下:

附录

1、这里贴出关于(字符串前面u,r,b)的知识点,加深印象,如果没有了解过,就当学习一下,以后自然会用到。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

1、字符串前加 u

例:u"我是含有中文字符组成的字符串。"

作用:

后面字符串以 Unicode 格式 进行编码,一般用在中文字符串前面,防止因为源码储存格式问题,导致再次使用时出现乱码。

2、字符串前加 r

例:r"\n\n\n\n”  # 表示一个普通生字符串 \n\n\n\n,而不表示换行了。

作用:

去掉反斜杠的转义机制。

(特殊字符:即那些,反斜杠加上对应字母,表示对应的特殊含义的,比如最常见的”\n”表示换行,”\t”表示Tab等。 )

应用:

常用于正则表达式,对应着re模块。

3、字符串前加 b

例: response = b'<h1>Hello World!</h1>' # b' ' 表示这是一个 bytes 对象

作用:

b" "前缀表示:后面字符串是bytes 类型。

用处:

网络编程中,服务器和浏览器只认bytes 类型数据。

如:send 函数的参数和 recv 函数的返回值都是 bytes 类型

附:

在 Python3 中,bytes 和 str 的互相转换方式是

str.encode('utf-8')

bytes.decode('utf-8')

2、关于python编码基础知识,字符串和字节流之间转换如下图:

 

总结:

感谢每一个认真阅读我文章的人!!!

作为一位过来人也是希望大家少走一些弯路,如果你不想再体验一次学习时找不到资料,没人解答问题,坚持几天便放弃的感受的话,在这里我给大家分享一些自动化测试的学习资源,希望能给你前进的路上带来帮助。

软件测试面试文档

我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

 

          视频文档获取方式:
这份文档和视频资料,对于想从事【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!以上均可以分享,点下方小卡片即可自行领取。

  • 14
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值