2. 测试框架选型:Python单元测试框架对比
做自动化测试,选框架是第一步。
说实话,这一步很多人会纠结。Python里最主流的两个单元测试框架,就是unittest和pytest。我当年刚入行时也纠结过,后来踩了不少坑,才慢慢摸清楚它们的脾气。
2.1 unittest vs pytest:一场老将与新秀的较量
先说说unittest。它是Python标准库自带的,不用额外安装。这一点很友好。但用起来嘛……我个人觉得有点啰嗦。
你看,unittest要求你写测试类,还要继承TestCase,方法名必须以test开头。断言也得用self.assertEqual这种写法。代码量不小。
而pytest呢?它更自由。函数名带test就行,断言直接用Python原生的assert。简洁太多了。
我举个例子你就明白了:
# unittest 写法
import unittest
class TestMath(unittest.TestCase):
def test_add(self):
self.assertEqual(1 + 1, 2)
# pytest 写法
def test_add():
assert 1 + 1 == 2
看到了吧?pytest的代码量少了一半。我在项目中带新人时,用pytest他们上手更快,基本看一遍就会写了。
下面这张表,是我总结的核心区别:
| 对比项 | unittest | pytest |
|---|---|---|
| 安装方式 | 内置,无需安装 | 需 pip install pytest |
| 用例编写 | 必须写类,继承TestCase | 函数即可,无需类 |
| 断言方式 | self.assertEqual() 等 | 原生 assert |
| fixture机制 | setUp/tearDown,较笨重 | @pytest.fixture,灵活强大 |
| 参数化 | 需用subTest,较麻烦 | @pytest.mark.parametrize,一行搞定 |
| 插件生态 | 几乎没有 | 非常丰富(allure、xdist等) |
| 报告输出 | 默认文本,较简陋 | 可生成HTML、Allure等精美报告 |
我的建议:新项目直接用pytest。除非你是在维护老项目,或者公司强制要求用unittest,否则别犹豫。
2.2 pytest核心优势:为什么我选它?
pytest的优势,说白了就三个字:省事儿。
第一,fixture机制太香了。
unittest里的setUp和tearDown,每个测试类都得写一遍。而且作用域是类级别的,想跨类复用?得自己想办法。
pytest的fixture就不一样了。你可以定义在conftest.py里,全局共享。还能控制作用域:function、class、module、session。想怎么用就怎么用。
我在项目中遇到过这样一个场景:多个测试模块都需要登录操作。用unittest的话,每个类里都得写一遍登录逻辑。用pytest,我只需要在conftest.py里定义一个fixture,所有测试文件都能直接引用。省了多少重复代码啊。
# conftest.py
import pytest
@pytest.fixture(scope="session")
def login_session():
# 登录操作,只执行一次
token = do_login("admin", "123456")
return token
# test_case.py
def test_get_user_info(login_session):
# 直接使用login_session
response = get_user_info(login_session)
assert response.status_code == 200
第二,参数化测试,一行代码搞定。
测试中经常需要测多组数据。unittest的做法是写多个测试方法,或者用subTest。代码又长又丑。
pytest的parametrize装饰器,一行就能搞定多组数据测试。而且失败时能清楚看到是哪组数据出了问题。
import pytest
@pytest.mark.parametrize("input_val, expected", [
(1, 2),
(2, 4),
(3, 6),
(0, 0),
(-1, -2),
])
def test_double(input_val, expected):
assert double(input_val) == expected
第三,插件生态丰富。
pytest有几百个插件。我最常用的几个:
- pytest-xdist:并行执行测试,速度翻倍
- pytest-html:生成漂亮的HTML报告
- pytest-allure-adaptor:集成Allure报告,适合大项目
- pytest-cov:统计代码覆盖率
- pytest-rerunfailures:失败用例自动重跑
嗯,这里要注意:插件虽好,但别装太多。装多了启动会变慢,反而影响效率。
2.3 环境搭建:5分钟搞定
环境搭建其实很简单。我一般用虚拟环境,避免污染全局Python。
第一步:创建虚拟环境
python -m venv venv
source venv/bin/activate # Linux/Mac
venv\Scripts\activate # Windows
第二步:安装pytest
pip install pytest
第三步:安装常用插件
pip install pytest-html pytest-xdist pytest-cov
第四步:验证安装
pytest --version
看到版本号就说明装好了。
小技巧:你可以把依赖写进requirements.txt,下次直接pip install -r requirements.txt一键安装。
避坑指南:我曾经在Windows上遇到过编码问题。pytest默认用UTF-8,但Windows控制台可能是GBK。如果测试文件里有中文,可能会报错。解决方案是在pytest.ini里加上:
[pytest]
testpaths = tests
python_files = test_*.py
python_functions = test_*
或者在conftest.py里设置编码:
import sys
import io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
好了,环境搭好了,框架也选好了。下一章我们开始写第一个测试用例。你想想看,从零到一其实就这么简单。