pytest教程(二):如何调用pytest和创建测试demo

1.安装pytest

pytest要求:Python 3.6、3.7、3.8、3.9或PyPy3。
(1)在命令行中执行如下命令:

pip install -U pytest

执行结果:
在这里插入图片描述

(2)检查你是否安装了正确的版本:

(venv) E:\auto_pytest>pytest --version
pytest 6.2.3

2.创建第一个测试

创建一个名为test_sample.py的新文件,包含一个函数和一个测试:

#!/usr/bin/env python 
# encoding: utf-8 
"""
@author: 九九的金金子
@file: test_sample.py.py
@time: 2021/4/12 11:56
"""
# content of test_sample.py
def func(x):
    return x + 1


def test_answer():
    assert func(3) == 5

执行及结果:

(venv) E:\auto_pytest>pytest test_sample.py
========================================================================== test session starts ==========================================================================
platform win32 -- Python 3.7.9, pytest-6.2.3, py-1.10.0, pluggy-0.13.1
rootdir: E:\auto_pytest
plugins: allure-pytest-2.8.32
collected 1 item                                                                                                                                                         

test_sample.py F                                                                                                                                                   [100%]

=============================================================================== FAILURES ================================================================================
______________________________________________________________________________ test_answer ______________________________________________________________________________

    def test_answer():
>       assert func(3) == 5
E       assert 4 == 5
E        +  where 4 = func(3)

test_sample.py:14: AssertionError
======================================================================== short test summary info ========================================================================
FAILED test_sample.py::test_answer - assert 4 == 5
=========================================================================== 1 failed in 0.13s ===========================================================================

[100%]指的是运行所有测试用例的总体进度。完成后,pytest会显示一个失败报告,因为func(3)不返回5。

注意:
您可以使用assert语句来验证测试期望。pytest的高级断言内将智能地报告断言表达式的中间值。

3.运行多个测试

pytest将运行当前目录及其子目录中所有形式为test_.py或_test.py的文件。更一般地说,它遵循标准的测试发现规则。
断言某个异常被引发
使用raises助手来断言某些代码引发异常:

#!/usr/bin/env python 
# encoding: utf-8 
"""
@author: 九九的金金子
@file: test_sysexit.py
@time: 2021/4/12 13:49
"""
# content of test_sysexit.py
import pytest


def f():
    raise SystemExit(1)


def test_mytest():
    with pytest.raises(SystemExit):
        f()

执行及结果:

(venv) E:\auto_pytest>pytest -q test_sysexit.py
.                                                                                                                                                                  [100%]
1 passed in 0.12s

q/——quiet标志在这个示例和下面的示例中保持输出简短。

4.将多个测试分组到一个类中

一旦开发了多个测试,您可能希望将它们分组到一个类中。pytest让创建包含多个测试的类变得很容易:

#!/usr/bin/env python 
# encoding: utf-8 
"""
@author: 九九的金金子
@file: test_class.py
@time: 2021/4/12 13:52
"""
# content of test_class.py
class TestClass:
    def test_one(self):
        x = "this"
        assert "h" in x

    def test_two(self):
        x = "hello"
        assert hasattr(x, "check")

pytest发现所有遵循Python测试发现约定的测试,因此它发现两个以test_为前缀的函数。不需要子类化任何东西,但是要确保用Test作为类的前缀,否则类将被跳过。我们可以简单地通过传递它的文件名来运行模块:
执行及结果:

(venv) E:\auto_pytest>pytest -q test_class.py
.F                                                                                                                                                                 [100%]
=============================================================================== FAILURES ================================================================================
__________________________________________________________________________ TestClass.test_two ___________________________________________________________________________

self = <test_class.TestClass object at 0x000001934888F248>

    def test_two(self):
        x = "hello"
>       assert hasattr(x, "check")
E       AssertionError: assert False
E        +  where False = hasattr('hello', 'check')

