Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pytest和单元测试 #2

Open
wangbinyq opened this issue Feb 19, 2016 · 6 comments
Open

pytest和单元测试 #2

wangbinyq opened this issue Feb 19, 2016 · 6 comments
Labels

Comments

@wangbinyq
Copy link
Owner

No description provided.

@wangbinyq wangbinyq mentioned this issue Feb 19, 2016
@wangbinyq wangbinyq added draft and removed draft labels Feb 19, 2016
@wangbinyq
Copy link
Owner Author

pytest 查找规则:

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

  • 递归遍历目录,除非目录指定了不同递归
  • 文件名符合test__.py,__test.py
  • Test开头的类,并且不能有init方法
  • 对test_开头的函数和方法进行测试

@wangbinyq
Copy link
Owner Author

pytest assert方法

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

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

@wangbinyq
Copy link
Owner Author

pytest fixtures

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

  • fixtures有名字,可以在测试函数、模块、类或整个工程中明确通过fixtures的名字调用fixtures
  • fixtures以模块的方式实现,每个fixtures函数可以调用其他的fixtures
  • fixtures可以通过参数或者配置进行复用

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
Copy link
Owner Author

参数化fixtures和测试函数

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

  • fixtures通过pytest.fixture 的 params参数,这个fixture也可以参数化测试函数(只要fixture直接返回request.param)
  • 测试函数通过@pytest.mark.parametrize装饰器参数化
  • pytest_generate_tests

@wangbinyq
Copy link
Owner Author

Example

@wangbinyq wangbinyq changed the title pytest pytest和单元测试 Feb 22, 2016
@wangbinyq
Copy link
Owner Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant