Python3+pytest框架系列---2

一、项目及框架搭建

1、项目环境工具

 

 

  •  python   https://www.python.org/downloads/
  • pycharm   http://www.jetbrains.com/pycharm/
  • git                https://git-scm.com/download

2、配置

Pycharm配置

配置python解释器 :Settings -> Project -> Project Interpreter

配置git解释器: Settings -> Version Control -> Git

Pycharm+Git配置

配置github :Settings -> Version Control -> GitHub

创建github项目:https://github.com/

上传github :增加忽略文件需要 安装.ignore插件,上传需配置github

二、requests

1、requests介绍及简单使用

(1)Requests介绍

流行的接口http(s)请求工具

使用功能强大、简单方便、容易上手

(2)Requests简单使用

安装Requests包

 $ pip3 install requests

简单使用

import requests

requests.get("http://www.baidu.com")

Requests请求返回介绍

r.status_code #响应状态

r.content #字节方式的响应体,会自动为你解码 gzip 和 deflate 压缩

r.headers #以字典对象存储服务器响应头,若键不存在则返回None

r.json() #Requests中内置的JSON

r.url # 获取url r.encoding # 编码格式

r.cookies # 获取cookie

r.raw #返回原始响应体

r.text #字符串方式的响应体,会自动根据响应头部的字符编码进行

r.raise_for_status() #失败请求(非200响应)抛出异常

 2、request用例编写

  • 编写登录用例脚本

url = "http://172.17.0.139:5004/authorizations/"

data = {"username":"python", "password":"12345678"}

r= requests.post(url,json=data)

  • 编写个人信息获取脚本

url = "http://172.17.0.139:5004/user/"

headers = '{"Authorization": "JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1NjUwNjMwOTksInVzZXJfaWQiOjEsImVtYWlsIj oiOTUyNjczNjM4QHFxLmNvbSIsInVzZXJuYW1lIjoicHl0aG9uIn0.f3GdeSnzb3UGsw1p1ejZ1rNLaaiBOAHUnN8_pq8LDE"}'

r = requests.get(url,headers=headers)

  • 商品列表数据

url = "http://172.17.0.139:5004/categories/115/skus"

data = {  "page":"1", "page_size": "10", "ordering": "create_time"}

r = requests.get(url, json=data)

print(r.text)

print(r.json)

添加到购物车

def cart():

url = "http://172.17.0.139:5004/cart/"

data = { "sku_id": "3", "count": "1", "selected": "true"}

headers = {"Authorization": "JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1NjU4NTU2NzcsInVzZXJfaWQiOjEsImVtYWlsIj oiOTUyNjczNjM4QHFxLmNvbSIsInVzZXJuYW1lIjoicHl0aG9uIn0.yotHV8wMX7MKHyioFDaGnrjTDTAYsLB0R 8Qsungw_ms"}

r = requests.post(url, json=data,headers=headers)

print(r.text)

print(r.json)

def get_cart():

url = "http://172.17.0.139:5004/cart/"

headers = { "Authorization": "JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1NjU4NTU2NzcsInVzZXJfaWQiOjEsImVtYWlsIj oiOTUyNjczNjM4QHFxLmNvbSIsInVzZXJuYW1lIjoicHl0aG9uIn0.yotHV8wMX7MKHyioFDaGnrjTDTAYsLB0R 8Qsungw_ms"}

r = requests.get(url, headers=headers)

print(r.text)

print(r.json)

保存订单

def orders():

url = "http://172.17.0.139:5004/orders/"

data = { "address": "1", "pay_method": "1"}

headers = {"Authorization": "JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1NjU4NTU2NzcsInVzZXJfaWQiOjEsImVtYWlsIj oiOTUyNjczNjM4QHFxLmNvbSIsInVzZXJuYW1lIjoicHl0aG9uIn0.yotHV8wMX7MKHyioFDaGnrjTDTAYsLB0R 8Qsungw_ms"}

r = requests.post(url, json=data,headers=headers)

print(r.text)

print(r.json)

3、Requests方法封装

封装requests get方法

#1、创建封装get方法

def requests_get(url,headers):

#2、发送requests get请求

   r = requests.get(url,headers = headers)

#3、获取结果相应内容

  code = r.status_code

   try:

    body = r.json()

  except Exception as e:

    body = r.text

#4、内容存到字典

  res = dict()

  res["code"] = code

  res["body"] = body

#5、字典返回

  return res

封闭requests post方法

#post方法封装

#1、创建post方法

def requests_post(url,json=None,headers=None):