test_class.py:16: AssertionError
======================================================================== short test summary info ========================================================================
FAILED test_class.py::TestClass::test_two - AssertionError: assert False
1 failed, 1 passed in 0.12s

第一次测试通过了,第二次测试失败了。您可以很容易地看到断言中的中间值,以帮助您理解失败的原因。

将测试分组在类中是有益的,原因如下:

  • 测试组织
  • 仅为该特定类中的测试共享fixture
  • 在类级别上应用标记,并隐式地将它们应用于所有测试进入翻译页面

在将测试分组到类中时,需要注意的是每个测试都有一个类的唯一实例。让每个测试共享相同的类实例对测试隔离非常不利,并且会促进糟糕的测试实践。这一点概述如下:

#!/usr/bin/env python 
# encoding: utf-8 
"""
@author: 九九的金金子
@file: test_class_demo.py
@time: 2021/4/12 13:56
"""
# content of test_class_demo.py
class TestClassDemoInstance:
    def test_one(self):
        assert 0

    def test_two(self):
        assert 0

执行及结果:

(venv) E:\auto_pytest>pytest -k TestClassDemoInstance -q
FF                                                                                                                                                                 [100%]
=============================================================================== FAILURES ================================================================================
____________________________________________________________________ TestClassDemoInstance.test_one _____________________________________________________________________

self = <test_class_demo.TestClassDemoInstance object at 0x00000228F08E27C8>

    def test_one(self):
>       assert 0
E       assert 0

test_class_demo.py:11: AssertionError
____________________________________________________________________ TestClassDemoInstance.test_two _____________________________________________________________________

self = <test_class_demo.TestClassDemoInstance object at 0x00000228F08DE748>

    def test_two(self):
>       assert 0
E       assert 0

test_class_demo.py:14: AssertionError
======================================================================== short test summary info ========================================================================
FAILED test_class_demo.py::TestClassDemoInstance::test_one - assert 0
FAILED test_class_demo.py::TestClassDemoInstance::test_two - assert 0
2 failed, 5 deselected in 0.19s

请注意,在类级别添加的属性是类属性,因此它们将在测试之间共享。

5.为功能测试请求一个唯一的临时目录

pytest提供了内置的fixture /函数参数来请求任意资源,比如一个唯一的临时目录:

#!/usr/bin/env python 
# encoding: utf-8 
"""
@author: 九九的金金子
@file: test_tmp_path.py
@time: 2021/4/12 13:58
"""
# content of test_tmp_path.py
def test_needsfiles(tmp_path):
    print(tmp_path)
    assert 0

在测试函数签名中列出名称tmp_path, pytest将在执行测试函数调用之前查找并调用fixture工厂来创建资源。在运行测试之前,pytest创建一个每调用一次测试唯一的临时目录:
执行及结果:

(venv) E:\auto_pytest>pytest -q test_tmp_path.py
F                                                                                                                                                                  [100%]
=============================================================================== FAILURES ================================================================================
____________________________________________________________________________ test_needsfiles ____________________________________________________________________________

tmp_path = WindowsPath('C:/Users/01399256/AppData/Local/Temp/pytest-of-01399256/pytest-2/test_needsfiles0')

    def test_needsfiles(tmp_path):
        print(tmp_path)
>       assert 0
E       assert 0

test_tmp_path.py:11: AssertionError
------------------------------------------------------------------------- Captured stdout call --------------------------------------------------------------------------
C:\Users\01399256\AppData\Local\Temp\pytest-of-01399256\pytest-2\test_needsfiles0
======================================================================== short test summary info ========================================================================
FAILED test_tmp_path.py::test_needsfiles - assert 0
1 failed in 0.19s

关于临时目录处理的更多信息可以在临时目录和文件中找到。

找出该命令存在哪种类型的内置pytest fixture:

pytest --fixtures   # shows builtin and custom fixtures

注意,除非添加了-v选项,否则这个命令会省略以_开头的fixture。

猜你喜欢

转载自blog.csdn.net/daxiangaifashi/article/details/115620126