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字符串是有层次的,比如使用''' '''和" "和‘ ’,所以不能像上图那样使用两个" "。

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

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

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

现在我也找了很多测试的朋友,做了一个分享技术的交流群,共享了很多我们收集的技术文档和视频教程。
如果你不想再体验自学时找不到资源,没人解答问题,坚持几天便放弃的感受
可以加入我们一起交流。而且还有很多在自动化,性能,安全,测试开发等等方面有一定建树的技术大牛
分享他们的经验,还会分享很多直播讲座和技术沙龙
可以免费学习!划重点!开源的!!!
qq群号:110685036

编码处理

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

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

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编码基础知识,字符串和字节流之间转换如下图:

最后感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走!

软件测试面试文档

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

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值