WEB UI自动化测试之Pytest框架学习
文章目录
- 前言
- Pytest简介
- Pytest安装
- Pytest的常用插件
- Pytest的命名约束
- Pytest的运行方式
- Pytest运行方式与unittest对比
- 主函数运行
- 命令行运行
- 执行结果代码说明
- pytest.ini配置文件方式运行(推荐)
- 使用markers标记测试用例
- pytest中添加Fixture(测试夹具)
- pytest中的setup与teardown
- conftest
- pytest中的fixtrue装饰器
- pytest中的fixtrue装饰器的优势
- Fixture装饰器的定义方式
- fixtrue装饰器参数详解-scope
- scope = “function”
- scope = “class”
- scope = “module”
- fixtrue参数详解-autouse
- 测试用例添加、加载、运行(对比unittest)
- pytest跳过测试用例skip、skipif
- @pytest.mark.skip
- @pytest.mark.skipif
- 跳过标记
- Pytest参数化
- 函数返回值作为参数
- “笛卡尔积”,多个参数化装饰器
- 输出测试报告
- 预期失败函数
- 作用
- 应用场景
- 语法与参数
- 控制方法执行顺序
- 简介
- 安装 pytest-ordering
- 使用方法
- 示例
- 示例1:基于 order 的执行顺序
- 示例2:基于 before/after 的执行顺序
- 失败重试
- 简介
- 安装
- 使用方法
- 装饰器方式
- 参数添加运行方式
- 参考目录
前言
阅读本文前请注意最后编辑时间,文章内容可能与目前最新的技术发展情况相去甚远。欢迎各位评论与私信,指出错误或是进行交流等。
在之前已经学习过用unittest测试框架,本文介绍另外一个目前主流的测试框架Pytest。
Pytest简介
官方文档介绍:
Pytest is a framework that makes building simple and scalable tests easy. Tests are expressive and readable—no boilerplate code required. Get started in minutes with a small unit test or complex functional test for your application or library.
官方地址:https://docs.pytest.org
pytest是一个非常成熟的Python测试框架,主要有以下几个特点:
- 简单灵活,容易上手
- 支持参数化
- 能够支持简单的单元测试和复杂的功能测试,还可以配合selenium/appnium等进行自动化测试、接口自动化测试(pytest+requests)
- pytest具有很多第三方插件,并且可以自定义扩展,比较好用的如pytest-selenium(集成selenium)、pytest-html(html测试报告生成)、pytest-rerunfailures(失败case重复执行)、pytest-xdist(多CPU分发)等
- 测试用例的skip和xfail处理
- 可以很好的和jenkins集成
- 测试报告框架----allure 也支持pytest
Pytest安装
安装命令
pip install -U pytest
查看是否安装成功
pytest --version # 展示当前已安装版本
Pytest的常用插件
插件列表网址:https://plugincompat.herokuapp.com
包含很多插件包,大家可依据工作的需求选择使用。
Pytest的命名约束
1)模块名(py文件)通常被统一放在一个testcases文件夹中,必须是以test_开头或者_test.py结尾
2)测试类(class)必须以Test开头,并且不能带init方法,类里的方法必须以test_开头
3)测试用例(函数)必须以test_开头
此时,在执行pytest命令时,会自动从当前目录及子目录中寻找符合上述约束的测试函数来执行。
# 测试函数必须以test_开头(类以外)def test_demo1(self):print("测试用例1")# 测试类(class)必须以Test开头
class TestDemo:# 类里的方法必须以test_开头def test_demo2(self):print("测试用例2")
Pytest的运行方式
Pytest运行方式与unittest对比
运行步骤 | Pytest | unittest |
---|---|---|
导包 | 导入pytest模块 | 导入unittest模块 |
创建测试方法(不写在测试类中的) | 测试方法名称必须以test开头 | 测试方法名称必须以test开头 |
创建测试类 | 必须以Test开头,并且不能带init方法 | 测试类的命名不做要求,但需要继承unittest.TestCase类。 |
添加测试固件(fixtrue 非必需) | setUp()、tearDown()系列方法 、 fixtrue装饰器 | 使用setUp()、tearDown()系列方法 |
测试类中定义测试方法(即测试用例) | 测试方法名称必须以test开头 | 测试方法名称必须以test开头 |
执行测试用例 | 通过主函数/命令行/配置文件 方式运行 | 通过主函数 或者 使用TestSuite/TestLoader/TextTestRunner |
主函数运行
import pytest
# 创建测试方法(不写在测试类中的)
def test_01():print("啥也没有")
# 通过主函数方式运行
if __name__=='__main__':pytest.main()
main()中可使用的参数有:
参数 | 描述 | 案例 |
---|---|---|
-v | 输出调试信息。 | 如:打印信息 pytest.main([‘-v’,‘testcase/test_one.py’,‘testcase/test_two.py’]) |
-s | 输出更详细的信息,如:文件名、用例名 | pytest.main([‘-vs’,‘testcase/test_one.py’,‘testcase/test_two.py’]) |
-n | 多线程或分布式运行测试用例 | |
-x | 只要有一个用例执行失败,就停止执行测试 | pytest.main([‘-vsx’,‘testcase/test_one.py’]) |
– maxfail | 出现N个测试用例失败,就停止测试 | pytest.main([‘-vs’,‘-x=2’,‘testcase/test_one.py’] |
–html=report.html | 生成测试报告 | pytest.main([‘-vs’,‘–html=./report.html’,‘testcase/test_one.py’]) |
-m | 通过标记表达式执行 | |
-k | 根据测试用例的部分字符串指定测试用例,可以使用and,or |
命令行运行
文件路径:testcase/test_one.py
def test_a():print("啥也没有")assert 1==1
终端输入:pytest ./testcase/test_one.py --html=./report/report.html
命令行中可使用的参数有:
参数 | 描述 | 案例 |
---|---|---|
-v | 输出调试信息。 | pytest -x ./testcase/test_one.py |
-q | 输出简单信息。 | pyets -q ./testcase/test_one.py |
-s | 输出更详细的信息,如:文件名、用例名 | pytest -s ./testcase/test_one.py |
-n | 多线程或分布式运行测试用例 | |
-x | 只要有一个用例执行失败,就停止执行测试 | pytest -x ./testcase/test_one.py |
– maxfail | 出现N个测试用例失败,就停止测试 | pytest --maxfail=2 ./testcase/test_one.py |
–html=report.html | 生成测试报告 | pytest ./testcase/test_one.py --html=./report/report.html |
-k | 根据测试用例的部分字符串指定测试用例,可以使用and,or |
执行结果代码说明
- Exit code 0 所有用例执行完毕,全部通过
- Exit code 1 所有用例执行完毕,存在Failed的测试用例
- Exit code 2 用户中断了测试的执行
- Exit code 3 测试执行过程发生了内部错误
- Exit code 4 pytest 命令行使用错误
- Exit code 5 未采集到可用测试用例文件
pytest.ini配置文件方式运行(推荐)
不管是mian执行方式还是命令执行,最终都会去读取pytest.ini文件。
配置有 pytest.ini 的工程, 只需要打开命令行输入pytest,即可进行测试。
在项目的根目录下创建pytest.ini文件,包含以下内容
[pytest]
addopts=-vs -m slow --html=./report/report.html
testpaths=./scripts
test_files=test_*.py
test_classes=Test*
test_functions=test_*
makerers=smock:冒烟测试用例regression: 回归测试标记
参数 | 作用 |
---|---|
[pytest] | 用于标志这个文件是pytest的配置文件 |
addopts | 命令行参数,多个参数之间用空格分隔 |
testpaths | pytest要进行测试的工作目录 |
test_files | 工作目录下要进行测试的文件名匹配规则 |
test_classes | 工作目录下 测试文件中 可执行类的名称匹配规则 |
test_functions | 测试类中 测试方法名的匹配规则 |
markers | 用例标记,自定义mark,需要先注册标记 |
使用markers标记测试用例
在 pytest 中,markers 是一种非常有用的功能,它可以对测试用例进行标记,以便实现更灵活的测试执行和分组等操作。
**在pytest.ini文件中自定义 markers。**例如:
makerers=
smock:冒烟测试用例
regression: 回归测试标记
这里创建了冒烟测试和回归测试的标记,我们就可以使用这个标记为测试用例进行标记。如下所示:
import pytest@pytest.mark.smoke
def test_01():assert 1==1@pytest.mark.regression
def test_02():assert 2==2
如果不想每次都输入-m smoke,我们可以把这部分放到pytest.ini下。
pytest中添加Fixture(测试夹具)
pytest中的setup与teardown
Pytest也提供了类似于unittest中 setup、teardown的方法,并且分为了五类:
- 模块级别:setup_module、teardown_module
- 函数级别:setup_function、teardown_function,不在类中的方法
- 类级别:setup_class、teardown_class
- 方法级别:setup_method、teardown_method
- 方法细化级别:setup、teardown
我们直接来看代码和运行结果
#!/usr/bin/env python
# -*- coding: utf-8 -*-import pytestdef setup_module():print("=====整个.py模块开始前只执行一次:打开浏览器=====")def teardown_module():print("=====整个.py模块结束后只执行一次:关闭浏览器=====")def setup_function():print("===每个函数级别用例开始前都执行setup_function===")def teardown_function():print("===每个函数级别用例结束后都执行teardown_function====")def test_one():print("one")def test_two():print("two")class TestCase():def setup_class(self):print("====整个测试类开始前只执行一次setup_class====")def teardown_class(self):print("====整个测试类结束后只执行一次teardown_class====")def setup_method(self):print("==类里面每个用例执行前都会执行setup_method==")def teardown_method(self):print("==类里面每个用例结束后都会执行teardown_method==")def setup(self):print("=类里面每个用例执行前都会执行setup=")def teardown(self):print("=类里面每个用例结束后都会执行teardown=")def test_three(self):print("three")def test_four(self):print("four")if __name__ == '__main__':pytest.main(["-q", "-s", "-ra", "setup_teardown.py"])
注意,从执行结果我们可以看到:
- 模块级别:setup_module、teardown_module 在整个.py模块开始前和结束后只执行一次;
- 函数级别:setup_function、teardown_function,对不在类中的方法生效。在每个函数级别用例开始前和结束后执行;
- 类级别:setup_class、teardown_class,整个测试类开始前和结束后执行一次;
- 方法级别:setup_method、teardown_method,测试类里面每个测试用例开始前和结束后都执行一次;
- 方法细化级别:setup、teardown,跟前面方法级别使用类似,不过setup在setup_method之后执行,teardown在teardown_method之前执行;
Pytest除了与unittest中类似的提供了setup和teardown方法外,还提供了使用装饰器的格式来为测试用例添加Fixture。
conftest
在介绍装饰器格式的Fixture前,先介绍conftest。
Conftest它是pytest的一个组件,用于配置测试环境和参数。
因此,conftest.py 文件是存放测试夹具(Fixtures)的理想场所。
测试夹具就像是测试用例执行时的得力助手,能够为测试提供各种必要的资源,如数据、对象、环境等。
通过在 conftest.py 中定义测试夹具,我们可以在多个测试模块中轻松地共享和复用这些资源,避免了在每个测试文件中重复编写相同的准备代码,大大提高了代码的可维护性和测试效率。
- 运行测试之前,pytest会自动识别并执行conftest.py文件中的配置。
- 运行测试之前,pytest 会默认读取 conftest.py里面的所有 fixture
- conftest.py 文件名称是固定的,不能改动
- conftest.py 只对同一个 package 下的所有测试用例生效
- 不同目录可以有自己的 conftest.py,一个项目中可以有多个 conftest.py
- 测试用例文件中不需要手动 import conftest.py,pytest 会自动查找
** 各级工作目录下的conftest.py**
pytest中的fixtrue装饰器
我们可以在conftest.py中,或者是测试模块中定义fixtrue装饰器。
如果有以下场景:1.用例一需要执行登录操作;2.用例二不需要执行登录操作;3.用例三需要执行登录操作,则unittest框架中的setup和teardown则不满足要求。而Pytest中的fixture装饰器就可以解决这一问题
pytest中的fixtrue装饰器的优势
- 命名方式灵活,不限于setup和teardown两种命名
- conftest.py可以实现数据共享,不需要执行import 就能自动找到fixture装饰器
Fixture装饰器的定义方式
@pytest.fixture(scope = "function",params=None,autouse=False,ids=None,name=None)
fixtrue装饰器参数详解-scope
用于控制Fixture装饰器的作用范围,默认取值为function(函数级别)
取值 | 范围 | 说明 |
---|---|---|
function | 函数级 | 每一个函数或方法都可以调用,在测试用例执行前生效。 |
class | 模块级 | 测试类内的测试用例可以调用,具体在何处生效得视情况而定 |
module | 模块级 | 每一个.py文件调用一次, 在第一次调用fixtrue的地方生效 |
session | 会话级 | 每次会话只运行一次,会话内所有方法及类,模块都共享这个fixtrue |
scope = “function”
- 场景一:做为参数传入
import pytest@pytest.fixture()
def login():print("打开浏览器")a = "account"return a@pytest.fixture()
def logout():print("关闭浏览器")class TestLogin:#传入lonin fixturedef test_001(self, login):print("001传入了loging fixture")assert login == "account"#传入logout fixturedef test_002(self, logout):print("002传入了logout fixture")def test_003(self, login, logout):print("003传入了两个fixture")def test_004(self):print("004未传入仍何fixture哦")if __name__ == '__main__':pytest.main()
从运行结果可以看出,fixture函数做为参数传入时,会先执行所有的fixture函数。
- 场景二:Fixture的相互调用
import pytest@pytest.fixture()
def account():a = "account"print("第一层fixture")return a#Fixture的相互调用一定是要在测试类里调用这层fixture才会生次,普通函数单独调用是不生效的
@pytest.fixture()
def login(account):print("第二层fixture")class TestLogin:def test_1(self, login):print("直接使用第二层fixture,返回值为{}".format(login))def test_2(self, account):print("只调用account fixture,返回值为{}".format(account))if __name__ == '__main__':pytest.main()
1.即使fixture之间支持相互调用,但普通函数直接使用fixture是不支持的,一定是在测试类中的测试函数内调用才会逐级调用生效
2.有多层fixture调用时,最先执行的是最内层fixture,而不是先执行传入测试函数的fixture
3.上层fixture的值不会自动return,这里就类似函数相互调用一样的逻辑
scope = “class”
当fixture的作用范围是class时, 具体如何生效要根据fixture的写法来决定。一共有两种情况
1.当测试类内的每一个测试方法都调用了fixture,fixture只在该class下所有测试用例执行前执行一次
2.测试类下面只有部分测试方法使用了fixture函数名。fixture只在该class下第一个使用fixture函数的测试用例执行前执行一次
- 场景一: 每一个测试方法都调用了fixture
import pytest
# fixture作用域 scope = 'class'
@pytest.fixture(scope='class')
def login():print("scope为class")class TestLogin:def test_1(self, login):print("用例1")def test_2(self, login):print("用例2")def test_3(self, login):print("用例3")if __name__ == '__main__':pytest.main()
- 场景二: 部分测试方法都调用了fixture
import pytest
@pytest.fixture(scope='class')
def login():a = '123'print("输入账号密码登陆")class TestLogin:def test_1(self):print("用例1")def test_2(self, login):print("用例2")def test_3(self, login):print("用例3")def test_4(self):print("用例4")if __name__ == '__main__':pytest.main()
scope = “module”
import pytest@pytest.fixture(scope='module')
def login():print("fixture范围为module")def test_01():print("用例01")def test_02(login):print("用例02")class TestLogin():def test_1(self):print("用例1")def test_2(self):print("用例2")def test_3(self):print("用例3")if __name__ == '__main__':pytest.main()
fixtrue参数详解-autouse
默认False
若为True,每个测试函数都会自动调用该fixture,无需传入fixture函数,作用范围跟着scope走
autouse=ture的效果如下:
测试用例添加、加载、运行(对比unittest)
- 如果要运行多个测试用例,unittest提供了TestSuite/TestLoader的方法加载测试用例,随后利用TextTestRunner执行测试用例套件。
- Pytest 可通过pytest.ini配置文件 确定测试的工作目录。对测试方法、测试类、测试模块的命名进行了约束后,在配置文件中写好名称匹配规则后,通过主函数或者命令行的方式运行。Pytest会自动加载符合条件的测试用例并运行。
pytest跳过测试用例skip、skipif
@pytest.mark.skip
跳过执行测试,有可选参数 reason:跳过的原因,会在执行结果中打印
@pytest.mark.skip可以加在函数上,测试类上,测试类中的方法上
如果加在测试类上面,测试类里面的所有测试用例都不会执行
import pytest@pytest.mark.skip(reason="不执行该用例!!因为没写好!!")
def test_case01():print("skip加在函数上")@pytest.mark.skip(reason="skip加在测试类上")
class TestSkip:def test_1(self):print("%% 不会执行 %%")def test_2(self):print("%% 不会执行 %%")class Test1:@pytest.mark.skip(reason="skip加在测试类中的方法上")def test_1(self):print("%% 不会执行 %%")
@pytest.mark.skipif
方法:
skipif(condition, reason=None)
参数:
condition:跳过的条件,必传参数
reason:标注原因,必传参数
使用方法:
@pytest.mark.skipif(condition, reason=“xxx”)
import pytest
class Test_ABC:def setup_class(self):print("------->setup_class")def teardown_class(self):print("------->teardown_class")def test_a(self):print("------->test_a")assert 1@pytest.mark.skipif(condition=2>1,reason = "跳过该函数")def test_b(self):print("------->test_b")assert 0
执行结果:test_abc.py ------->setup_class------->test_a #只执行了函数test_a.------->teardown_classs # 跳过函数
跳过标记
可以将 pytest.mark.skip 和 pytest.mark.skipif 赋值给一个变量,在不同模块之间共享这个变量。可以用一个单独的文件去管理这些通用标记
# 标记
skipmark = pytest.mark.skip(reason="不能在window上运行=====")
skipifmark = pytest.mark.skipif(sys.platform == 'win32', reason="不能在window上运行啦啦啦=====")@skipmark
class TestSkip_Mark(object):@skipifmarkdef test_function(self):print("测试标记")def test_def(self):print("测试标记")@skipmark
def test_skip():print("测试标记")
Pytest参数化
@pytest.mark.parametrize(argnames, argvalues);# argnames 含义:参数列表
# argvalues 含义:参数值列表# 例如:
@pytest.mark.parametrize("test_input,expected", [("3+5", 8), ("2+4", 6), ("6*9", 42)])
def test_eval(test_input, expected):print(f"测试数据{test_input},期望结果{expected}")assert eval(test_input) == expected
# 参数列表就是"test_input,expected" 与函数中的形参一致。 参数值必须是一个列表,且由于有两个参数,需要以元组的方式存放
# 如果只有一个参数,如:@pytest.mark.parametrize(“username”, [“yy”, “yy2”, “yy3”])
# 如果有多个参数例,则需要用元组来存放值,一个元组对应一组参数的值
函数返回值作为参数
import pytest
def return_test_data():# 中间代码掠过return [(1,2),(0,3)]
class Test_ABC:def setup_class(self):print("------->setup_class")def teardown_class(self):print("------->teardown_class")@pytest.mark.parametrize("a,b",return_test_data()) # 使用函数返回值的形式传入参数值def test_a(self,a,b):print("test data:a=%d,b=%d"%(a,b))assert a+b == 3执行结果:test_abc.py ------->setup_classtest data:a=1,b=2 # 运行第一次取值 a=1,b=2.test data:a=0,b=3 # 运行第二次取值 a=0,b=3.------->teardown_class
“笛卡尔积”,多个参数化装饰器
# 笛卡尔积,组合数据
data_1 = [1, 2, 3]
data_2 = ['a', 'b']
@pytest.mark.parametrize('a', data_1)
@pytest.mark.parametrize('b', data_2)
def test_parametrize_1(a, b):print(f'笛卡尔积 测试数据为 : {a},{b}')
输出测试报告
目前主流的与Pytest搭配的测试报告是Allure,Allure是一个灵活轻量级多语言测试报告工具。
关于Allure会在另外一篇博文中介绍。
预期失败函数
作用
期望测试用例是失败的,但是仍会运行此测试用例,并且也不会影响其他测试用例的的执行。
如果预期失败的测试用例执行失败,则输出结果是xfail(不会额外显示出错误信息)
如果预期失败的测试用例执行成功,则输出结果是xpass。(不符合预期的成功)
应用场景
- 用例功能不完善,或者用例执行一直失败。
- 对尚未实现的功能进行测试时。
- 尚未修复的错误进行测试时。
语法与参数
@pytest.mark.xfail(condition=None, reason=None);
-
condition:表示预期结果,然后用例实际执行的结果,与预期结果对比,会出现4种测试结果状态。
failed, passed, xfailed, xpassed。
提示:condition可以等于True或者False,也可以等于一个表达式,如:condition=1>2等。 -
reason:说明用例标记为预期失败的原因, 默认为None。(必填)
另外,我们也可以通过pytest.xfail方法在用例执行过程中直接标记用例结果为XFAIL,并跳过剩余的部分:
def test_function():if not valid_config():pytest.xfail("failing configuration (but should work)")
控制方法执行顺序
在使用 Pytest 进行单元测试或集成测试时,通常测试用例的执行顺序是自动排序的。不过在某些情况下,特别是当测试用例存在依赖关系时,我们可能希望自定义测试的执行顺序。为了解决这一需求,Pytest 提供了一个实用插件——pytest-ordering。
简介
pytest-ordering 是 Pytest 的一个插件,允许我们自定义测试用例的执行顺序。通过为测试用例指定顺序标记,可以在确保测试独立性的同时,满足特定的执行需求。
安装 pytest-ordering
pip install pytest-ordering
使用方法
在安装插件后,可以使用 @pytest.mark.run 标记来为测试用例设置执行顺序。常用的执行顺序标记有以下几种:
- @pytest.mark.run(order=N):使用具体的整数值 N 定义执行顺序,数字越小,优先级越高。
- @pytest.mark.run(before=‘test_name’):表示当前测试用例应在指定测试 test_name 之前运行。
- @pytest.mark.run(after=‘test_name’):表示当前测试用例应在指定测试 test_name 之后运行。
示例
示例1:基于 order 的执行顺序
import pytest@pytest.mark.run(order=2)
def test_case_1():assert True@pytest.mark.run(order=1)
def test_case_2():assert True@pytest.mark.run(order=3)
def test_case_3():assert True
执行顺序将按照 order 的值来确定,因此运行顺序为:test_case_2 -> test_case_1 -> test_case_3。
示例2:基于 before/after 的执行顺序
import pytest@pytest.mark.run(before="test_case_2")
def test_initial_setup():assert Truedef test_case_1():assert True@pytest.mark.run(after="test_case_1")
def test_case_2():assert True
在此示例中,执行顺序为 test_initial_setup -> test_case_1 -> test_case_2。
失败重试
有时候用例失败并非代码问题,而是由于网络等因素,导致请求失败。从而降低了自动化用例的稳定性,最后还要花时间定位到底是自身case的原因还是业务逻辑问题,还是其他原因,增加了定位成本。
增加容错机制,失败重试,会解决大部分由于网络原因、服务重启等原因造成的case失败问题。那该如何增加失败重试机制呢?使用pytest-rerunfailures插件来实现失败重试功能。
简介
pytest-rerunfailures 是一个基于 pytest 框架的插件,它允许我们对测试用例进行失败重试。当一个测试用例失败时,插件会自动重新运行失败的测试用例,直到达到预定的重试次数或测试用例通过为止。这样可以增加用例的稳定性,并减少因为偶发性问题导致的测试失败。
文档地址:
https://github.com/pytest-dev/pytest-rerunfailures
https://pypi.org/project/pytest-rerunfailures/#description
安装
pip install pytest-rerunfailures
使用方法
装饰器方式
import pytest
# 参数:reruns=n(重新运行次数),reruns_delay=m(每次重试之间的延迟时间)
@pytest.mark.flaky(reruns=3, reruns_delay=2)
def test_case():
assert 1 == 2
运行case,看一下执行结果:
# 执行命令
pytest -s -v test_demo.py::test_case# 结果
RERUN
test_dir/test_demo.py::test_case RERUN
test_dir/test_demo.py::test_case RERUN
test_dir/test_demo.py::test_case FAILED
可以看到,重试了3次,最终结果为失败。
参数添加运行方式
pytest-rerunfailures支持使用命令行选项和配置文件的方式进行配置。
并且是对所有的测试用例生效
# 在命令行运行中添加参数 --reruns 3 --reruns-delay 2
pytest -s -v --reruns 3 --reruns-delay 2 test_demo.py::test_case# 主函数运行中添加参数
pytest.main(["-s", "-v", "--reruns", "3", "--reruns-delay", "2", "test_demo.py::test_case"])# 或者在pytest.ini配置文件addopts中添加参数
addopts=-vs --reruns 3 --reruns-delay 2 --html=./report/report.html
注意:如果指定了用例的重新运行次数,则在命令行添加 --reruns 对这些用例是不会生效的
参考目录
https://www.bilibili.com/video/BV18Q4y1y7v3
https://blog.csdn.net/kkkkk19980517/article/details/139065687
https://blog.csdn.net/lovedingd/article/details/98952868
https://blog.csdn.net/qq_42610167/article/details/101204066
https://blog.csdn.net/qq_45609369/article/details/140007322
https://blog.csdn.net/m0_63463510/article/details/145914339
https://blog.csdn.net/m0_37135615/article/details/146145220
https://blog.csdn.net/fyyaom/article/details/102938704
https://blog.csdn.net/cebawuyue/article/details/144106872
https://blog.csdn.net/weixin_56331124/article/details/145190520
相关文章:

WEB UI自动化测试之Pytest框架学习
文章目录 前言Pytest简介Pytest安装Pytest的常用插件Pytest的命名约束Pytest的运行方式Pytest运行方式与unittest对比主函数运行命令行运行执行结果代码说明 pytest.ini配置文件方式运行(推荐)使用markers标记测试用例 pytest中添加Fixture(测…...

深入理解 iOS 开发中的 `use_frameworks!`
在使用 CocoaPods 管理 iOS 项目依赖时,开发者经常会在 Podfile 文件中看到一个配置选项:use_frameworks!。本文将详细介绍这个配置选项的含义,以及如何决定是否在项目中使用它。 一、什么是 use_frameworks! 在 CocoaPods 中引入第三方库时…...

矩阵置零算法讲解
矩阵置零算法讲解 一、问题描述 给定一个 (m \times n) 的矩阵,如果一个元素为 (0) ,则将其所在行和列的所有元素都设为 (0) 。要求使用原地算法,即在不使用额外矩阵空间的情况下完成操作。 二、解题思路 暴力解法 最直观的想法是遍历矩阵,当遇到 (0) 元素时,直接将其…...

二本计算机,毕业=失业?
我嘞个豆,二本计算机,毕业即失业?! 今天咱们聊聊普通院校计算机专业的学生未来的发展方向。有些话可能不太中听,但希望大家能理性看待。 首先得承认,对于普通双非和二本的学生来说,就业率加上…...
Java 并发编程挑战:从原理到实战的深度剖析与解决方案
Java 作为企业级应用开发的主流语言,其多线程能力是支撑高并发场景的核心。然而,线程安全、死锁、性能瓶颈等问题仍是开发者难以绕过的暗礁。本文将从 JVM 内存模型、并发工具链到实际案例,系统性揭示 Java 并发编程的挑战与解决方案…...
机器学习第六讲:向量/矩阵 → 数据表格的数学表达,如Excel表格转数字阵列
机器学习第六讲:向量/矩阵 → 数据表格的数学表达,如Excel表格转数字阵列 资料取自《零基础学机器学习》。 查看总目录:学习大纲 关于DeepSeek本地部署指南可以看下我之前写的文章:DeepSeek R1本地与线上满血版部署:…...

[docker基础二]NameSpace隔离实战
目录 一 实战目的 二 基础知识 1)dd 命令详解 2)mkfs命令详解 3)df命令详解 4)mount 命令详解 5)unshare命令详解 三 实战操作一(PID隔离) 四 实战操作二(MOunt隔离) 1)创建 Mount 隔离进程 2)在新进程里边,创建空白文件&#…...