#2、发送post请求

  r= requests.post(url,json=json,headers=headers)

#3、获取结果内容

  code = r.status_code

   try:

    body = r.json()

   except Exception as e:

    body = r.text

#4、内容存到字典

  res = dict()

  res["code"] = code

  res["body"] = body

#5、字典返回

  return res

封装requests公共方法

  • 增加cookies,headers参数
  • 根据参数method判断get/post请求

def requests_api(self,url,data = None,json=None,headers=None,cookies=None,method="get"):

  if method =="get":

  #get请求

    self.log.debug("发送get请求")

    r = requests.get(url, data = data, json=json, headers=headers,cookies=cookies)

  elif method == "post":

  #post请求

    self.log.debug("发送post请求")

    r = requests.post(url,data = data, json=json, headers=headers,cookies=cookies)

  #2. 重复的内容,复制进来

  #获取结果内容

  code = r.status_code

  try:

    body = r.json()

  except Exception as e:

    body = r.text

  #内容存到字典

  res = dict()

  res["code"] = code

   res["body"] = body

  #字典返回

  return res

重构get方法

  • 调用公共方法request_api,
  • 参数:固定参数:url,method
  • 其它参数: **args

#1、定义方法

def get(self,url,**kwargs):

#2、定义参数

#url,json,headers,cookies,method

#3、调用公共方法

  return self.requests_api(url,method="get",**kwargs)

重构post方法

  • 调用公共方法request_api,
  • 参数:固定参数:url,method
  • 其它参数: **args

def post(self,url,**kwargs):

#2、定义参数 #url,json,headers,cookies,method

#3、调用公共方法

  return self.requests_api(url,method="post",**kwargs)

三、配置文件

1、Yaml 介绍及安装

  • Yaml 介绍

Yaml 是一种所有编程语言可用的友好的数据序列化标准。语法和其他高阶语言类似,并且可以简单表达字 典、列表和其他基本数据类型的形态。语法规则如下:

1. 大小写敏感。

2. 使用缩进表示层级关系。

3. 使用空格键缩进,而非Tab键缩进

4. 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可。

5. 文件中的字符串不需要使用引号标注,但若字符串包含有特殊字符则需用引号标注;

6. 注释标识为# 官网:https://yaml.org/

  • Yaml 安装

$ pip3 install PyYaml

  • Yaml 快速体验

    字典{"name": "test_yaml", "result", "success"}写成Yaml的形式,并输出结果 结构通过空格缩进来展示。

    列表里的项用"-"来代表,字典里的键值对用":"分隔.

    示例函数:

    data.yaml 

     name: "test_yaml"

     result: "success"

    demo.py

    import yaml

     with open("./data.yaml",'r') as f:

      data = yaml.safe_load(f)

      print(data)

    运行结果:

    {'name': 'test_yaml', 'result': 'success'}

 

2、Yaml 字典和列表介绍

 (1)字典

字典里的键值对用":"分隔.

示例: {"name": "test_yaml", "result", "success"}

name: "test_yaml"

age: "success"

总结: 字典直接写key和value,每一个键值对占一行。 : 后面要有空格

(2)列表

一组按序排列的值(简称 "序列或列表")

数组前加有 “-” 符号,符号与值之间需用空格分隔

示例:["a", "b", "c"]

- "a"

- "b"

- "c"

列表中的元素需要用 -来表示

每一个元素前面都有一个 -,后面接元素内容

3、Yaml 字典和列表基本操作

(1)字典嵌套字典

需求:

{

  person1:{

    "name": "xiaoming",

    "age": "18"

  },

  person2: {

    "name": "xiaohong",

    "age": "20"

  }

}

示例:

person1:

  name: "xiaoming"

  age: "18"

person2:

  name: "xiaohong"

  age: "20"

(2)字典嵌套列表

需求:

{person: ["1", "2", "3"]}

示例 :

persion:

- "1"

- "2"

- "3"

(3)列表嵌套字典

需求:

[{ "username1": "test1" }, { "password1": "111", "username2": "test2", "password2": "222" }]

示例:

- username1: "test1"

- password1: "111"

 username2: "test2"

 password2: "222"

(4)列表嵌套列表

需求:

[["a","b","c"],["1","2","3"]]

示例:

-

  - "a"

  - "b"

  - "c"

-

  - "1"

  - "2"

  - "3"

注意:

  • pycharm会自动将yaml中的tab转化成空格。但是不能复制”tab键“,不会进行转化。
  • 同级别左侧必须要对齐,少个空格无所谓。

4、读取yaml文件

