单元测试和验证

Skip to content

这是一段机器翻译的文本,可能包含错误!

现在我们已经创建了类并处理了验证,我们为开始测试奠定了良好的基础。测试是开发过程的重要组成部分,它可以帮助我们确保我们的代码按预期工作。

毕竟,如果我们不测试代码,如何才能确保它正常工作呢?

什么是单元测试?

单元测试是一种自动且系统地测试我们代码的小部分的方法。在 Python 中,我们使用一个名为 pytest 的模块来编写和运行测试。一个“单元”是应用程序中最小的可测试部分,通常是一个单独的函数或方法。在使用 pytest 时,重要的是我们要遵循正确的命名约定,以便 pytest 能够找到我们的测试,例如将测试文件命名为 test_ 开头,将测试函数命名为 test_ 开头。

单元测试示例:

def test_add():
    # 确认 0.3 + 0.3 + 0.3 等于 0.9
    assert 0.3 + 0.3 + 0.3 == 0.9

通过在终端中输入 pytest 来运行。

Fun fact

上述代码会失败,因为在 Python 中,0.3 + 0.3 + 0.3 会变成 0.8999999999!

Easy 任务 1 - 安装 pytest

在你的虚拟环境中安装 pytest。通过在终端中运行以下命令来执行此操作:

pip install pytest
# 安装 pytest 软件包

Easy 任务 2 - 创建一个测试

在你的项目文件夹中创建一个名为 test_data.py 的新文件。 在此文件中,你应该为你在上一模块中创建的 Person 类创建一个测试。 该测试应该检查是否可以使用有效值创建 Person

测试示例:

from main import Person

def test_person_working():
    bob_kaare = Person(name="Bob Kåre",
                       eye_color=EyeColor.BLUE,
                       phone_number=PhoneNumber("12345678"),
                       email=Email("bob_kaare@example.com"))
    # 确认姓名是否正确
    assert bob_kaare.name == "Bob Kåre"
    # 确认眼睛颜色是否正确
    assert bob_kaare.eye_color == EyeColor.BLUE

这种类型的测试被称为“快乐路径”测试,因为我们测试当提供有效值时,一切是否都能正常工作,而且它用处不大。

Medium 任务 3 - 测试验证

test_person.py 中创建更多测试,以检查 EmailPhoneNumber 中的验证是否按预期工作。测试有效和无效值。您需要使用 pytest 中的一个名为 raises 的函数,该函数检查是否引发了特定错误。

import pytest

def test_exception():
    with pytest.raises(KeyError):
        my_dict = {"a": 1, "b": 2}
        value = my_dict["c"]  # 这将“引发”一个 KeyError

Tip

只要函数名称以 test_ 开头,你就可以创建任意数量的函数。

Løsning: Eksempel på en test for ugyldig e-post
from main import Email

import pytest

def test_invalid_email():
    with pytest.raises(ValueError):
        email = Email("not-an-email")

为什么要做这件事?

通过为我们的代码编写良好的测试,我们可以确保它按预期工作,并且如果我们在代码中进行更改,我们可以轻松地找出哪里出了问题。 这在大型项目中尤其重要,因为许多开发人员一起工作,并且很容易出错。

例如,通过使用 Jest 或 Selenium 等软件,我们可以自动测试网站,从而确保每次代码更改后一切都按预期工作。 我们当然想知道“用户注册”、“支付”和“登录”是否正常工作,不是吗?

考虑以下场景

发生什么(或应该发生什么)如果…:

  • 一位用户试图使用已被注册的电子邮件地址进行注册?
  • 一位用户的出生日期在未来?
  • 一位用户输入姓名“jOHN dOE”?

A software tester walks into a bar...

Hard 任务 4 - 自动测试 (CI)

当我们把代码发布到 GitHub 上时,我们可以设置一些叫做 GitHub Actions 的东西,它可以自动运行我们的测试,每次我们对代码进行更改时。 这被称为持续集成 (CI),它可以帮助我们确保我们的代码始终按预期工作。

在你的项目文件夹中创建一个名为 .github/workflows/pytest.yml 的文件。 在此文件中,你应该添加以下代码:

name: Pytest

on: [push]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4
    - name: Set up Python
      uses: actions/setup-python@v5
      with:
        python-version: '3.11'
    - name: Install dependencies
      run: |

        python -m pip install --upgrade pip
        pip install pytest
        # 安装项目所需的任何其他依赖项
        pip install -r requirements.txt
    - name: Run tests with pytest
      run: pytest

如果已正确配置,您现在应该会在您的 GitHub 仓库中看到一个名为“Actions”的新选项卡。 在这里,您可以查看您的测试是否会在每次更改代码时自动运行,并且如果任何测试失败(红色叉号和通过电子邮件)您将收到通知。

Merknad om filstruktur

您的文件结构将决定 GitHub Actions 是否有效。 确保 .github 文件夹位于您项目的根目录中,并且您的测试文件所在的 tests 文件夹也位于根目录中。

您可以选择修改 pytest.yml 文件以指向正确的文件夹。

这样的 Actions 文件也可以用于在多个 Python 版本或操作系统上测试你的代码,它们还可以用于自动构建和发布你的软件,例如发布一个网站,或者更新 App Store 或 Google Play 中的应用。

Code Coverage

也有“代码覆盖率”这一概念,它可以帮助你查看有多少代码被实际测试。 这对于确定你是否拥有足够的测试,或者你的代码中是否有根本没有被测试的部分,可能很有用。

一些工作场所要求你在部署代码之前,必须有一定比例的代码被测试覆盖,以确保代码的健壮性和功能的正常运行。

Unit Test Meme