使用Pytest进行单元测试的初学者指南

部署运行你感兴趣的模型镜像

1.引言

在软件开发过程中,测试是确保代码质量的关键环节。Python 拥有众多测试框架,而 pytest 是其中最受欢迎的之一。它以简洁的语法、强大的功能和丰富的插件生态系统而著称。本指南将深入介绍 pytest,帮助你掌握如何使用它来高效地测试 Python 代码。

2. 安装 pytest

安装 pytest 非常简单。如果你使用的是 Python 的虚拟环境(强烈推荐),首先激活虚拟环境,然后使用以下命令安装:

pip install pytest

如果你想安装特定版本的 pytest,可以在命令中指定版本号,例如:

pip install pytest==5.4.3

3. 第一个 pytest 测试用例

让我们从一个简单的例子开始,了解 pytest 是如何工作的。创建一个名为test_example.py的文件,内容如下:

def add(a, b):
    return a + b

def test_add():
    assert add(1, 2) == 3

在这个例子中,我们定义了一个add函数,然后编写了一个名为test_add的测试用例。测试用例使用assert语句来验证add函数的输出是否符合预期。要运行这个测试用例,在命令行中进入包含test_example.py文件的目录,然后运行:

pytest

如果一切正常,你将看到类似以下的输出:​​​​​​​

============================= test session starts =============================
platform linux -- Python 3.6.9, pytest-5.4.3, py-1.8.1, pluggy-0.13.1
root@5605836111362047397950633459331456893668-ubuntu
collecting... done
collected 1 item

test_example.py.

============================== 1 passed in 0.01s ==============================

这里的.表示测试通过。如果测试失败,将会显示详细的错误信息。

4. pytest 的基本概念

4.1 测试函数

pytest 通过识别以test_开头的函数名来确定测试函数。在上面的例子中,test_add就是一个测试函数。你可以在一个文件中定义多个测试函数,它们将按照顺序依次被测试。

4.2 断言

断言是测试用例中最重要的部分之一。它用于验证代码的输出是否符合预期。在 pytest 中,通常使用assert语句来进行断言。例如:​​​​​​​

def test_something():
    value = some_function()
    assert value == expected_value

如果value不等于expected_value,测试将失败,并显示详细的错误信息。

4.3 夹具(Fixtures)

夹具是 pytest 中一个非常重要的概念。它用于为测试用例提供一些前置条件和后置条件。例如,你可能需要在测试用例中使用一个数据库连接,夹具可以在测试开始前创建这个连接,并在测试结束后关闭它。夹具可以通过@pytest.fixture装饰器来定义,如下所示:​​​​​​​

@pytest.fixture
def database_connection():
    connection = create_database_connection()
    yield connection
    connection.close()

在这个例子中,database_connection是一个夹具,它创建了一个数据库连接,并在测试结束后关闭它。在测试用例中,可以使用这个夹具,如下所示:​​​​​​​

def test_database_operation(database_connection):
    result = do_satabase_operation(database_connection)
    assert result == expected_result

夹具可以有不同的作用域,例如函数级、类级、模块级和会话级。不同的作用域决定了夹具在测试过程中的重复使用方式。

4.4 测试模块和测试套件

一个测试模块是一个包含测试函数和夹具的 Python 文件。多个测试模块可以组成一个测试套件。你可以使用pytest命令来运行一个测试套件,它将自动收集所有的测试模块并进行测试。

4.5 标记(Markers)

标记是 pytest 中用于分类和筛选测试用例的一种手段。你可以使用@pytest.mark装饰器来给测试用例加上标记,例如:​​​​​​​

@pytest.mark.slow
def test_slow_function():
    # 执行一个耗时的操作
    pass

在这个例子中,test_slow_function被标记为slow。你可以使用pytest -m slow命令来只运行被标记为slow的测试用例。

5. 编写更复杂的测试用例

5.1 参数化测试

参数化测试是一种将测试用例中的某些参数进行变化的方法,从而可以用一个测试函数测试多个情况。例如,我们可以对上面的add函数进行参数化测试,如下所示:​​​​​​​

import pytest

@pytest.mark.parametrize("a,b,expected", [(1, 2, 3), (2, 3, 5), (3, 4, 7)])
def test_add(a, b, expected):
    assert add(a, b) == expected