Day22打卡-复习
复习日 仔细回顾一下之前21天的内容,没跟上进度的同学补一下进度。 作业: 自行学习参考如何使用kaggle平台,写下使用注意点,并对下述比赛提交代码 泰坦尼克号人员生还预测https://www.kaggle.com/competitions/titanic/overview K…...
Express知识框架
一、核心概念 1. Express 简介 Node.js 的 Web 框架,提供 HTTP 服务器封装 轻量级但灵活,支持中间件扩展 基于路由,支持 RESTful API 和传统 MVC 架构 无内置 ORM 或模板引擎,但可集成第三方库 2. 核心对象 express() - 创建…...

uniapp + vue3 + 京东Nut动作面板组件:实现登录弹框组件(含代码、案例、小程序截图)
uniapp + vue3 + 京东Nut动作面板组件:实现登录弹框组件(含代码、案例、小程序截图) 代码示下,不再赘述。 动作面板组件:https://nutui-uniapp.netlify.app/components/feedback/actionsheet.html 项目背景 业务需求 描述: uniapp + vue3 + 京东Nut框架:实现登录弹框组…...

C++类和对象--中阶
C类和对象中阶 01. 类的6个默认成员函数 在 C 中,类有 6 个特殊的默认成员函数(不是 6 个构造函数),它们会在特定情况下由编译器自动生成。包括构造函数,析构函数,拷贝构造和赋值运算符重载,取…...
OSPF的四种特殊区域(Stub、Totally Stub、NSSA、Totally NSSA)详解
OSPF的四种特殊区域(Stub、Totally Stub、NSSA、Totally NSSA)通过限制LSA的传播来优化网络性能,减少路由表规模。以下是它们的核心区别: 1. Stub 区域(末梢区域) 允许的LSA类型:Type 1-3&#…...

