网站初期seo怎么做网站建设公司如何选取
目录:
- pytest结合数据驱动-yaml
 - pytest结合数据驱动-excel
 - pytest结合数据驱动-csv
 - pytest结合数据驱动-json
 - pytest测试用例生命周期管理(一)
 - pytest测试用例生命周期管理(二)
 - pytest测试用例生命周期管理(三)
 - pytest测试用例生命周期管理-自动注册
 - pytest测试用例生命周期管理-自动生效
 - pytestfixture实现参数化
 
1.pytest结合数据驱动-yaml
数据驱动
-  
什么是数据驱动?
- 数据驱动就是数据的改变从而驱动自动化测试的执行,最终引起测试结果的改变。简单来说,就是参数化的应用。数据量小的测试用例可以使用代码的参数化来实现数据驱动,数据量大的情况下建议大家使用一种结构化的文件(例如 yaml,json 等)来对数据进行存储,然后在测试用例中读取这些数据。
 
 -  
应用:
- App、Web、接口自动化测试
 - 测试步骤的数据驱动
 - 测试数据的数据驱动
 - 配置的数据驱动
 
 
yaml 文件介绍
- 对象:键值对的集合,用冒号 “:” 表示
 - 数组:一组按次序排列的值,前加 “-”
 - 纯量:单个的、不可再分的值 
- 字符串
 - 布尔值
 - 整数
 - 浮点数
 - Null
 - 时间
 - 日期
 
 
# 编程语言
languages:- PHP- Java- Python
book:Python入门: # 书籍名称price: 55.5author: Lilyavailable: Truerepertory: 20date: 2018-02-17Java入门:price: 60author: Lilyavailable: Falserepertory: Nulldate: 2018-05-11 
yaml 文件使用
- 查看 yaml 文件 
- pycharm
 - txt 记事本
 
 - 读取 yaml 文件 
- 安装:
pip install pyyaml - 方法:
yaml.safe_load(f) - 方法:
yaml.safe_dump(f) 
 - 安装:
 
import yamlfile_path = './my.yaml'
with open(file_path, 'r', encoding='utf-8') as f:data = yaml.safe_load(f) 
代码实例:
工程目录结构
- data 目录:存放 yaml 数据文件
 - func 目录:存放被测函数文件
 - testcase 目录:存放测试用例文件
 
# 工程目录结构
.
├── data
│   └── data.yaml
├── func
│   ├── __init__.py
│   └── operation.py
└── testcase├── __init__.py└── test_add.py 
测试准备
- 被测对象:
operation.py - 测试用例:
test_add.py - 测试数据:
data.yaml 
# operation.py 文件内容
def my_add(x, y):result = x + yreturn result
# test_add.py 文件内容
class TestWithYAML:@pytest.mark.parametrize('x,y,expected', [[1, 1, 2]])def test_add(self, x, y, expected):assert my_add(int(x), int(y)) == int(expected)
# data.yaml 文件内容
-- 1- 1- 2
-- 3- 6- 9
-- 100- 200- 300 
import pytest
import yamlfrom func.operation import my_add# 方法一
# class TestWithYAML:
#     @pytest.mark.parametrize('x,y,expected', [[1, 1, 2], [3, 6, 9], [100, 200, 300]])
#     def test_add(self, x, y, expected):
#         assert my_add(int(x), int(y)) == int(expected)# 方法二
def get_data():with open("../data/data.yaml", encoding='utf-8') as f:data = yaml.safe_load(f)return dataclass TestWithYAML:@pytest.mark.parametrize('x,y,expected', get_data())def test_add(self, x, y, expected):assert my_add(int(x), int(y)) == int(expected)
 
2.pytest结合数据驱动-excel
读取 Excel 文件
-  
第三方库
xlrdxlwingspandas
 -  
openpyxl
- 官方文档: https://openpyxl.readthedocs.io/en/stable/
 
 
openpyxl 库的安装
- 安装:
pip install openpyxl - 导入:
import openpyxl 
openpyxl 库的操作
-  
读取工作簿
 -  
读取工作表
 -  
读取单元格
 
import openpyxl# 获取工作簿
book = openpyxl.load_workbook('./data/test.xlsx')# 读取工作表
sheet = book.active
print(sheet)# 读取单个单元格
cell_a1 = sheet['A1']
print(cell_a1.value)cell_a3 = sheet.cell(column=1, row=3)  # A3
print(cell_a3.value)# 读取多个连续单元格
cells = sheet["A1":"C3"]
for i in cells:for j in i:print(j.value,end=' ')print() 
代码实例:
import openpyxl
import pytest
import yamlfrom func.operation import my_add# 方法一
# class TestWithYAML:
#     @pytest.mark.parametrize('x,y,expected', [[1, 1, 2], [3, 6, 9], [100, 200, 300]])
#     def test_add(self, x, y, expected):
#         assert my_add(int(x), int(y)) == int(expected)# 方法二
# def get_data():
#     with open("../data/data.yaml", encoding='utf-8') as f:
#         data = yaml.safe_load(f)
#     return data
#
#
# class TestWithYAML:
#     @pytest.mark.parametrize('x,y,expected', get_data())
#     def test_add(self, x, y, expected):
#         assert my_add(int(x), int(y)) == int(expected)# 方法三
def get_excel():book = openpyxl.load_workbook("../data/test.xlsx")sheet = book.activecells = sheet["A1":"C3"]values = []for row in cells:data = []for cell in row:data.append(cell.value)values.append(data)return valuesclass TestWithYAML:@pytest.mark.parametrize('x,y,expected', get_excel())def test_add(self, x, y, expected):assert my_add(int(x), int(y)) == int(expected)
 
3.pytest结合数据驱动-csv
csv 文件介绍
- csv:逗号分隔值
 - 是 Comma-Separated Values 的缩写
 - 以纯文本形式存储数字和文本
 - 文件由任意数目的记录组成
 - 每行记录由多个字段组成
 
Linux从入门到高级,linux,¥5000
web自动化测试进阶,python,¥3000
app自动化测试进阶,python,¥6000
Docker容器化技术,linux,¥5000
测试平台开发与实战,python,¥8000 
csv 文件使用
-  
读取数据
- 内置函数:
open() - 内置模块:
csv 
 - 内置函数:
 -  
方法:
csv.reader(iterable)- 参数:iterable ,文件或列表对象
 - 返回:迭代器,每次迭代会返回一行数据。
 
 
import csvdef get_csv():with open('./data/params.csv', 'r', encoding='utf-8') as file:raw = csv.reader(file)for line in raw:print(line)if __name__ == '__main__':get_csv() 
代码实例:
测试准备
-  
被测对象:
operation.py -  
测试用例:
test_add.py -  
测试数据:
params.csv 
# operation.py 文件内容
def my_add(x, y):result = x + yreturn result# test_add.py 文件内容
class TestWithCSV:@pytest.mark.parametrize('x,y,expected', [[1, 1, 2]])def test_add(self, x, y, expected):assert my_add(int(x), int(y)) == int(expected)# params.csv 文件内容
1,1,2
3,6,9
100,200,300 
import csvimport openpyxl
import pytest
import yamlfrom func.operation import my_add# 方法一
# class TestWithYAML:
#     @pytest.mark.parametrize('x,y,expected', [[1, 1, 2], [3, 6, 9], [100, 200, 300]])
#     def test_add(self, x, y, expected):
#         assert my_add(int(x), int(y)) == int(expected)# 方法二
# def get_data():
#     with open("../data/data.yaml", encoding='utf-8') as f:
#         data = yaml.safe_load(f)
#     return data
#
#
# class TestWithYAML:
#     @pytest.mark.parametrize('x,y,expected', get_data())
#     def test_add(self, x, y, expected):
#         assert my_add(int(x), int(y)) == int(expected)# 方法三
# def get_excel():
#     book = openpyxl.load_workbook("../data/test.xlsx")
#     sheet = book.active
#     cells = sheet["A1":"C3"]
#     values = []
#     for row in cells:
#         data = []
#         for cell in row:
#             data.append(cell.value)
#         values.append(data)
#     return values
#
#
# class TestWithYAML:
#     @pytest.mark.parametrize('x,y,expected', get_excel())
#     def test_add(self, x, y, expected):
#         assert my_add(int(x), int(y)) == int(expected)# 方法四
def get_csv():with open('../data/test.csv', encoding='utf-8') as f:raw = csv.reader(f)data = []for line in raw:data.append(line)return dataclass TestWithYAML:@pytest.mark.parametrize('x,y,expected', get_csv())def test_add(self, x, y, expected):assert my_add(int(x), int(y)) == int(expected)
 
