关于查询类接口的一些总结

由于项目需要,最近在写一个接口测试脚本,所以许久没有更新了,不过写完后,也有一些收获和大家分享一下

本次写的主要是查询类接口,所以重点说一下编写查询类接口时用到的一些方法

1. 按照日期查询

这类查询功能,在平时测试时往往需要选定一个日期,点击查询,然后查看列表中列出的结果是否符合预期

那么针对日期类的查询,如何构造有效的参数呢

要考虑一点:如何使所选定的日期长久有效

假如选定2019-05-01至2019-05-29,

它存在的问题是,到了2020年再执行这个脚本时,数据就显得比较旧,甚至由于清除数据库脏数据,再也查不到结果了,所以尽量不要指定日期

 

有一个解决方法,先获取当前日期,然后往前倒退30天、50天等

例如今天是2019-10-29,那就查询2019-09-29至2019-10-29的数据,永远以当前日期为基准

获取当前日期,可以用python自带的datetime模块

#coding:UTF-8

import datetime

now_date = datetime.datetime.now()  # 获取今天时间
# print(now_date)
end_date = now_date.strftime("%Y-%m-%d")  # 定义今天时间为查询结束时间,并转为字符串对象,以年-月-日格式输出
offset = datetime.timedelta(days=-50)  # 定义偏移量,即与当前日期的时间间隔
begin_date = (now_date + offset).strftime("%Y-%m-%d")  # 定义查询开始时间=当前时间回退50天

2. 从一批响应内容中随机取出一个进行断言

使用random.choice()方法,从一组数据中随机取出一个,一般是从一个列表、元祖或字符串中抽取数据

假如一个查询接口中返回了多组数据,每组数据的构造相似,这时做断言的话,不可能每个数据都匹配一次

如下拉勾网搜索一个职位时

 

可以看到result列表中包含许多条职位信息,每个职位信息都各自在一个json字符串中,断言时,只需取其中一组数据即可;

问题来了,选哪一组进行断言,第一组?最后一组?指定一组?

第一组可以达到目的,最后一组也行

但是指定断言一组不靠谱,因为这次查询可能返回了3组,下次可能返回了2组

还有一种方式,就是随机取一组数据进行断言,

这时候就可以使用random.choice()方法,从所有返回结果中随机取出一组数据,再将那一组数据的某个值与预期断言即可

示例:

>>>import random
>>>numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>random.choice(numbers)
5
>>> for i in range(3): # 循环8次,每次随机取一个数
  random.choice(numbers)
4
4
9

之前写过一个电话号码生成器(可以到历史文章中查看详细介绍),也用到了random.choice()

3.利用字符串切片断言电话号码后四位

有时候一些敏感信息需要进行脱敏处理,例如会把电话号码或身份证号码的中间几位进行加密处理,常见形式如下

188****8888

当以电话号码进行查询时,返回结果中一般也会把电话加密,不过既然是根据电话号码来查询,如果响应中有返回号码信息,最好还是用电话号码进行断言

这时候可以匹配电话号码的后四位,如果匹配成功则认为查询结果正确
因此可以使用切片方法来取出电话号码的后四位

>>> phone = "188****8888"
>>> phone
'188****8888'
>>> phone[-4:]
'8888'
>>>

4. 使用zip()函数遍历2个列表,将信息组合显示

场景:比如按照某个主题进行查询时,实际传参传的是该主题对应的编号,
例如『主题A』对应编号『11』,『主题B』对应编号『22』
在编写脚本时,我希望打出的日志更人性化,
可以打印出:查询『主题编号"11",对应的主题名称为"主题A"』的数据有xx条

由于主题名称和主题编号是在2个列表中,所以就想如何把2个列表关联起来呢? 能不能同时迭代2个列表,将主题名称与主题编号对应起来?

于是就找到了zip()函数

网上的一个简单例子:

>>> list1 = ['a', 'b', 'c', 'd']
>>> list2 = ['apple', 'boy', 'cat', 'dog']
>>> for x, y in zip(list1, list2):
      print(x, 'is', y)

# 输出
a is apple
b is boy
c is cat
d is dog

复杂一点的例子,列表中包含字典

>>> a = [{"first_name":1,"second_name":2,"third_name":3},
         {"first_name":4,"second_name":5,"third_name":6},
         {"first_name":7,"second_name":8,"third_name":9}]

b = [{"first":11,"second":22,"third":33},
     {"first":44,"second":55,"third":66},
     {"first":77,"second":88,"third":99}]

>>> for x,y in zip(a,b):
  print("一级主题名称:{},一级id:{}~二级主题名称:{},二级id:{}~三级主题名称:{},三级id:{}".format(x["first_name"],y["first"],x["second_name"],y["second"],x["third_name"],y["third"]))
 
 运行结果如下:
一级主题名称:1,一级id:11~二级主题名称:2,二级id:22~三级主题名称:3,三级id:33
一级主题名称:4,一级id:44~二级主题名称:5,二级id:55~三级主题名称:6,三级id:66
一级主题名称:7,一级id:77~二级主题名称:8,二级id:88~三级主题名称:9,三级id:99 

 5.format()函数在编写sql语句中的应用

python中的sql语句需要写在一对引号中,例如

original_sql = "select * from movies where movie_name = '疯狂动物城'"

上面语句中movie_name字段目前是一个固定值,假如切换环境执行,如果对应的数据库没有"疯狂动物城"这条数据,那么这个sql查询就会失效,返回为空

所以我们需要保证要查询的movie_name尽可能有值

 

假如此时有一个接口可以获取movie_name或者事先准备好一批movie_name值

那么就可以读取接口返回的movie_name或者读取提前准备好的amovie_name

 

因此需要想办法使sql语句中的movie_name参数化,能够动态读取传进来的值

仔细看上面的sql语句,注意到sql语句包含在一对引号中,所以它就相当于一个字符串,因此可以利用format()函数来达到目的

使用方法如下

movies = ["疯狂动物城", "坏蛋必须死", "冰雪奇缘"]

original_sql = "select * from movies where movie_name = '{}'"
# 注意因为sql中字符要用引号包裹,所以这里的{}也需要用引号括起来({}可以看作是一个预定的位置,存放movie_name的值)

for i in movies:
    sql = original_sql.format(i)
    print(sql)

运行结果

 

 

再来看例子,假如一个名为get_name()的方法,返回电影的名称,一个名为get_date()的方法,返回电影的上映日期
接下来要把电影名称和上映时间放到sql的查询条件中

original_sql = "select * from movies where movie_name = '{}' and release_date = '{}'"

sql = original_sql.format(self.get_name(), self.get_date())

另外format()函数也可以设置参数

上面的例子,可以改为

original_sql = "select * from movies where movie_name = '{name}' and release_date = '{date}'"

sql = original_sql.format(name=self.get_name(), date=self.get_date())

6.正则表达式提取中文字符

有时接口返回的某个字段值得时候,会自动加上某个后缀

例如姓名:张三qt,李四1,王五rw

 

其实数据库中存在的数据不带后缀,就是单纯的中文字符

例如:

select * from name_list where name = '张三'  #可以查到数据

select * from name_list where name = '张三qt' #查不到数据

 

所以在通过接口获取到这些数据后,需要处理一下,只保留中文字符,然后传给sql查询语句

这里通过正则表达式的方式来处理

import re

name = "张三rx"
pattern = re.compile(r'[\u4e00-\u9fa5]')  # 定义一个正则表达式,去掉字符串末尾的数字
m = pattern.findall(name)  # 匹配结果,返回每个汉字组成的列表
print(m)
real_name = "".join(m)  # 将每个汉字组成一个字符串
print(real_name)

运行结果

 

posted @ 2019-11-16 00:03  我是冰霜  阅读(2095)  评论(0编辑  收藏  举报