数据签名在区块链中的独特应用与挑战
随着信息技术的飞速发展,分布式系统因其高效、可靠、可扩展等显著优点,在众多领域得到了极为广泛的应用。分布式系统通过网络将多个独立的计算节点连接在一起,协同完成复杂的任务,这种架构使得系统具备了强大的容错能力和负载均衡…...

数据可视化大屏——物流大数据服务平台(二)
代码分析: 物流大数据平台代码分析 这是一个基于 Bootstrap 和 ECharts 构建的物流大数据平台前端页面,设计采用了经典的三栏布局,主要展示河南省及全国的物流数据可视化内容。下面从多个维度进行分析: 1. 页面结构分析 整体采…...
5倍无损压缩+50 倍速转换HD Video 4K/8K 视频处理
各位视频处理小达人们,我跟你们说啊!有个超厉害的专业视频处理软件,叫HD Video Converter Factory Pro,简称HDVC,是WonderFox公司开发的。这软件功能老强大了,下面我给你们详细唠唠! 先说说它的…...
Vue学习百日计划-Deepseek版
阶段1:基础夯实(Day 1-30) 目标:掌握HTML/CSS/JavaScript基础,理解Vue核心概念和基础语法。 每日学习内容(2小时): HTML/CSS(Day 1-10) 学习HTML标签语义化…...