4.pytest结合数据驱动-json
json 文件介绍
-  
json 是 JS 对象
 -  
全称是 JavaScript Object Notation
 -  
是一种轻量级的数据交换格式
 -  
json 结构
- 对象 
{"key": value} - 数组 
[value1, value2 ...] 
 - 对象 
 
{"name:": "tom","detail": {"course": "python","city": "北京"},"remark": [1000, 666, 888]
} 
json 文件使用
- 查看 json 文件 
- pycharm
 - txt 记事本
 
 - 读取 json 文件 
- 内置函数 open()
 - 内置库 json
 - 方法:
json.loads() - 方法:
json.dumps() 
 
params.json
{"case1": [1, 1, 2],"case2": [3, 6, 9],"case3": [100, 200, 300]
} 
import jsondef get_json():with open('./data/params.json', 'r') as f:data = json.loads(f.read())print(data)print(type(data))s = json.dumps(data, ensure_ascii=False)print(s)print(type(s))if __name__ == '__main__':get_json() 
代码示例:
测试准备
-  
被测对象:
operation.py -  
测试用例:
test_add.py -  
测试数据:
params.json 
# operation.py 文件内容
def my_add(x, y):result = x + yreturn result# test_add.py 文件内容
class TestWithJSON:@pytest.mark.parametrize('x,y,expected', [[1, 1, 2]])def test_add(self, x, y, expected):assert my_add(int(x), int(y)) == int(expected)# params.json 文件内容
{"case1": [1, 1, 2],"case2": [3, 6, 9],"case3": [100, 200, 300]
} 
import csv
import jsonimport openpyxl
import pytest
import yamlfrom func.operation import my_add# 方法一
# class TestWithYAML:
#     @pytest.mark.parametrize('x,y,expected', [[1, 1, 2], [3, 6, 9], [100, 200, 300]])
#     def test_add(self, x, y, expected):
#         assert my_add(int(x), int(y)) == int(expected)# 方法二
# def get_data():
#     with open("../data/data.yaml", encoding='utf-8') as f:
#         data = yaml.safe_load(f)
#     return data
#
#
# class TestWithYAML:
#     @pytest.mark.parametrize('x,y,expected', get_data())
#     def test_add(self, x, y, expected):
#         assert my_add(int(x), int(y)) == int(expected)# 方法三
# def get_excel():
#     book = openpyxl.load_workbook("../data/test.xlsx")
#     sheet = book.active
#     cells = sheet["A1":"C3"]
#     values = []
#     for row in cells:
#         data = []
#         for cell in row:
#             data.append(cell.value)
#         values.append(data)
#     return values
#
#
# class TestWithYAML:
#     @pytest.mark.parametrize('x,y,expected', get_excel())
#     def test_add(self, x, y, expected):
#         assert my_add(int(x), int(y)) == int(expected)# 方法四
# def get_csv():
#     with open('../data/test.csv', encoding='utf-8') as f:
#         raw = csv.reader(f)
#         data = []
#         for line in raw:
#             data.append(line)
#     return data
#
#
# class TestWithYAML:
#     @pytest.mark.parametrize('x,y,expected', get_csv())
#     def test_add(self, x, y, expected):
#         assert my_add(int(x), int(y)) == int(expected)# 方法五
def get_json():with open('../data/params.json', 'r') as f:data = json.loads(f.read())print(data)print(type(data))print(list(data.values()))return list(data.values())class TestWithYAML:@pytest.mark.parametrize('x,y,expected', get_json())def test_add(self, x, y, expected):assert my_add(int(x), int(y)) == int(expected)
 
