本文将介绍针对测试和生产等不同测试环境下,维护一套可读性,追溯性强的测试用例的工具-pytest。
打开pytest.org, 第一句话就是 pytest: helps you write better programs 。 诚然,没有测试保障的程序不是好程序。在DevOps 思想流行的现进,需要有一套用于特性/bug fix 回归的测试框架和用例,能够直接被DevOps系统调用。
pytest.org有足够的的pytest的介绍,本文只会介绍如何利用pytest提供的特性支持多环境测试。
以下几个特性会在您日后的开发(测试)中遇到。
pytest 提供了一组内置的标签,包括
这组标签可以直接用来修饰需要被执行的用例,使得这些用例允许在某些特定的环境下执行,标记用例的超时时间等,但另一个有用的使用方式是定义自己的marker,marker 定义在 pytest.ini 文件中。
# cat pytest.ini
[pytest]
log_cli = true
log_level = DEBUG
addopts = -p no:warnings
log_format = %(asctime)s %(levelname)s %(message)s
log_date_format = %Y-%m-%d %H:%M:%S
# custom markers
markers =
p0test: p0 test cases: should be able run on all env
p1test: p1 test cases: not used
p2test: p2 only run in product env
使用 pytest --markers 可以得到当前支持的可以使用的marker。 可以方便地测试用例(方法或者类)上使用pytest 的修饰器来修改用例的执行行为:
比如如下测试类,只有变量QC_API_DEFAULT_ZONEID 的取值为100002的时候才执行。而用例test_foo 只有传递了p1test marker 的时候才执行。
import unittest
@pytest.mark.skipif(QC_API_DEFAULT_ZONEID != 100002, reason="only support 100002"
class TestDescribeInstances(unittest.TestCase):
@pytest.mark.p1test
def test_foo(self):
assert True
def test_bar(self):
assert False
以上用例可以用以下pytest 命令执行:
pytest -v -rap -m p1test
可以通过传递环境变量,并在python代码中读取环境变量来控制这些测试用例的执行行为:
RUN_ENV=test pytest -v -rap -m p1test
某些情况下,我们的测试用例需要在一个特定的场景下执行,执行完用例之后,需要把场景还原。
这时候,我们可以定义一个测试类,在这个测试类中定义 setup_class 和 tear_down 静态方法。这样就能够满足我们需要的场景,保证整个测试结束后,环境恢复原装
class ExampleTest(unittest.TestCase):
@staticmethod
def setup_class(cls):
cls.foo = 1
LOG.info("setup")
@staticmethod
def teardown_class(cls):
LOG.info("teardown")
简单地说,当我们的测试用例需要一些“假”的数据的时候(或者测试需要具备某些前提条件),使用fixture。
@pytest.fixture(autouse=True, scope='class')
def class_client(request):
# inject class variables
# Notes (eliqiao): when you use it in your test function
# do not reassign this, you can update it
# so that we can share it in a class scope
request.cls.inst = {}
yield
@pytest.mark.usefixtures('class_client')
class ExampleTest(unittest.TestCase):
@staticmethod
def setup_class(cls):
cls.foo = 1
LOG.info("setup")
@staticmethod
def teardown_class(cls):
LOG.info("teardown")
在上面的例子中,定义了一个应用在类上的fixture , 这个fixture 在这个类中的每个方法被调用之前,都会被执行,从此改变测试类的一些参数/行为。
当然,关于fixture 还有更高级的用法,如何你的测试用例需要提前准备一些数据,那么它是一个很好的选择。
通过安装 pytest-xdist (distributed testing plugin) 插件,我们可以让测试用例“并行”(在某些配置下也可以说并发)地执行测试用例,当然,是在你的系统有多个CPU或者有多个HOST可以使用的情况下。
两个关键的参数分别是:
pytest -v -n ${WORKERS} --dist=loadfile -m $TESTFLAG --log-file ./pytest.log
tox 是另一个能帮助我们更好地完成测试的工具。 使用 tox,能够保证测试环境的稳定性,它提供了python 的 virtualenv 环境,允许我们显式地指定我们的测试环境中需要安装哪些依赖包,从而能保证测试结果的一致性。
[testenv:py36-test]
setenv =
LANG = en_US.utf8
RUN_ENV = test
passenv = https_proxy QC_* QCI_*
basepython = python3.6
install_command = pip install -r requirements_dev.txt {opts} {packages}
commands = pytest {posargs:tests}
以上是一个 tox.ini 文件的片段,它定义了一个执行测试的环境,执行tox 命令,它会在执行测试之前先帮我们创建一个python的 virtualenv 的环境,在该环境中安装 requirements_dev.txt 中指定的 python 软件包(特定版本),同时传递一些环境变量到执行环境中,这些环境变量可以被 pytest 读取,然后用做 pytest 在执行marker 检查时的条件。
以上,我们可以通过 tox 帮我们创建不同的测试环境,通过传递的环境变量,pytest 会选择在某些环境下运行那些测试用例。 同时这些测试用例可以并发地执行,然后输出漂亮的报告。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。