Maven 处理依赖冲突
Maven处理依赖冲突 什么是依赖冲突?如何解决?Maven自动处理依赖冲突的规则路径优先原则第一声明优先原则注意 子模块覆盖父模块父模块声明dependency子模块覆盖dependency父模块声明dependencyManagement 子模块覆盖dependency父模块声明dependencyManag…...

5.12第四次作业
实验要求:完成上图内容,要求五台路由器的环回地址均可以相互访问 AR1 AR2 AR3 AR4 AR5 AS 200 ospf配置 AR2 AR3 AR4 BGP配置 AR1(AS100) AR2(AS200) AR4 AR5(AS300) 结果...

【Lattice FPGA 开发】Diamond在线调试Reveal逻辑乱跳的解决
在Vivado中在always块中写逻辑时如果出现always块中的异步复位敏感词在块内部未使用的情况,如下例的rst: always (posedge clk or posedge rst) begin if(~tx_sense_flag)o_rd_adr < d1;else if((o_rd_adr d94) & (bit_cnt d7))o_rd_adr <…...

Go语言——kratos微服务框架使用
文章目录 一、安装依赖二、创建项目三、初始化项目四、使用git_bash命令终端运行命令五、创建自己的项目1、修改app.proto3、internal/service/app.go4、修改internal/service/service.go文件5、创建internal/biz/content.go文件6、修改internal/biz/biz.go文件7、创建internal…...
动作识别笔记
一些casual paper review 动作识别Input 从前:RGB,然后 RGB+2D pose 接着各种手工modalities,现在是纯pose 但是包含了 多人 interactive的pose Graph from skeleton verticies: keypoints,Edges: just joint btw keypoints一个训练的sample 是一个 panoramic graph, con…...