5.pytest测试用例生命周期管理(一)
Fixture 特点及优势
- 1、命令灵活:对于 setup,teardown,可以不起这两个名字
 - 2、数据共享:在 conftest.py 配置⾥写⽅法可以实现数据共享,不需要 import 导⼊。可以跨⽂件共享
 - 3、scope 的层次及神奇的 yield 组合相当于各种 setup 和 teardown
 - 4、实现参数化
 
Fixture 在自动化中的应用- 基本用法
- 场景:
 
测试⽤例执⾏时,有的⽤例需要登陆才能执⾏,有些⽤例不需要登陆。
setup 和 teardown ⽆法满⾜。fixture 可以。默认 scope(范围)function
- 步骤: 
- 1.导⼊ pytest
 - 2.在登陆的函数上⾯加@pytest.fixture()
 - 3.在要使⽤的测试⽅法中传⼊(登陆函数名称),就先登陆
 - 4.不传⼊的就不登陆直接执⾏测试⽅法。
 
 
import pytest@pytest.fixture()
def login():print('完成登录操作')def test_search():print('搜索')# def test_cart():
#     login()
#     print('购物车')def test_cart(login):print('购物车')def test_order(login):print('下单功能') 
6.pytest测试用例生命周期管理(二)
Fixture 在自动化中的应用 - 作用域
| 取值 | 范围 | 说明 | 
|---|---|---|
| function | 函数级 | 每一个函数或方法都会调用 | 
| class | 类级别 | 每个测试类只运行一次 | 
| module | 模块级 | 每一个.py 文件调用一次 | 
| package | 包级 | 每一个 python 包只调用一次(暂不支持) | 
| session | 会话级 | 每次会话只需要运行一次,会话内所有方法及类,模块都共享这个方法 | 
import pytest@pytest.fixture(scope="function")
def login():print('完成登录操作')def test_search():print('搜索')# def test_cart():
#     login()
#     print('购物车')def test_cart(login):print('购物车')def test_order(login):print('下单功能')class TestDemo:def test_case1(self, login):print("case1")def test_case2(self, login):print("case2")
 
7.pytest测试用例生命周期管理(三)
Fixture 在自动化中的应用 - yield 关键字
- 场景:
 
你已经可以将测试⽅法【前要执⾏的或依赖的】解决了,测试⽅法后销毁清除数据的要如何进⾏呢?
- 解决:
 
通过在 fixture 函数中加⼊ yield 关键字,yield 是调⽤第⼀次返回结果,第⼆次执⾏它下⾯的语句返回。
- 步骤:
 
在@pytest.fixture(scope=module)。在登陆的⽅法中加 yield,之后加销毁清除的步骤
import pytest
'''
@pytest.fixture
def fixture_name():setup 操作yield 返回值teardown 操作
'''@pytest.fixture(scope="function")
def login():#setup操作print('完成登录操作')tocken = "abcdafafasdfds"username = 'tom'yield tocken,username #相当于return#teardown操作print('完成登出操作')def test_search():print('搜索')# def test_cart():
#     login()
#     print('购物车')def test_cart(login):print('购物车')def test_order(login):print('下单功能')class TestDemo:def test_case1(self, login):print("case1")def test_case2(self, login):print("case2") 
8.pytest测试用例生命周期管理-自动注册
Fixture 在自动化中的应用 - 数据共享
- 场景:
 
