pytest命令允许参数

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了pytest命令允许参数相关的知识,希望对你有一定的参考价值。

参考技术A 1、-K EXPRESSION
执行某个关键字的用例
用例要匹配给出的表达式;使用python的语法,匹配的范围是文件名、类名、函数名为变量,用and来区分

pytest -k "test and TestClass and not test_a" test.py # test-文件名,TestClass-类名,test_a-函数名,not就是不运行函数名test_a函数

2、--maxfail=num
当错误个数到达给定数时,退出测试,这里就不列举实例了,结果与-x类似
-x,,如果遇到错误就停止

3、-m MARKEXPR
只能运行有相应标识的测试用例,使用这个参数,测试用例要使用@pytest.mark.marker修饰
pytest –m slow test.py # slow是测试用例函数使用了@pytest.mark.slow来修饰,执行这个
注意,-m后面不能带''号(单引号),只能带“”(双引号),不然识别不到
如果要运行多个标识的话,用表达式,如下
pytest -m "slow or faster" 运行有slow标识或 faster标识用例
pytest -m "slow and faster" 运行有slow和faster标识的用例
pytest -m "slow and not faster" 运行有slow和没有faster标识的用例

4、-v, --verbose
详细结果

5、-q, --quiet
极简结果显示,简化控制台的输出,可以看出输出信息和之前不添加-q不信息不一样, 下图中有两个..点代替了pass结果

6、-s
输入我们用例中的调式信息,比如print的打印信息等,我们在用例中加上一句 print(driver.title),我们再运行一下我们的用例看看,调试信息输出

7、 -V
可以输出用例更加详细的执行信息,比如用例所在的文件及用例名称等

8、--junit-xml=path
输出xml文件格式,在与jenkins做集成时使用

9、--result-log=path
将最后的结果保存到本地文件中

pytest文档69-Hook函数之参数化生成测试用例pytest_generate_tests

前言

pytest 实现参数化有三种方式

  • pytest.fixture() 使用 fixture 传 params 参数实现参数化
  • @ pytest.mark.parametrize 允许在测试函数或类中定义多组参数,在用例中实现参数化
  • pytest_generate_tests 允许定义自定义参数化方案或扩展。

pytest_generate_tests

pytest_generate_tests 在测试用例参数化收集前调用此钩子函数,根据测试配置或定义测试函数的类或模块中指定的参数值生成测试用例,
可以使用此钩子实现自定义参数化方案或扩展,相关文档参考官方文档https://docs.pytest.org/en/latest/parametrize.html#pytest-generate-tests

有时您可能想要实现自己的参数化方案或实现某种动态性来确定 fixture 的参数或范围。为此,可以使用pytest_generate_tests在收集测试函数时调用的钩子。通过传入的 metafunc 对象,您可以检查请求的测试上下文,最重要的是,您可以调用 metafunc.parametrize() 引起参数化。

例如,假设我们要运行一个测试,并接受要通过新的 pytest 命令行选项设置的字符串输入。让我们首先编写一个接受 stringinput 函数参数的简单测试:

# content of test_strings.py


def test_valid_string(stringinput):
    assert stringinput.isalpha()

现在,我们添加一个conftest.py文件,其中包含命令行选项和测试函数的参数化:

# content of conftest.py


def pytest_addoption(parser):
    parser.addoption(
        "--stringinput",
        action="append",
        default=[],
        help="list of stringinputs to pass to test functions",
    )


def pytest_generate_tests(metafunc):
    if "stringinput" in metafunc.fixturenames:
        metafunc.parametrize("stringinput", metafunc.config.getoption("stringinput"))

如果现在传递两个stringinput值,则测试将运行两次:

$ pytest -q --stringinput="hello" --stringinput="world" test_strings.py
..                                                                   [100%]
2 passed in 0.12s

我们还使用一个stringinput运行,这将导致测试失败:

$ pytest -q --stringinput="!" test_strings.py
F                                                                    [100%]
================================= FAILURES =================================
___________________________ test_valid_string[!] ___________________________

stringinput = '!'

    def test_valid_string(stringinput):
>       assert stringinput.isalpha()
E       AssertionError: assert False
E        +  where False = <built-in method isalpha of str object at 0xdeadbeef>()
E        +    where <built-in method isalpha of str object at 0xdeadbeef> = '!'.isalpha

test_strings.py:4: AssertionError
========================= short test summary info ==========================
FAILED test_strings.py::test_valid_string[!] - AssertionError: assert False
1 failed in 0.12s

不出所料,我们的测试功能失败。

如果您未指定字符串输入,则将跳过它,因为 metafunc.parametrize()将使用空参数列表来调用它:

$ pytest -q -rs test_strings.py
s                                                                    [100%]
========================= short test summary info ==========================
SKIPPED [1] test_strings.py: got empty parameter set ['stringinput'], function test_valid_string at $REGENDOC_TMPDIR/test_strings.py:2
1 skipped in 0.12s

请注意,当metafunc.parametrize使用不同的参数集多次调用时,这些集合中的所有参数名称都不能重复,否则会引发错误。
更多的参数化案例参考https://docs.pytest.org/en/latest/example/parametrize.html#paramexamples

使用示例

在 conftest.py 自定义参数化的钩子, 判断当测试用例传了 param 参数,就让它生成参数化的用例

def pytest_generate_tests(metafunc):
    """ generate (multiple) parametrized calls to a test function."""
    if "param" in metafunc.fixturenames:
        metafunc.parametrize("param",
                             metafunc.module.test_data,
                             ids=metafunc.module.names,
                             scope="function")

test_parm.py相关的测试数据和用例内容,names是用例的名称,test_data是测试数据

import requests

# 作者-上海悠悠 QQ交流群:717225969
# blog地址 https://www.cnblogs.com/yoyoketang/

# 用例的id名称
names = ["login nam1", "login name2"]
# 测试数据 list of dict
test_data = [{
                "url": "http://49.235.x.x:5000/api/v1/login/",
                "method": "POST",
                "headers":
                    {
                        "Content-Type": "application/json"
                    },
                "json":
                    {
                        "username": "test",
                        "password": "123456"
                    }

        },
        {
            "url": "http://49.235.x.x:5000/api/v1/login/",
            "method": "POST",
            "headers":
                {
                    "Content-Type": "application/json"
                },
            "json":
                {
                    "username": "test",
                    "password": "123456"
                }

        }
        ]


def test_login(param):
    r = requests.session().request(**param)
    print(r.text)

这样运行会,自动生成2条测试用例

================= test session starts ===============
platform win32 -- Python 3.6.6, pytest-4.5.0, py-1.9.0, pluggy-0.13.1
rootdir: D:\\
collected 2 items

..\\test_param.py 
{"code": 0, "msg": "login success!", "username": "test", "token": "81ae10099feaca6f0af5ba122444bea2a83a2dc9"}
.{"code": 0, "msg": "login success!", "username": "test", "token": "1ccfb99fd68f22da66c95660702af22d64108067"}
.

=============== 2 passed in 0.62 seconds ===============

上面是把测试数据和代码放一起,想实现代码和数据分离的话,上面的 names 和 test_data 测试数据写到 yaml 文件,写个函数去读取 yaml 文件的数据。

以上是关于pytest命令允许参数的主要内容,如果未能解决你的问题,请参考以下文章

pytest的基础(命名运行标签和断言)

pytest文档52-命令行参数--setup-show查看fixture的执行过程

pytest配置文件-随笔

Pytest02-pytest命名规则

pytest 用例编写规则命令行执行用例用例执行的先后顺序

pytest文档69-Hook函数之参数化生成测试用例pytest_generate_tests