在这个例子中,我们使用@pytest.mark.parametrize装饰器对test_add函数进行了参数化。参数化的参数为a、b和expected,分别对应add函数的两个输入参数和预期输出。通过这种方式,我们可以用一个测试函数测试add的多个输入输出组合。

5.2 处理异常

有时候我们需要测试代码在出现异常时的行为。在 pytest 中,可以通过@pytest.mark.raises装饰器来测试异常,如下所示:​​​​​​​

import pytest

@pytest.mark.raises(Exception)
def test_division():
    with open('non-existent-file.txt', 'r') as f:
        content = f.read()

在这个例子中,test_division被标记为raises,并且期望在执行代码时出现Exception类型的异常。如果没有出现异常或者出现的异常类型不正确,测试将失败。

5.3 结合夹具和参数化测试

我们可以将夹具和参数化测试结合起来,以创建更复杂的测试用例。例如,假设我们有一个夹具database_connection和一个参数化测试函数test_database_operation,我们可以这样结合它们:​​​​​​​

@pytest.mark.parametri
def test_database_operation(database_connection, a, b, expected):
    result = do_database_operation(database_connection, a, b)
    assert result == expected

在这个例子中,test_database_operation既使用了夹具database_connection,又使用了参数化测试的参数a、b和expected。通过这种方式,我们可以创建出更复杂的测试用例。

6. 测试文件和测试目录结构

在实际项目中,我们需要合理地安排测试文件和测试目录结构。一般来说,我们可以按照以下原则进行安排:

  • 对于一个 Python 项目,通常在项目根目录下创建一个tests目录。

  • 在tests目录下,可以根据项目的模块结构进一步细分测试目录。例如,如果项目有module1和module2两个模块,那么可以在tests目录下创建test_module1和test_module2两个子目录。

  • 在每个测试子目录中,放置与该子目录对应的模块的测试文件。例如,在test_module1目录中放置test_module1.py文件。

通过这种结构,我们可以更方便地组织和管理测试文件,并且在运行测试时,pytest也更容易找到所有的测试文件。

7. 常见问题解答

7.1 如何知道我的测试是否有效?

如果测试通过,在运行测试时你会看到一个.表示通过。如果测试失败,会显示详细的错误信息,你可以根据这些信息来判断测试是否有效以及找出问题所在。

7.2 如何处理测试中的数据?

你可以使用夹具来处理测试中的数据。夹具可以创建模拟数据,也可以获取真实数据。例如,你可以定义一个夹具来创建一个数据库连接,然后通过这个连接获取真实数据,或者定义一个夹具来创建模拟数据,如上面提到的database_connection和fake_data夹具。

7.3 如何筛选特定的测试用例?

你可以使用标记来筛选特定的测试用例。例如,你可以使用pytest -m slow命令来只运行被标记为slow的测试用例。你也可以使用@pytest.mark装饰器给测试用例加上其他标记,然后根据这些标记来筛选测试用例。

7.4 如何在测试中使用真实数据?

你可以使用夹具来获取真实数据。例如,你可以定义一个夹具来创建一个数据库连接,然后通过这个连接获取真实数据。在测试用例中使用这个夹具,就可以使用真实数据进行测试。

7.5 如何加快测试速度?

可以通过以下几种方式加快测试速度:

  • 减少不必要的测试用例。如果某些测试用例对项目质量影响不大,可以考虑删除它们。

  • 优化测试数据。如果测试数据过多或者过于复杂,可以考虑简化它。

  • 优化测试代码。如果测试代码存在冗余或者效率低下的问题,可以考虑优化它。

  • 并行测试。如果你的计算机有多个核心,可以考虑使用并行测试技术,如pytest-xdist插件,可以同时运行多个测试用例,提高测试效率。

8. 结论

pytest 是一个功能强大、简洁易用的 Python 测试框架。通过本指南,你应该对 pytest 有了一个基本的了解,包括它的安装、基本概念、如何编写复杂的测试用例以及如何组织测试文件和测试目录结构。在实际项目中,熟练掌握 pytest 将有助于提高代码质量和项目的可维护性。希望本指南对你有所帮助,让你在测试 Python 代码时更加得心应手。

最后: 下方这份完整的软件测试视频教程已经整理上传完成,需要的朋友们可以自行领取【保证100%免费】

软件测试面试文档

我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

在这里插入图片描述

在这里插入图片描述

您可能感兴趣的与本文相关的镜像

Python3.8

Python3.8

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值