基础练习

  1. 定义一个函数,生成一个随机的姓名。

📎fristname.txt 所有的姓
📎name.txt 名字、
自动化测试的应用场景: 在做接口测试时 申请贷款接口需要人名。随机生成一个姓名。
思路:
将文件中内容读取(解析)出来,放到列表中,通过随机函数随机选择一个。

  1. # 集合数据 有去重功能
  2. with open('name.txt',mode='r',encoding='utf8') as f:
  3. data = f.readlines()
  4. # 转换为集合
  5. data = set(data)
  6. # print(data)
  7. # 循环处理
  8. strname = ""
  9. for name in data:
  10. if name != "\n":
  11. name=name.replace(',\n',',')
  12. # print(name)
  13. strname= strname+name
  14. # 字符串去掉空格
  15. strname = strname.strip()
  16. # str 转换为list
  17. namelist = strname.split(',')
  18. # print(namelist)
  19. with open('fristname.txt', mode='r', encoding='utf8') as f:
  20. data = f.readlines()
  21. # print(data)
  22. first_names = []
  23. for firstnames in data:
  24. fnames = firstnames.strip()
  25. fn = fnames.split(',')
  26. # print(fn)
  27. first_names.extend(fn)
  28. # print(first_names)
  29. import random
  30. f = random.choice(first_names)
  31. n = random.choice(namelist)
  32. print(f+n)
  1. 随机生成电话号码。

    1. def generate_phone():
    2. """
    3. 生成一个随机的 11位手机号码
    4. :return:
    5. """
    6. #确定前两位手机
    7. pre_2 =["13","15","17","18"]
    8. # 随机选择一个元素
    9. p2 = random.choice(pre_2)
    10. # 生成9位随机数字
    11. l9 = ""
    12. for i in range(9):
    13. # 每次循环生成一个随机数字
    14. n = random.randint(0,9)
    15. l9 = l9+str(n) # 将数字转换为字符串之后进行拼接
    16. return p2+l9
  2. 随机生成身份证号。

    1. def generate_id():
    2. """
    3. 生成一个随机的身份证号 并返回
    4. :return:
    5. """
    6. # 拿到项目根目录
    7. root = get_project_root()
    8. # 拼接csv文件
    9. file_csv = os.path.join(root,'gb2260.csv')
    10. # 通过解析csv文件获取所有的地区编码
    11. all_code = parse_csv(file_csv)
    12. # print(all_code)
    13. # 随机选择一个列表
    14. code = random.choice(all_code)
    15. # print(code)
    16. # 列表转换为字符串
    17. p6 = ''.join(code)
    18. #print(p6)
    19. # 设置出生年月日
    20. year = random.randint(1960,2020)
    21. month = random.randint(1,12)
    22. # 闰年 2月份 29天
    23. if year%4==0 and month == 2:
    24. day=random.randint(1,29)
    25. # 31天
    26. elif month in [1,3,5,7,8,10,12]:
    27. day = random.randint(1,31)
    28. elif month in [4,6,9,11]:
    29. day = random.randint(1,30)
    30. # 平年的2月 28天
    31. else:
    32. day = random.randint(1,28)
    33. # month ,day 小于10 前面补0
    34. if month<10:
    35. month = f'0{month}'
    36. if day <10:
    37. day = f'0{day}'
    38. # 合并年月日 转换为字符串
    39. ymd = f'{year}{month}{day}'
    40. # print(ymd)
    41. # 获取最后4位 最后一位X
    42. l3 = ""
    43. for i in range(3):
    44. n = random.randint(0,9)
    45. # 数字转换字符串 拼接
    46. l3 = l3+str(n)
    47. l1 = list(range(10))
    48. l1.append("X") # [0,1,2,3,4,5,6,7,8,9,"X"]
    49. # print(l1)
    50. l = random.choice(l1) # 最后1位
    51. l4 = l3 + str(l) # 最后4位
    52. return f'{p6}{ymd}{l4}'

自动化练习

参数化练习

使用pytest+requests+csv 进行单接口的参数化测试
数据文件:📎home_topics.csv

  1. import requests
  2. import pytest
  3. # 编写代码,读取csv文件中的内容,读取成功之后将数据赋值给home_data 能够让这个测试用例跑起来
  4. @pytest.mark.parametrize("tab,limit,expect_tab,expect_limit",home_data)
  5. def test_home_page(tab,limit,expect_tab,expect_limit):
  6. url = "http://47.100.175.62:3000/api/v1/topics"
  7. querydata = {
  8. "tab":tab,
  9. "limit":limit
  10. }
  11. r = requests.get(url,params=querydata)
  12. #断言tab值
  13. for topic in r.json()["data"]:
  14. assert topic["tab"] == expect_tab
  15. # 断言limit
  16. assert len(r.json()["data"]) == expect_limit

