Pytest测试框架教程

1、简介

pytest是Python的另一个第三方单元测试库。它的目的是让单元测试变得更容易,并且也能扩展到支持应用层面复杂的功能测试。

特性:

  • 支持用简单的assert语句实现丰富的断言,无需复杂的self.assert*函数
  • 自动识别测试模块和测试函数
  • 模块化夹具用以管理各类测试资源
  • 对unittest完全兼容,对nose基本兼容
  • 支持Python3和PyPy3
  • 丰富的插件生态,已有300多个各式各样的插件,社区繁荣

2、pytest与unittest的区别

image.png

3、pytest安装

安装命令:pip install pytest
验证命令:pytest --version(打印版本号即为成功)
示例:

image.png

4、pytest规则

pytest是如何去寻找要执行的测试用例的

  • pytest将在当前目录及其子目录中运行所有格式为test_.py或者_test.py的文件
  • 类必须以Test开头
    官方:它遵循标准的测试发现规则,官方文档如下:
    1、如果未指定任何参数,则从当前目录或testpaths(如果pytest.ini已配置)开始,另外,命令行参数可以在目录、文件名、节点ID的任何组合中使用
    2、递归到目录,除非它们匹配norecursedirs(pytest.ini配置)
    3、在这些目录中,搜索test_*.py或*_test.py,在这个文件中,搜索测试项目
    * 在类之外拥有test前缀的测试函数或方法
    * 在拥有Test前缀中的测试类(不含__init__方法)中拥有test前缀的测试函数或方法
    4、也可以自定义测试发现规则(兼容unittest的原因)

5、pytest断言

代码示例:

import pytest
from selenium import webdriver
from time import sleep
"""
    借助python的运算符号和关键字实现不同数据类型的断言
"""
# 百度搜索案例
def test_baidu_search():
    driver = webdriver.Chrome()
    driver.get("http://www.baidu.com")
    driver.implicitly_wait(10)
    driver.find_element_by_id("kw").send_keys("哈哈哈")
    driver.find_element_by_id("su").click()
    sleep(3)
    # == 断言
    # 窗口的 title判断
    web_title = driver.title
    assert "哈哈哈_百度搜索" == web_title
    driver.quit()
    print("driver已退出!")

    # != 测试不相等
    # <= 测试小于等于
    # >= 测试大于等于
    # in 测试包含
    # not in 测试不包含
    # 判断是否为true
    # 判断是否为False

if __name__ == '__main__':
    # -s:打印测试用例的print信息
    # test_assert.py : 只扫描该文件
    pytest.main(["-s", "test_assert.py"])


6、pytest参数化

import pytest
from selenium import webdriver
from time import sleep

"""
    pytest 参数化
    当一组测试用例有固定的测试数据时,就可以通过参数化的方式简化测试用例的编写
    通过pytest.mark.parametrzie()方法设置参数:
    参数名:"search_key,expected"
    参数值:通过数组定义参数值时,每一个元组都是一条测试用例的测试数据
    ids参数:默认None,用来重新定义测试用例的名称
"""


# 百度搜索案例
# 参数化
@pytest.mark.parametrize(
    "search_key,expected",
    [
        ("哈哈哈", "哈哈哈_百度搜索"),
        ("呵呵呵", "呵呵呵_百度不想搜索"),
    ],
    ids=["case1", "case2"]
)
def test_baidu_search(search_key, expected):
    driver = webdriver.Chrome()
    driver.get("http://www.baidu.com")
    driver.implicitly_wait(10)
    driver.find_element_by_id("kw").send_keys(search_key)
    driver.find_element_by_id("su").click()
    sleep(3)
    # == 断言
    # 窗口的 title判断
    web_title = driver.title
    assert expected == web_title
    driver.quit()
    print("driver已退出!")


if __name__ == '__main__':
    pytest.main(["-s", "test_param.py"])

7、pytest常用运行参数

-s 打印信息
-v 显示详细信息
-k 运行包含某个字符串的测用例
-q 简化控制台输出信息
-x 如果执行到失败的用例,则停止测试

运行测试目录:pytest.main["-s","/test_dir"]
指定特定类或方法:pytest.main("-s","xxx.py::类名") pytest.main("-s","xxx.py::方法名")

import pytest
from selenium import webdriver
from time import sleep
"""
    借助python的运算符号和关键字实现不同数据类型的断言
"""
# 百度搜索案例
def test_baidu_search():
    driver = webdriver.Chrome()
    driver.get("http://www.baidu.com")
    driver.implicitly_wait(10)
    driver.find_element_by_id("kw").send_keys("哈哈哈")
    driver.find_element_by_id("su").click()
    sleep(3)
    # == 断言
    # 窗口的 title判断
    web_title = driver.title
    assert "哈哈哈_百度搜索" == web_title
    driver.quit()
    print("driver已退出!")

def test_fun1():
    assert 1 == 1
    print("fun1")

if __name__ == '__main__':
    # -s:打印测试用例的print信息
    # test_assert.py : 只扫描该文件
    pytest.main(["-s", "test_assert.py"])
    # pytest.main(["-v", "-s", "test_assert.py"])
    # pytest.main(["-k", "fun", "-s", "test_assert.py"])
    # pytest.main(["-q", "test_assert.py"])
    # pytest.main(["-x", "test_assert.py"])
    # pytest.main(["-s", "test_assert.py::test_fun1"])

8、生成测试报告

8.1、生成JunitXML测试报告:

cmd进入测试用例目录,执行:
pytest xxx.py --junit-xml=./report/log01.xml
image.png

8.2、生成在线测试报告:

cmd进入测试用例目录,执行:
pytest xxx.py --pastebin=all
控制台最后会生成URL链接

9、控制测试用例执行

  • 出现n个测试用例失败,则结束测试执行
    pytest --maxfail=2 #出现2个用例失败则终止测试
import pytest

# 失败
def test_fail01():
    print("第一次失败")
    assert 1 == 2


def test_fail02():
    print("第二次失败")
    assert 1 == 2


def test_fail03():
    print("第三次成功")
    assert 1 == 1


if __name__ == '__main__':
    # 失败两次停止测试,第三条用例不会执行
    pytest.main(["--maxfail=2", "test_fail.py"])

10、多进程运行用例

  • 安装pytest-xdist
pip install pytest-xdist
  • 运行模式
pytest -n NUMCPUS
  • 代码示例
import pytest

def test_case01():
    assert 1 == 1

def test_case02():
    assert 1 == 1

if __name__ == '__main__':
    # 使用两核CPU跑用例
    # pytest.main(["-s", "-n", "2", "test_many.py"])

    # CPU满核跑用例
    pytest.main(["-s", "-n", "auto", "test_many.py"])

11、通过标记执行用例

pytest -m flag
这条命令会执行被装饰器@pytest.mark.flag 装饰的所有测试用例
1、在测试用例.py同目录创建初始化文件pytest.ini
2、新建标记名,示例

[pytest]
markers =
    flag

代码示例:

import pytest


@pytest.mark.flag
def test_case01():
    assert 1 == 1

def test_case02():
    assert 1 == 2

if __name__ == '__main__':
    # 只会执行带flag标记的用例
    # pytest.main(["-m", "flag", "test_mark.py"])

    # 不会执行带flag标记的用例
    pytest.main(["-m", "not flag", "test_mark.py"])

20210902 待更新...

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容