与其他测试⼯程师合作⼀起开发时,公共的模块要放在⼤家都访问到的地⽅。
- 解决:
 
使⽤ conftest.py 这个⽂件进⾏数据共享,并且他可以放在不同位置起着不同的范围共享作⽤。
-  
前提:
- conftest ⽂件名是不能换的
 - 放在项⽬下是全局的数据共享的地⽅
 
 -  
执⾏:
- 系统执⾏到参数 login 时先从本模块中查找是否有这个名字的变量什么的,
 - 之后在 conftest.py 中找是否有。
 
 -  
步骤:
 
将登陆模块带@pytest.fixture 写在 conftest.py 里面
代码示例:
conftest.py
# conftest.py名字是固定的,不能改变
import pytest@pytest.fixture(scope="function")
def login():# setup操作print('完成登录操作')tocken = "abcdafafasdfds"username = 'tom'yield tocken, username  # 相当于return# teardown操作print('完成登出操作') 
test_test1.py
import pytest
'''
@pytest.fixture
def fixture_name():setup 操作yield 返回值teardown 操作
'''def test_search():print('搜索')# def test_cart():
#     login()
#     print('购物车')def test_cart(login):print('购物车')def test_order(login):print('下单功能')class TestDemo:def test_case1(self, login):print("case1")def test_case2(self, login):print("case2") 
项目结构:

9.pytest测试用例生命周期管理-自动生效
Fixture 在自动化中的应用 - 自动应用
场景:
不想原测试⽅法有任何改动,或全部都⾃动实现⾃动应⽤,
没特例,也都不需要返回值时可以选择⾃动应⽤
解决:
使⽤ fixture 中参数 autouse=True 实现
步骤:
在⽅法上⾯加 @pytest.fixture(autouse=True)
test_test1.py
import pytest'''
@pytest.fixture
def fixture_name():setup 操作yield 返回值teardown 操作
'''def test_search():print('搜索')# def test_cart():
#     login()
#     print('购物车')# def test_cart(login):
#     print('购物车')
def test_cart():print('购物车')# def test_order(login):
#     print('下单功能')def test_order():print('下单功能')class TestDemo:# def test_case1(self, login):#     print("case1")def test_case1(self):print("case1")# def test_case2(self, login):#     print("case2")def test_case2(self):print("case2") 
conftest.py
# conftest.py名字是固定的,不能改变
import pytest@pytest.fixture(scope="function", autouse=True)
def login():# setup操作print('完成登录操作')tocken = "abcdafafasdfds"username = 'tom'yield tocken, username  # 相当于return# teardown操作print('完成登出操作') 
运行结果:

 
10.pytestfixture实现参数化
Fixture 在自动化中的应用 -参数化
场景:
测试离不开数据,为了数据灵活,⼀般数据都是通过参数传的
解决:
fixture 通过固定参数 request 传递
步骤:
在 fixture 中增加@pytest.fixture(params=[1, 2, 3, ‘linda’])
在⽅法参数写 request,方法体里面使用 request.param 接收参数
# @pytest.fixture(params=['tom', 'jenny'])
# def login(request):
#     print(f"用户名:{request.param}")
#     return request.param
#
#
# def test_demo1(login):
#     print(f'demo1 case:数据为{login}')@pytest.fixture(params=[['tom', 'harry'], ['jenny', 'jack']])
def login(request):print(f"用户名:{request.param}")return request.paramdef test_demo1(login):print(f'demo1 case:数据为{login}') 
Fixture 的用法总结
- 模拟 setup,teardown(一个用例可以引用多个 fixture)
 - yield 的用法
 - 作用域( session,module, 类级别,方法级别 )
 - 自动执行 (autouse 参数)
 - conftest.py 用法,一般会把 fixture 写在 conftest.py 文件中(这个文件名字是固定的,不能改)
 - 实现参数化
 