参考:https://gitee.com/imzack/auto_aptest/blob/master/testcases/test_cnode_each_api.py

  1. import requests
  2. import pytest
  3. # 编写代码,读取csv文件中的内容,读取成功之后将数据
  4. import csv
  5. home_data = []
  6. # 解析csv文件中的内容
  7. with open('home_topics.csv',mode='r',encoding='utf8') as f:
  8. data = csv.reader(f)
  9. # 第一行数据不需要
  10. next(data) # 去掉第一行
  11. # 从第二行数据开始迭代
  12. for line in data:
  13. print(line)
  14. # 将数据追加到list
  15. home_data.append(tuple(line))
  16. print("data",home_data)
  17. @pytest.mark.parametrize("tab,limit,expect_tab,expect_limit",home_data)
  18. def test_home_page(tab,limit,expect_tab,expect_limit):
  19. url = "http://47.100.175.62:3000/api/v1/topics"
  20. querydata = {
  21. "tab":tab,
  22. "limit":int(limit) # csv文件中读出来的时候时 字符串,将字符串转换为int
  23. }
  24. r = requests.get(url,params=querydata)
  25. #断言tab值
  26. for topic in r.json()["data"]:
  27. assert topic["tab"] == expect_tab
  28. # 断言limit
  29. assert len(r.json()["data"]) == int(expect_limit) # 从csv文件中读取出来的时候为字符串类型,转换格式为int数字。

上下游传参+参数化

需要对两个接口进行参数化测试

  1. 搜索商品接口
  2. 添加购物车

练习题 - 图1
做这两个接口的前提条件是 用户已经成功登录,获取到token值。
通过使用 pytest的脚手架功能 @pytest.fixture 将登录操作放进来生成token值。

  1. '''
  2. 新丰商城 单接口测试
  3. '''
  4. import pytest
  5. from common.utils import generate_phone
  6. import requests
  7. testdata={
  8. "token":"",
  9. "goodsid":0 # 商品的id
  10. }
  11. base_url = "http://49.233.108.117:28019"
  12. # 注册,登录使用的是同一个手机号码 定义变量
  13. phone = generate_phone()
  14. #scope="module" 模块级别, 整个python文件运行之前和之后的操作 整个文件运行之前生成1个token
  15. @pytest.fixture(scope="module",autouse=True)
  16. def token():
  17. # 脚手架中注册并登录一个账号
  18. # 注册用户
  19. url = base_url+"/api/v1/user/register"
  20. body_data = {
  21. "loginName": phone,
  22. "password": "123456"
  23. }
  24. # 发送请求
  25. requests.post(url,json=body_data)
  26. # 登录用户
  27. url = base_url + "/api/v1/user/login"
  28. body_data = {
  29. "loginName": phone,
  30. "passwordMd5": "E10ADC3949BA59ABBE56E057F20F883E"
  31. }
  32. r = requests.post(url, json=body_data)
  33. # 设置 token
  34. # 提取变量值 token
  35. testdata["token"] = r.json()["data"]
  36. # 运行之前的所有操作
  37. print("已经成功获取一个token值",r.json()["data"])
  38. yield
  39. search_data=['iphone','小米','华为']
  40. @pytest.mark.parametrize("key",search_data)
  41. def test_search(key):
  42. url = base_url+'/api/v1/search'
  43. header={
  44. "token": testdata["token"]
  45. }
  46. query_data={
  47. "keyword":key
  48. }
  49. # 搜索条件为 iphone
  50. r = requests.get(url, params=query_data, headers=header)
  51. # 断言
  52. # 所有搜索结果中都包含iphone
  53. # 拿到所有的商品信息
  54. allgoods = r.json()["data"]["list"]
  55. # 循环所有商品的时候
  56. for good in allgoods:
  57. print(good)
  58. # 拿到每个商品的名称
  59. goodname = good["goodsName"]
  60. # print('商品的名称', goodname) # 因为返回结果中有大小写字母混合的场景。使用字符串转换大写方法
  61. assert key.upper() in goodname.upper() # upper 将字符串转为大写
  62. # 提取商品id 给下游接口
  63. testdata["goodsid"] = good["goodsId"]
  64. print("传递的参数数据",testdata["goodsid"])
  65. #商品的id 从搜索接口中获取
  66. cart_data = [
  67. (0,0),
  68. ("${goodsid}",0), # ${goodsid} 表示具体的商品id
  69. ("${goodsid}",1),
  70. ("${goodsid}",10)
  71. ]
  72. @pytest.mark.parametrize("goodsId,count",cart_data)
  73. def test_add_cart(goodsId,count):
  74. if goodsId =="${goodsid}":
  75. goodsId = testdata["goodsid"] # 替换为具体的值
  76. url = base_url+"/api/v1/shop-cart"
  77. body_data ={
  78. "goodsCount": count,
  79. "goodsId": goodsId
  80. }
  81. header = {
  82. "token": testdata["token"]
  83. }
  84. print("加入购物车数据",body_data)
  85. r = requests.post(url,json=body_data,headers=header)
  86. print("购物车返回结果",r.json())

运行可以看到执行的结果
练习题 - 图2