二、pytest测试框架基础使用

一、pytest的基础插件

pytest-xdist 测试用例分布式执行。多CPU分发。
pytest-ordering 用于改变测试用例的执行顺序(从上到下)
pytest-rerunfailures 用例失败后重跑
pytest-html (生成html格式的自动化测试报告)
allure-pytest 用于生成美观的测试报告。

放到requirements.txt中,通过pip install -r requirements.txt

二、pytest测试用例默认规则

1.模块名必须以test_开头或者_test结尾            --> test_login.py
2.测试类必须以Test开头,并且不能有init方法。 --> TestLogin
3.测试方法必须以test开头                                 --> test_login

三、pytest测试用例的运行方式

 

# interface_case/test_login.py

def test_login():
    print("测试接口登录函数")


class TestLogin:

    def test_login(self):
        print("测试接口登录类")
# interface_case/test_logout.py

class TestLogout:

    def test_logout(self):
        print("测试接口注销类")
# web_case/test_login.py

class TestLogin:

    def test_login_01(self):
        print("测试WEB登录类01")

    def test_login_02(self):
        print("测试WEB登录类02")

    def test_login_03(self):
        print("测试WEB登录类03")

    def test_login_04(self):
        print("测试WEB登录类04")
# web_case/test_logout.py

class TestLogout:

    def test_logout(self):
        print("测试WEB注销类")
# all.py

import pytest

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

3.1 主函数模式

