让我说我在conftest.py文件中建立了一个pytest fixture,看起来像:
def live_fixture():
# network access here...
pass
我在许多测试函数中使用相同的fixture,比如test_spam.py有一些测试函数:
@pytest.mark.live
def test_one(live_fixture):
assert 1
def test_one():
assert 2
@pytest.mark.live
def test_three(live_fixture):
assert 3
我在第一个和第三个测试函数上使用@pytest.mark.live
装饰,因为这两个测试都依赖于夹具live_fixture
,它通过网络传出并完成任务。理由:我喜欢让我的测试的可靠子集离线传递,例如。
py.test -m "not live" test_spam.py --blockage
将可靠地传递(使用漂亮的pytest-blockage模块来强制执行无网络访问限制。)
但是在这里使用@pytest.mark.live
的每个测试函数上写出live_fixture
装饰是单调乏味且容易出错的。有没有办法让该夹具声明任何使用它的测试函数都应该自动应用@pytest.mark.live
修饰,或者某种方式来检测内部文件test_spam.py test_one
和{{1}使用test_three
,因此应该有效地装饰live_fixture
?
答案 0 :(得分:2)
我找到了另一个合理的解决方案,试图弄清楚pytest.mark是如何工作的。
我发现类Node有一个方法“add_marker”,它应该是实现功能pytest.mark的确切方法。并且类Item从Node扩展。
所以我的解决方案是:
示例:在conftest.py中添加以下方法
#validations
validates_uniqueness_of :bmp_id, :message => "TODO", if: :pad_and_pipes_exists
def pad_and_pipes_exists
if bmpsublist_id == 4 || bmpsublist_id == 5 || bmpsublist_id == 6 || bmpsublist_id == 7
sublist_ids = Array.wrap([4, 5, 6, 7])
pads_exists = false
sublist_ids.each do |sublist_id|
if Bmp.find_by_bmpsublist_id(sublist_ids) != nil
pads_exists = true
end #end if statement
end #end each statment
end #end first if statement
return pads_exists
end #end function
我希望至少我的回答能激发某人想出一个更体面的方式。
答案 1 :(得分:0)
好吧,我愚弄了这一点,并得到了一些非常粗糙的工作。我定义了这样一个函数:
import sys, inspect, pytest
def mark_live_fixtures(module_name):
testfunctions = [obj for name,obj
in inspect.getmembers(sys.modules[module_name])
if (inspect.isfunction(obj) and
name.startswith('test') and name != 'testall')]
for func in testfunctions:
if 'live_fixture' in inspect.getargspec(func).args:
func = pytest.mark.live(func)
然后我可以在测试文件的底部粘贴mark_live_fixtures(__name__)
,并且似乎使用{{pytest.mark.live
装饰将live_fixture
装饰应用于该模块中的所有测试函数1}}。但这种方法至少存在两个问题:
@mock.patch
或其他常见的测试修饰将不具有可用于inspect.getargspec的正确参数内省(这是decorator模块存在的原因),因此它们不会被装饰为预期。这当然有点难看,也许有人有更清洁的解决方案?