pytest最好的测试框架

pytest最好的测试框架_第1张图片

前言

  1. 简单灵活,容易上手;支持参数化; 测试用例的skip和xfail处理;

  2. 能够支持简单的单元测试和复杂的功能测试,还可以用来做selenium/appnium等自动化测试、接口自动化测试(pytest+requests);

  3. pytest具有很多第三方插件,并且可以自定义扩展, 比较好用的如 pytest-allure(完美html测试报告生成) pytest-xdist(多CPU分发)等;

  4. 可以很好的和jenkins集成;

如何运行
1.pytest将在当前目录及其子目录中运行test _ * .py或* test.py形式的所有文件。
2.以test_开头的函数,以Test开头的类,以test_开头的方法。所有包package都要有__init
_.py文件。
3.Pytest可以执行unittest框架写的用例和方法

本期内容
1.安装并运行pytest
2.了解pytest灵活框架结构和灵活执行方式
3.断言
4.Pytest-fixture 是最闪亮功能!!
5.yield与final

正在努力

  • 一.安装pytest
    • 运行
      • 1.可以多个执行
      • 也可以单个执行
      • pytest+ -v+文件名 执行 可以看到 执行的信息 错误和正确的测试信息
      • pytest+ -s+文件名 执行 可以看到测试的输出
  • 二.pytest灵活框架结构和灵活执行方式
    • ———灵活架构
      • 写一个简单的架构
      • 跳过
        • @pytest.mark.skip("看你不顺眼 就跳过")
        • @pytest.mark.xfail()
      • 标记
    • ———灵活执行方式
      • 第一种方法 也就是 pycharm终端运行的方式
      • 第二种方法 也就是cmd 运行
    • 第三种 不加装饰器标记也想执行不同层次的用例
    • 第四种pytest -k "TestPytest or test_app_function02
  • 三.简单介下断言
  • 四.Pytest -fixture 是最闪亮功能!!
    • • 场景1:测试用例执行时,有的用例的数据保存在数据库中,需要先连接数据库再执行测试用例,最后停止数据库的连接。setup和teardown可以实现。fixture可以灵活命名实现。默认scope(范围)function
    • • 场景2: • 不想原测试方法有任何改动,或全部都自动实现自动应用,没特例,也都不需要返回值时可以选择自动应用
    • 场景3 执行前 准备测试数据,通过fixture准备
  • 五.yield与final
    • 神奇的yield
      • 使用这 个结构,+selenium,实现bing_sous效果
        • 1.打开浏览器是两个测试方法依赖,要在初 始 化实现。 使用yield 返回driver 。
    • • 场景1:
    • 做两个小任务
      • 任务一:把加法数据从文件中传。尝试
      • 任务二:将bing搜索改成参数化数据驱动(pytest--,yaml)
  • 多线程并行与分布式执行
    • 多线程并发:考虑,多个CPU代价,cpu核,脚本个 数,及执行时间长短。
  • pytest-allure生成报告
    • 打开下载网站
    • 打开pycharm 终端运行
    • 生成报告
    • • 场景:希望在报告中看到测试功能,子功能或场景,测试步骤
    • 报告的多样化

一.安装pytest

打开pycharm 打开终端 输入 pip install pytest 来安装
pytest最好的测试框架_第2张图片
没有 自定义版本 他会安装最新版本

运行

cd 进入你要执行文件的目录

1.可以多个执行

直接终端CD进入目录 输入pytest
就可运行 全部的test测试文件
pytest最好的测试框架_第3张图片
可以看到 我是再unittest目录下执行 我要执行的文件
并且可以看到已经全部执行了
图中绿色的点 代表 执行成功 黄色的S代表 跳过

也可以单个执行

直接终端CD进入目录 输入pytest+文件名 执行
pytest最好的测试框架_第4张图片
可以看到 只有一个文件被执行

pytest+ -v+文件名 执行 可以看到 执行的信息 错误和正确的测试信息

pytest最好的测试框架_第5张图片

pytest+ -s+文件名 执行 可以看到测试的输出

pytest最好的测试框架_第6张图片

