wangbinyq / personal-wiki

2 stars 0 forks source link

pytest和单元测试 #2

Open wangbinyq opened 8 years ago

wangbinyq commented 8 years ago

pytest 查找规则:

如果不带参数运行pytest,那么查找从testpaths(如果有)或者当前目录开始查找,否者,命令行参数就用于目录、文件查找。

wangbinyq commented 8 years ago

pytest assert方法

通常情况下使用assert语句就能对大多数测试进行断言。 对于异常断言,使用pytest.raises或@pytest.mark.xfail。

对于自定义类型的assert比较断言,使用pytest_assertrepr_compare注册比较断言函数

wangbinyq commented 8 years ago

pytest fixtures

pytest fixtures提供传统xUnit单元测试中setUp/tearDown的功能,但是比setUp/tearDown更强大(pytest也支持xUnit单元测试)。

fixtures作为参数

# content of ./test_smtpsimple.py
import pytest

@pytest.fixture
def smtp():
    import smtplib
    return smtplib.SMTP("smtp.gmail.com")

def test_ehlo(smtp):
    response, msg = smtp.ehlo()
    assert response == 250
    assert 0 # for demo purposes

test_ehlo的参数smtp就是一个fixture,通过pytest.fixture装饰器定义。定义和使用fixtures的名字必须一样。这里smtp参数就是smtp fixture的返回值。

模块、类、会话级共享fixture

在pytest.fixture装饰器中添加参数scope能改变fixture的生存范围,如果scope='module',那么fixture就是模块级的,这个fixture函数只会在每次相同模块加载的时候执行。这样就可以复用一些需要时间进行创建的对象。

根据pytest的规则,会在conftest.py文件中查找fixture,这样我们就可以把所有的fixtures放到一个文件中。

Fixtures执行tearDown代码

 # content of conftest.py

import smtplib
import pytest

@pytest.fixture(scope="module")
def smtp(request):
    smtp = smtplib.SMTP("smtp.gmail.com")
    def fin():
        print ("teardown smtp")
        smtp.close()
    request.addfinalizer(fin)
    return smtp  # provide the fixture value

与测试互操作

# content of conftest.py
import pytest
import smtplib

@pytest.fixture(scope="module")
def smtp(request):
    server = getattr(request.module, "smtpserver", "smtp.gmail.com")
    smtp = smtplib.SMTP(server)

    def fin():
        print ("finalizing %s (%s)" % (smtp, server))
        smtp.close()
    request.addfinalizer(fin)
    return smtp

fixture有一个参数request,这个例子通过request取得了模块中的smtpserver变量,还可以通过request取得function, class or module context

参数化fixtures

request不仅能获取测试中的量,还可以为通过request参数话fixtures

# content of conftest.py
import pytest
import smtplib

@pytest.fixture(scope="module",
                params=["smtp.gmail.com", "mail.python.org"])
def smtp(request):
    smtp = smtplib.SMTP(request.param)
    def fin():
        print ("finalizing %s" % smtp)
        smtp.close()
    request.addfinalizer(fin)
    return smtp

本例会创建两个smtp fixtures,它们的不同处在于request.param。每个使用smtp fixture的测试函数都会执行两次,对应不同的param。

通过fixtures对测试进行分组

Autouse fixtures (xUnit setup on steroids)

wangbinyq commented 8 years ago

参数化fixtures和测试函数

pytest支持fixtures和测试函数的参数化

wangbinyq commented 8 years ago

Example

wangbinyq commented 8 years ago

Mock

Mocking in Python: A Guide to Better Unit Tests Mock docs