(1)运行所有:pytest.main()
(2)指定模块:pytest.main(['-vs','test_login.py'])
(3)指定目录:pytest.main(['-vs','./interface_testcase'])
(4)通过nodeid指定用例运行:nodeid由模块名,分隔符,类名,方法名,函数名组
成。
pytest.main(['-vs','./interface_testcase/test_interface.py::test_04_func'])
pytest.main(['-
vs','./interface_testcase/test_interface.py::TestInterface::test_03_zhiliao'])

参数详解:
    -s:表示输出调试信息,包括print打印的信息
    -v:显示更详细的信息
    -vs:这两个参数一起用
    -n:支持多线程或者分布式运行测试用例。 -n 后面的数字是几,就代表几个线程
        如:pytest -vs ./testcase/test_login.py -n 2
    --reruns NUM:失败用例重跑
    -x:表示只要要一个用例报错,那么测试停止。
    --maxfail=2 出现两个用例失败就停止。
    -k:根据测试用例的部分字符串指定测试用例。
        如:pytest -vs ./testcase -k "ao"
    --html ./report/report.html:生成html的测试报告。

3.1.1 运行所有: pytest.main()

 pytest.main()

3.1.2 指定模块:pytest.main(['-vs','test_login.py'])

pytest.main(['-vs','test_login.py'])

3.1.3 指定目录:pytest.main(['-vs','./interface_testcase'])

pytest.main(['-vs','./interface_testcase'])

3.1.4 指定函数(方法)pytest.main(["-vs", "./interface_testcase/test_login.py::test_login"])

pytest.main(["-vs", "./interface_testcase/test_login.py::test_login"])

3.1.5 分布式运行 pytest.main(["-vs", "./web_testcase/test_login.py", "-n =2"]) pytest.main(["-vs", "./web_testcase/test_login.py", "-n 2"])

pytest.main(["-vs", "./web_testcase/test_login.py", "-n =2"])    
pytest.main(["-vs", "./web_testcase/test_login.py", "-n 2"]) 
# web_case/test_login.py
import time
import pytest

class TestLogin:

    def test_login_01(self):
        time.sleep(3)
        print("测试WEB登录类01")

    def test_login_02(self):
        time.sleep(3)
        print("测试WEB登录类02")

    def test_login_03(self):
        time.sleep(3)
        print("测试WEB登录类03")

    def test_login_04(self):
        time.sleep(3)
        print("测试WEB登录类04")

 

开启2个线程,可以看到运行的时间从 12.04s -> 6.72s, 时间缩短了一半

3.1.6 失败用例重跑 pytest.main(["-vs", "./web_testcase/test_login.py", "--reruns=2"])

pytest.main(["-vs", "./web_testcase/test_login.py", "--reruns=2"])
# web_case/test_login.py
import pytest

class TestLogin:
    def test_login_01(self):
        print("测试WEB登录类01")

    def test_login_02(self):
        print("测试WEB登录类02")
        assert 1 == 2

    def test_login_03(self):
        print("测试WEB登录类03")

    def test_login_04(self):
        print("测试WEB登录类04")

 

3.1.7 一个用例报错,测试停止 pytest.main(["-vs", "./web_testcase/test_login.py", "-x"])

pytest.main(["-vs", "./web_testcase/test_login.py", "-x"])

3.2 命令行模式(在pycharm的Terminal中运行)

3.2.1 运行所有: pytest

pytest

 

3.2.2 指定模块:pytest -vs web_testcase/test_login.py

pytest -vs web_testcase/test_login.py

3.2.3 指定目录:pytest -vs ./interface_testcase

pytest -vs ./interface_testcase

3.2.4 指定函数(方法)pytest -vs ./interface_testcase/test_login.py::test_login

pytest -vs ./interface_testcase/test_login.py::test_login

3.2.5 分布式运行 pytest -vs ./testcase/test_login.py -n 2

pytest -vs ./testcase/test_login.py -n 2
# web_case/test_login.py
import time
import pytest

class TestLogin:

    def test_login_01(self):
        time.sleep(3)
        print("测试WEB登录类01")

    def test_login_02(self):
        time.sleep(3)
        print("测试WEB登录类02")

    def test_login_03(self):
        time.sleep(3)
        print("测试WEB登录类03")

    def test_login_04(self):
        time.sleep(3)
        print("测试WEB登录类04")

3.2.6 失败用例重跑 pytest -vs ./web_testcase/test_login.py --reruns 2

pytest -vs ./web_testcase/test_login.py --reruns 2

 

3.2.7 一个用例报错,测试停止 pytest -vs ./web_testcase/test_login.py -x

pytest -vs ./web_testcase/test_login.py -x

3.3 通过读取pytest.ini全局配置文件运行(最常见)

1. pytest.ini 是pytest单元测试框架的核心配置文件
2. 一般放置在项目的根目录
3. 编码格式必须是 ASCI格式, 可以使用notepad++修改格式
4. 文件的作用可以改变pytest的默认规则。
5. 运行的规则,不管是主函数的模式,还是命令行的模式,都会读取这个配置文件

[pytest]
;;命令行的参数,用空格分隔
addopts = -vs
;;测试用例的路径
testpaths = ./web_testcase
;;模块名的规则
python_files = test*.py
;;类名的规则
python_classes = Test*
;;方法名的规则
python_functions = test

[注意]: 中文需要删除,放在此处用于阅读方便

 直接pytest之后,如果没有pytest.ini文件,那么就会运行所有的用例,但是存在pytest.ini文件,并且文件指定了目录为 web_testcase,所以只会执行web_testcase下的用例。

并且如果当 python_files 为其他文件名的py文件时候,就会执行指定对应的文件名开头的文件的用例,同理类名和函数名也一个道理

四、pytest执行测试用例的顺序

# unittest:ascII的大小来绝对的执行的顺序
# pytest:默认从上到下
# 改变默认的执行顺序:使用mark标记。
@pytest.mark.run(order=3)
import pytest


class TestLogin:

    def test_login_06(self):
        print("测试WEB登录类06")

    def test_login_04(self):
        print("测试WEB登录类04")

    def test_login_07(self):
        print("测试WEB登录类07")

    def test_login_03(self):
        print("测试WEB登录类03")

 

# 默认情况下,从上往下依次执行,如果想要按照指定的过程来执行用例,需要使用装饰器来修改执行顺序
# @pytest.mark.run(order=3)

import pytest


class TestLogin:

    def test_login_06(self):
        print("测试WEB登录类06")

    @pytest.mark.run(order=1)
    def test_login_04(self):
        print("测试WEB登录类04")

    def test_login_07(self):
        print("测试WEB登录类07")

    @pytest.mark.run(order=2)
    def test_login_03(self):
        print("测试WEB登录类03")

 

# 注意: 当只存在一个标记的时候,不管标记的顺序是几,都按照顺序为1 执行,剩下的按照从上往下执行
import pytest

class TestLogin:

    def test_login_06(self):
        print("测试WEB登录类06")

    def test_login_04(self):
        print("测试WEB登录类04")

    def test_login_07(self):
        print("测试WEB登录类07")

    @pytest.mark.run(order=2)
    def test_login_03(self):
        print("测试WEB登录类03")

五、pytest如何分组执行(冒烟、分模块执行、分接口和web执行)pytest -m smoke

pytest -m smoke
pytest -m "smoke or usermanage"
;;pytest.ini markers将用例进行分类,最好要有,不然会有警告出现

[pytest]
addopts = -vs
testpaths = ./
python_files = test*.py
python_classes = Test*
python_functions = test
markers =
    smoke:冒烟模块
    usermanage:用户管理模块
    productmanage:商品管理模块
# interface_testcase/test_logout.py

import pytest

class TestLogout:

    @pytest.mark.smoke
    def test_logout(self):
        print("测试接口注销类")
# web_testcase/test_login.py

import pytest

class TestLogin:

    def test_login_06(self):
        print("测试WEB登录类06")

    @pytest.mark.smoke
    def test_login_04(self):
        print("测试WEB登录类04")
    
    @pytest.mark.usermanage
    def test_login_07(self):
        print("测试WEB登录类07")

    @pytest.mark.smoke
    def test_login_03(self):
        print("测试WEB登录类03")

 

 

;; 可以直接在 pytest.ini 文件中进行分组 

[pytest]
addopts = -vs -m smoke
testpaths = ./web_testcase/test_login.py
python_files = test*.py
python_classes = Test*
python_functions = test
markers =
    smoke:冒烟模块
    usermanage:用户管理模块
    productmanage:商品管理模块

六、pytest跳过测试用例

# (1)无条件跳过
@pytest.mark.skip(reason="薇薇太漂亮")

# (2)有条件跳过
@pytest.mark.skipif(age>=18,reason='已成年')
[pytest]
addopts = -vs
testpaths = ./web_testcase/test_login.py
python_files = test*.py
python_classes = Test*
python_functions = test
markers =
    smoke:冒烟模块
    usermanage:用户管理模块
    productmanage:商品管理模块
# web_testcase/test_login.py
import pytest


class TestLogin:
    age = 18

    def test_login_06(self):
        print("测试WEB登录类06")

    @pytest.mark.smoke
    @pytest.mark.skipif(age=18, reason="成年")
    def test_login_04(self):
        print("测试WEB登录类04")

    @pytest.mark.usermanage
    @pytest.mark.skip(reason="薇薇太漂亮")
    def test_login_07(self):
        print("测试WEB登录类07")

    @pytest.mark.smoke
    def test_login_03(self):
        print("测试WEB登录类03")

七、生成用例执行结果报告

--html ./report_html.html
[pytest]

addopts = -vs --html ./report_html.html
testpaths = ./web_testcase/test_login.py
python_files = test*.py
python_classes = Test*
python_functions = test

markers =
    smoke:冒烟模块
    usermanage:用户管理模块
    productmanage:商品管理模块

执行结束,会生成 report_html.html

 

 

posted on 2024-07-27 20:20  软饭攻城狮  阅读(2)  评论(0编辑  收藏  举报

导航