我之前听过很多次这个术语(谈论编程时),但是找不到任何解释是什么意思.有什么好的文章或解释吗?我没有找到任何值得一提的东西.
我正在使用py.test来测试包含在python类MyTester中的一些DLL代码.为了验证目的,我需要在测试期间记录一些测试数据,然后再进行更多处理.由于我有很多测试_...文件,我想在大多数测试中重用测试器对象创建(MyTester实例).
由于测试对象是获得对DLL的变量和函数的引用的对象,我需要将DLL的变量列表传递给每个测试文件的测试对象(要记录的变量对于test_ .. .文件).列表的内容应用于记录指定的数据.
我的想法是以某种方式这样做:
import pytest
class MyTester():
def __init__(self, arg = ["var0", "var1"]):
self.arg = arg
# self.use_arg_to_init_logging_part()
def dothis(self):
print "this"
def dothat(self):
print "that"
# located in conftest.py (because other test will reuse it)
@pytest.fixture()
def tester(request):
""" create tester object """
# how to use the list below for arg?
_tester = MyTester()
return _tester
# located in test_...py
# @pytest.mark.usefixtures("tester")
class TestIt():
# def __init__(self):
# self.args_for_tester = ["var1", "var2"]
# # how to …Run Code Online (Sandbox Code Playgroud) 考虑以下Pytest:
import pytest
class TimeLine(object):
instances = [0, 1, 2]
@pytest.fixture
def timeline():
return TimeLine()
def test_timeline(timeline):
for instance in timeline.instances:
assert instance % 2 == 0
if __name__ == "__main__":
pytest.main([__file__])
Run Code Online (Sandbox Code Playgroud)
该测试test_timeline使用Pytest fixture timeline,它本身具有该属性instances.此属性在测试中迭代,因此只有断言适用于每个输入时instance,测试才会通过timeline.instances.
然而,我真正想要做的是生成3个测试,其中2个应该通过,其中1个将失败.我试过了
@pytest.mark.parametrize("instance", timeline.instances)
def test_timeline(timeline):
assert instance % 2 == 0
Run Code Online (Sandbox Code Playgroud)
但这会导致
AttributeError: 'function' object has no attribute 'instances'
Run Code Online (Sandbox Code Playgroud)
据我了解,在Pytest灯具中,函数"变为"它的返回值,但在测试参数化时,这似乎还没有发生.如何以理想的方式设置测试?
我想使用fixtures作为pytest.mark.parametrize的参数或具有相同结果的东西.
例如:
import pytest
import my_package
@pytest.fixture
def dir1_fixture():
return '/dir1'
@pytest.fixture
def dir2_fixture():
return '/dir2'
@pytest.parametrize('dirname, expected', [(dir1_fixture, 'expected1'), (dir2_fixture, 'expected2')]
def test_directory_command(dirname, expected):
result = my_package.directory_command(dirname)
assert result == expected
Run Code Online (Sandbox Code Playgroud)
夹具参数的问题在于夹具的每个参数都会在每次使用时运行,但我不希望这样.我希望能够根据测试选择使用哪种灯具.
没有拆卸代码的(默认)功能范围夹具有什么优势?为什么不在测试开始时调用函数?
例如,写作的好处是什么:
@pytest.fixture
def smtp():
return smtplib.SMTP("smtp.gmail.com")
def test_ehlo(smtp):
response, msg = smtp.ehlo()
# ...
Run Code Online (Sandbox Code Playgroud)
而不是简单地:
def create_smtp():
return smtplib.SMTP("smtp.gmail.com")
def test_ehlo():
smtp = create_smtp()
response, msg = smtp.ehlo()
# ...
Run Code Online (Sandbox Code Playgroud)
我理解为什么在我们需要拆卸代码时固定装置很有用.我也理解为什么具有除函数之外的范围的灯具是有用的:我们可能希望在多个测试中重复使用相同的"外部"对象(以节省创建它所需的时间;或者甚至可能保持其状态 - 尽管看起来似乎相当危险,因为这会在单独的测试之间产生难以看见的耦合).
我有一个夹具返回某种类型的对象,我在另一个文件中定义了另一个夹具,它基本上使用该对象来做其他事情。但是我无法从我的第一个装置中返回对象。
file-1
def fixture_1(s, **kwargs):
def hook(s, **kwargs):
p_b = s.get()
p = p_b.build()
yield p
return hook
Run Code Online (Sandbox Code Playgroud)
file-2 conftest.py
@pytest.fixture(scope='module')
def fixture_1(s, **kwargs):
def hook(s, **kwargs):
#Default implementation is no-op.
pass
return hook
@pytest.fixture(scope='module')
def fixture_2(s,b_p):
some_p = fixture_1(s)
current_status = s.start(some_p)
print(current_status)
yield current_status
Run Code Online (Sandbox Code Playgroud)
我想基本上检索p返回的对象file-1 fixture_1并在file-2 fixture_2夹具中使用它。