二.pytest灵活框架结构和灵活执行方式

———灵活架构

写一个简单的架构

1.先更改一下执行工具
pytest最好的测试框架_第7张图片
2.打开pycharm 新建一个文件 名字为 test_pytest_demo(pytest执行的文件都要命名为test)
写入架构

import pytest


def setup_module():
    print("一个文件开始只执行一次")


def setup_function():
    print("每一个函数前执行一次")


def test_web_function01():
    print("函数级不在类中web的方法")


def test_app_function01():
    print("函数级不在类中app的方法")


def teardown_function():
    print("每一个函数后执行一次")


def teardown_module():
    print("一个文件结尾只执行一次")


class TestPytest(object):
    def setup_class(self):
        print("一个类 初始化只执行一次")

    def setup_method(self):
        print("每一个方法前执行一次")

    def test_method01_win(self):
        print("在win下执行测试")

    def test_method02_linux(self):
        print("在linux下执行测试")

    def teardown_method(self):
        print("每一个方法后执行一次")

    def teardown_class(self):
        print("一个类销毁只执行一次")


if __name__ == '__main__':
    pytest.main()

右键运行这个架构 记住要类级别执行
pytest最好的测试框架_第8张图片
这样 就可以看到测试成功了 pytest执行框架 是最好的
可以看到详情 简易执行

跳过

@pytest.mark.skip(“看你不顺眼 就跳过”)

直接跳过 不会执行 并且不计入失败测试
括号里为 你写的条件 这个要写在方法前
pytest最好的测试框架_第9张图片

@pytest.mark.xfail()

将注定会失败的执行标记为失败 报告里 会标记为通过
pytest最好的测试框架_第10张图片
可以看到 我写了个错误的断言 但是他标记为忽略 实则是错误的执行
但是并没有记入失败

标记

pytest -v -s -m apptest 执行用例是使用 @pytest.mark.apptest 标记的测试方法。
pytest -v -s -m “not apptest” 执行用例没有 @pytest.mark.apptest 标记的测试方法。
pytest最好的测试框架_第11张图片
pytest -v -s -m linuxtest 执行用例是使用 @pytest.mark.linuxtest 标记的测试方法。
pytest -v -s -m “not linuxtest” 执行用例没有 @pytest.mark.linuxtest 标记的测试方法。
pytest最好的测试框架_第12张图片

selected(被选择的,pytest -m linuxtest )1 selected .只有一 个 被选择上了。5 deselected 5个没有被 选择执行上。
pytest最好的测试框架_第13张图片

———灵活执行方式

第一种方法 也就是 pycharm终端运行的方式

pytest最好的测试框架_第14张图片

第二种方法 也就是cmd 运行

pytest最好的测试框架_第15张图片
-S 可以输出每一个方法执行的结果
-v 显示信息强度 也就是 结果里面 每一步的执行过程
可以 - v -v
也可以 -v -v -v 最高强度三个-v

第三种 不加装饰器标记也想执行不同层次的用例

pytest -v -s test_pytest_frame.py::TestPytest (TestPytest这个类下面的所有方法)
pytest最好的测试框架_第16张图片

第四种pytest -k "TestPytest or test_app_function02

•	pytest -k "TestPytest  or test_app_function02"   
 执行TestPytest这个类下面的所有方法+ test_app_function02方法

pytest最好的测试框架_第17张图片

三.简单介下断言

断言的使用
• 断言:支持显示最常见的子表达式的值,包括调用,属性,比较以及二元和一元运算符。
• 包含,相等,不等,大于 小于运算,assertnot 假

assert “h” in “hello”(判断h在hello中)assert 3==4(判断3=4)
•	 assert 3!=4(判断3!=4)
•	 assert f() ==4 (判断f()方法返回值是否=4)assert 5>6 (判断5>6为真)assert not xx (判断xx不为真)assert {'0', '1', '3', '8'} == {'0', '3', '5', '8'}

四.Pytest -fixture 是最闪亮功能!!

pytest最好的测试框架_第18张图片