(1)读取单个Yaml文档

yaml文档

#data.yaml

"用户名称": "test123"

"密码": "123456"

示例函数:demo.py 中文问题(windows): encoding='utf-8

import yaml

# 打开要读取的文件,中文 encoding='utf-8'

with open("./data.yaml", 'r', encoding='utf-8') ) as f:

  # 加载文件内容

  data = yaml.safe_load(f)

  # 打印结果

  print(data)

读取实际上就是先使用 with open 的形式获取文件对象,再使用 yaml 中的 load 方法加载这个文件对象,通过 过load方法,一个字符串变成了一个字典

结果: {'用户名称': 'test123', '密码': '123456'}

(2)读取多个Yaml文档

多个文档在一个yaml文件,使用 --- 分隔方式来分段

yaml文档:

---

"用户名称1": "test123"

"密码": "123456"

---

"用户名称2": "test456"

"密码": "123456"

示例:

import yaml

with open("./data.yaml",'r') as f:

  data = yaml.safe_load_all(f)

  for i in data:

    print(i)

结果:

{'用户名称1': 'test123', '密码': '123456'}

{'用户名称2': 'test456', '密码': '123456'}

5、yaml封装

import os

import yaml

#1、创建类

class YamlReader:

#2、初始化,文件是否存在

  def __init__(self,yamlf):

    if os.path.exists(yamlf):

      self.yamlf = yamlf

    else:

      raise FileNotFoundError("文件不存在")

    self._data = None

    self._data_all = None

#3、yaml读取

#单个文档读取

  def data(self):

    #第一次调用data,读取yaml文档,如果不是,直接返回之前保存的数据

    if not self._data:

      with open(self.yamlf,"rb") as f:

        self._data = yaml.safe_load(f)

    return self._data

#多个文档读取

  def data_all(self):

    #第一次调用data,读取yaml文档,如果不是,直接返回之前保存的数据

    if not self._data_all:

      with open(self.yamlf,"rb") as f:

        self._data_all = list(yaml.safe_load_all(f))

  return self._data_all

6、配置文件设置

(1)配置文件conf.yaml

BASE:

  #log等级

   log_level: "debug"

  #扩展名

   log_extension: ".log"

  test:

    url: "http://XXX"

    case_file: "testdata.xlsx"

    case_sheet: "接口测试"

(2)基本目录配置

 import os

from utils.YamlUtil import YamlReader

#1、获取项目基本目录

#获取当前项目的绝对路径

current = os.path.abspath(__file__)

#print(current)

BASE_DIR = os.path.dirname(os.path.dirname(current))

#print(BASE_DIR)

#定义config目录的路径

_config_path = BASE_DIR + os.sep + "config"

#定义data目录的路径

_data_path = BASE_DIR + os.sep + "data"

#定义conf.yml文件的路径

_config_file = _config_path + os.sep +"conf.yml"

#定义db_conf.yml路径

_db_config_file = _config_path + os.sep +"db_conf.yml"

#定义logs文件路径

_log_path = BASE_DIR + os.sep + "logs"

#定义report目录的路径

_report_path = BASE_DIR + os.sep + "report"

def get_report_path():

  """

  获取report绝对路径

  :return:

  """

  return _report_path

def get_data_path():

  return _data_path

def get_db_config_file():

  return _db_config_file

def get_config_path():

  return _config_path

def get_config_file():

  return _config_file

def get_log_path():

  return _log_path

(3)conf.yml配置文件读取

#2、读取配置文件

class ConfigYaml:

#初始yaml读取配置文件

  def __init__(self):

    self.config = YamlReader(get_config_file()).data()

    self.db_config = YamlReader(get_db_config_file()).data()

#获取测试用例excel名称

def get_excel_file(self):

  return self.config["BASE"]["test"]["case_file"]

#获取测试用例sheet名称

def get_excel_sheet(self):

  return self.config["BASE"]["test"]["case_sheet"]

#获取环境的URL

def get_conf_url(self):

  return self.config["BASE"]["test"]["url"]

#获取日志级别

def get_conf_log(self):

  return self.config["BASE"]["log_level"]

#获取文件扩展名

def get_conf_log_extension(self):

  return self.config["BASE"]["log_extension"]

#根据db_alias获取该名称下的数据库信息

def get_db_conf_info(self,db_alias):

  return self.db_config[db_alias]

#获取邮件配置相关信息

def get_email_info(self):

  return self.config["email"]

posted @ 2021-05-28 16:15  丝瓜呆呆  阅读(332)  评论(0编辑  收藏  举报