hiveserver2与beeline进行远程连接hive配置及遇到的问题
1、hiveserver2 参与用户模拟功能,因为开启后才能保证各用户之间的权限隔离。 1.1、配置 $HADOOP_HOME/etc/hadoop/core-site.xml <!--配置所有节点的root用户都可作为代理用户--> <property><name>hadoop.proxyuser.root.hosts</name>&…...

Stable Diffusion进阶之Controlnet插件使用
前面已经对Stable Diffusion的文生图和图生图的操作界面做了详细的介绍,接下来会介绍Stable Diffusion的进阶部分Controlnet插件的使用。往期文章详见: 爆肝整理!Stable Diffusion的完全使用手册(一)爆肝整理ÿ…...
解决vue create 创建项目,不能使用上下键选择模板的问题
使用 git bash 创建vue项目时候,无法使用上下键盘按键选择创建模板 处理: 1.当前界面,按CTR C终止创建命令; 2.使用 alias vuewinpty vue.cmd,更新命令环境; 3.再次使用 vue create demo创建项目…...

Multisim14使用教程详尽版--(2025最新版)
一、Multisim14前言 1.1、主流电路仿真软件 1. Multisim:NI开发的SPICE标准仿真工具,支持模拟/数字电路混合仿真,内置丰富的元件库和虚拟仪器(示波器、频谱仪等),适合教学和竞赛设计。官网:艾…...