• 场景1:测试用例执行时,有的用例的数据保存在数据库中,需要先连接数据库再执行测试用例,最后停止数据库的连接。setup和teardown可以实现。fixture可以灵活命名实现。默认scope(范围)function

• 步骤:

  1. 导入pytest
  2. 在登陆的函数上面加@pytest.fixture()
  3. 在要使用的测试方法中传入(登陆函数名称),就先登陆
  4. 不传入的就不登陆直接执行测试方法。

pytest最好的测试框架_第19张图片

• 场景2: • 不想原测试方法有任何改动,或全部都自动实现自动应用,没特例,也都不需要返回值时可以选择自动应用

• 解决: • 使用fixture中参数autouse=True实现
• 步骤:在方法上面加@pytest.fixture(autouse=True)
自动应用 示例如下
pytest最好的测试框架_第20张图片
• 使用@pytest.mark.usefixtures
• 步骤:在测试方法上加@pytest.mark.usefixtures(“方法名")
通过装饰器 示例如下

pytest最好的测试框架_第21张图片

场景3 执行前 准备测试数据,通过fixture准备

import pytest

@pytest.fixture()
def data():
    test_data = {'name': 'Guo', 'age': 18}
    return test_data


@pytest.mark.usefixtures("data")
def test_pay(data):
    name = data['name']
    age = data['age']
    print(name + "支付", "今年:", age)


@pytest.mark.usefixtures("data")
def test_basket():
    print(data)
    print("添加购物车")


def test_search():
    print("搜索商品,不需要登陆")

pytest最好的测试框架_第22张图片

五.yield与final

pytest最好的测试框架_第23张图片

定义:yield , 调用一次,给你一个反馈,调用第二 次,反馈从第一次结束语句开始给你反馈

神奇的yield

测试用例如下:
pytest最好的测试框架_第24张图片
pytest运行顺序
1先运行16行的
2在16行找到的参数open_close_broswer
3找到这个参数再12行
4返回这个参数执行并带入行
5执行yield
6执行17行
717行调用12行的参数
8执行关闭浏览器

使用这 个结构,+selenium,实现bing_sous效果

1.打开浏览器是两个测试方法依赖,要在初 始 化实现。 使用yield 返回driver 。

#在一个 方法实现打开关闭浏览器,并且是初始化销毁
import time

import pytest

from selenium import webdriver

from selenium.webdriver.common.by import By

@pytest.fixture()
def open_close_broswer():
    #   1.  使用浏览器驱动启动浏览器(chrome)
    driver = webdriver.Chrome("E:\selenium_project\driver\chromedriver.exe")
    # 输入要测试的网址
    driver.get("https://cn.bing.com/")
    yield driver
    # 关闭浏览器,释放资源
    driver.close()
def test_soso(open_close_broswer):
    # 通过ID搜索
    search_elementl = open_close_broswer.find_element(By.ID, "sb_form_q")
    # 清楚搜索框中的内容
    search_elementl.clear()
    # 输入搜索信息
    search_elementl.send_keys("selenium")
    # 通过NAME定位这个搜索框
    # search_elementl = driver.find_element(By.NAME,"q")
    # 定位到[搜索按钮]进行点击
    open_close_broswer.find_element(By.ID, "search_icon").click()
    # 断言(assert )操作,  验证搜索的信息在网页返回源码中
    assert "selenium" in open_close_broswer.page_source
    time.sleep(2)
def test_picture(open_close_broswer):
    print("点击图片,搜索图片")

运行后新的问题出现了
你发现打开两次浏览器 ,能 否只 打开一次 ,需要类级文件级初始化,不是 方法级的。
可以的 只需要加一个@pytest.fixture(scope="module")
让他只执行一次
后面在调用 他不执行

• 场景1:

• 测试离不开数据,为了数据灵活一般,数据都是通过参数传的
• 解决:fixture通过固定参数request传递;
• 步骤: • 在fixture中增加@pytest.fixture(params=[1, 2, 3, ‘linda’]) • 在方法参数写request
pytest最好的测试框架_第25张图片
可以看到 执行了三次

做两个小任务

任务一:把加法数据从文件中传。尝试

fixture----初 始化 依赖 -unittest–setup pytest.mark.paramilize—参数化数据 ddt
1.新建一个yaml 文件test_add_data.yaml 写入列表
pytest最好的测试框架_第26张图片
这里要记住yaml文件格式-空格XXX就行
可以新建一个python文件 看看能不能把他读出来
pytest最好的测试框架_第27张图片
是可以读出来的 encoding='utf8’代表 中文字符输出
接下来进行下一步使用参数化 输出

@pytest.mark.parametrize("num1,num2,result",yaml.safe_load(open("test_add_data.yaml",encoding='utf8')))
def test_add_yaml(num1, num2, result):
    assert num1 + num2 == result

pytest最好的测试框架_第28张图片
输出成功拉

任务二:将bing搜索改成参数化数据驱动(pytest–,yaml)

import time

import pytest
import yaml

from selenium import webdriver

from selenium.webdriver.common.by import By

@pytest.fixture(scope="module")
def open_close_broswer():
    #   1.  使用浏览器驱动启动浏览器(chrome)
    driver = webdriver.Chrome("E:\selenium_project\driver\chromedriver.exe")
    # 输入要测试的网址
    driver.get("https://cn.bing.com/")
    yield driver
    # 关闭浏览器,释放资源
    driver.close()

@pytest.mark.parametrize("a", yaml.safe_load(open("test_data.yaml", encoding='utf8')))
def test_soso(open_close_broswer,a):
    open_close_broswer.get("https://cn.bing.com/")
    time.sleep(2)
    # 通过ID搜索
    search_elementl = open_close_broswer.find_element(By.ID, "sb_form_q")
    # 清楚搜索框中的内容
    search_elementl.clear()
    # 输入搜索信息
    search_elementl.send_keys(a)
    # 通过NAME定位这个搜索框
    #search_elementl = driver.find_element(By.NAME,"q")
    # 定位到[搜索按钮]进行点击
    open_close_broswer.find_element(By.ID, "search_icon").click()
    # 断言(assert )操作,  验证搜索的信息在网页返回源码中
    assert "a" in open_close_broswer.page_source
    time.sleep(2)
def test_picture(open_close_broswer):
    print("点击图片,搜索图片")

driver.get(“https://cn.bing.com/”)
加这个是因为 你每次搜索完是新的网页 你需要回到原来的网页 重新搜索

pytest最好的测试框架_第29张图片
也可以把上面的浏览器驱动

 driver = webdriver.Chrome("E:\selenium_project\driver\chromedriver.exe")

换成这个

#..替换的是当前路径 也就是上一级路径
par_path = os.path.abspath('..')
    driver_path = par_path + r"\driver\chromedriver.exe"
    driver = webdriver.Chrome(executable_path=driver_path)

yaml 大家随便写 只要记住格式为

-空格XXX

即可

多线程并行与分布式执行

多线程并发:考虑,多个CPU代价,cpu核,脚本个 数,及执行时间长短。

●场景:测试用例1000条,-个用例执行1钟,- -
个测试人员执行需要1000分钟。通常我们会用人力成本换取时间成本,加几个人一-起执行,时间就会缩短。如果10人一起执行只需要100分钟,这就是一一种并行测试,分布式场景。
●解决: pytest分 布式执行插件: pytest-xdist, 多个CPU或主机执行
●前提:用例之间都是独立的,没有先后顺序,随机都能执行,可复运行不影响其他用例。
●安装: Pip3 install pytest-xdist
●多个CPU并行执行用例,直接加-n 3是并行数量: pytest -n 3 ●在多个终端下一起执行
●注意:只有超过秒级以上并发才显示效果,并且不只一个方法 ●https://pypi.org/project/pytest xdist/

第一步 在终端安装pytest-xdist

pip install pytest-xdist

在终端进入你要运行的文件目录
输入指令pytest -n 3
在这里插入图片描述
运行结果为
在这里插入图片描述

pytest-allure生成报告

打开下载网站

链接: allure
pytest最好的测试框架_第30张图片
下载zip包,解压,进入bin目录运行,把bin目录加入path路径

pytest最好的测试框架_第31张图片

打开pycharm 终端运行

pip install allure-pytest
安装一下 allure
pytest最好的测试框架_第32张图片

在测试执行期间收集结果 pytest -s –q --alluredir=./result/ 测试完成后查看实际报告, 在线看报告。allure serve ./result/
cd 到你的测试文件目录下 执行 pytest -v -s --alluredir=./result 来收集你的测试数据

生成报告

同样在终端(你的测试文件目录下)
allure serve ./result
pytest最好的测试框架_第33张图片
这样我们的报告就生成成功了

• 场景:希望在报告中看到测试功能,子功能或场景,测试步骤

•	解决:@Feature,story,step
•	步骤:
1.	Import allure
2.	功能上加@allure.feature(‘功能名称’)
3.	子功能上加@allure.story(‘子功能名称’)
4.	步骤上加@allure.step(‘步骤细节’)

在方法上加@allure.feature(“模块名”),,
如果模块下还有小功能小分支 @allure.feature(“模块名-评论”)
@allure.story(“功能名-添加”) def test_me():
pass
@allure.feature(“模块名-评论”)
@allure.story(“功能名-编辑评论”) def test_me():
pass @allure.feature(“模块名-评论”)
@allure.story(“功能名-查看评论”)

import pytest
import allure


# web UI测试
# 打开浏览器(fixture)  scope 是文件级(module) 和类级(class)
# 测试前购物车,支付,反馈(登录不登录)


@pytest.fixture(scope="module")
def driver():
    with allure.step("1、开浏览器"):
        print("打开浏览器")
    yield driver
    with allure.step("7、最后关闭浏览器"):
        print("关闭浏览器")



@pytest.fixture(scope="module")
def login(driver):
    with allure.step("2、登陆"):
        print("juiceshop登陆了")


@allure.feature("反馈")
@allure.story("匿名")
@pytest.mark.parametrize("fk",["sdjfflsd","蝴蝶"])
def test_anno_repains(driver,fk):
    with allure.step("3、匿名反馈"):
        print("匿名反馈"+fk)

@allure.feature("购物车")
@pytest.mark.usefixtures("login")
def test_basket():
    print("购物车")

@allure.feature("支付")
@pytest.mark.usefixtures("login")
def test_pay():
    print("支付")

@allure.feature("反馈")
@allure.story("实名")
@pytest.mark.usefixtures("login")
def test_login_repains():
    print("登陆后反馈")

可以看到报告中出现子级别
pytest最好的测试框架_第34张图片
这样的报告 看着非常简洁 并附有说服力

报告的多样化

•	附加图片:
•	allure.attach.file(source, name, attachment_type, extension):
•	allure.attach.file("./result/b.png", attachment_type=allure.attachment_type.PNG

pytest最好的测试框架_第35张图片
pytest最好的测试框架_第36张图片
可以看到报告里生成了图片


•	@allure.attach(‘具体文本信息’)
•	@allure.link,@allure.issue并 @allure.testcase描述
• @allure.description;@allure.title;
   import allure


@allure.feature("测试数字相等")
def test_01():
    allure.attach("整数相等")
    allure.attach.file("test_data.yaml", "数据", attachment_type=allure.attachment_type.YAML)
    assert 1 == 1


@allure.feature("测试字典相等")
def test_02():
    allure.attach("字典相等")
    assert {"name": "linda"} == {'name': 'linda'}
    allure.attach.file("bing.png","我喜欢",attachment_type=allure.attachment_type.PNG)


@allure.description("这个是要测试的点,包括功能测试。。。")
@allure.title("功能中安全测试")
@allure.link("http://114.116.97.187:3333/DVWA", "渗透测试用例")
@allure.issue("http://114.116.87.187:1081/zentao/user-login-L3plbnRhby8=.html", "bug地址")
@allure.testcase("http://114.116.87.187:1081/zentao/user-login-L3plbnRhby8=.html", "功能测试用例")
def test_03():
    print("描述详细")

运行如下
pytest最好的测试框架_第37张图片

可以看到里面的输入了文字 还有我们的title 还有描述都出来了

你可能感兴趣的:(pytest,python,jenkins)