使用Stable Diffusion(SD)中,步数(Steps)指的是什么?该如何使用?
Ⅰ定义: 在Stable Diffusion(SD)中,步数(Steps) 指的是采样过程中的迭代次数,也就是模型从纯噪声一步步“清晰化”图像的次数。你可以理解为模型在画这张图时“润色”的轮数。 Ⅱ步数的具体作…...
《Asp.net Mvc 网站开发》复习试题
一.选择题(注:每题2分,共 54分,只能在下列表格中,填写每个题目相应的正确字母选项) 01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: :27: 1. Mvc让软件…...

【se-res模块学习】结合CIFAR-10分类任务学习
继CIFAR-10图像分类:【Res残差连接学习】结合CIFAR-10任务学习-CSDN博客 再优化 本次训练结果在测试集上的准确率表现可达到90%以上 1.训练模型(MyModel.py) import torch import torch.nn as nnclass SENet(nn.Module): # SE-Net模块def…...

【C++设计模式之Template Method Pattern】
C设计模式之Template Method Pattern 模式定义核心思想动机(Motivation)结构(Structure)实现步骤应用场景要点总结 模式定义 模式定义: 定义一个操作中的算法的骨架(稳定),而将一些步骤延迟(变化)到子类中。Template Method使得子…...
JVM对象头中的锁信息机制详解
JVM对象头中的锁信息机制详解 Java中的对象锁机制是高性能并发的基石,而这一切的底层实现都离不开对象头中的 Mark Word 字段。本文将系统梳理JVM对象头中锁信息的存储与演化机制,解析锁升级与批量重偏向优化原理,并通过JOL工具实战验证对象…...