我正在编写一个插件,将单独处理我的单元测试,功能测试和整合测试不同。
我的tests文件夹将具有以下结构:
/测试
- / unit
- /功能
- / integration
每个单元测试将驻留在单元目录中,每个功能测试将驻留在功能目录中,依此类推。
我熟悉Layers插件,但我宁愿按照惯例进行测试 在测试运行之前,我应该使用哪个钩子来注入适当的层? 它应该是loadTestsFromModule钩子吗?你能告诉我一个例子吗?
我还希望将每种测试的摘要报告分开 我应该使用哪个钩子?
答案 0 :(得分:1)
您无需编写插件,the built-in attr module就是为此目的而设计的。但是,它不依赖于您的文件层次结构。相反,您将单个测试标记为单元,功能或集成。这看起来像是:
from nose.plugins import attrib
@attrib.attr("functional")
class FunctionalTestCase(unittest.TestCase):
pass
要仅运行功能测试,您可以执行以下操作:
nosetests -a functional
如果我正在创建这个测试布局,我可能会有3个unittest.TestCase子类,已标记为“unit”,“functional”和“integration”。新测试可以轻松地继承正确的测试类型。
答案 1 :(得分:1)
我通过使用nose2 attrib
插件进行发现以及从nose1 attrib
插件复制的一些代码使我能够装饰我的测试,从而使用了nose2。
attrib
插件您将看到the nose2 attrib
plugin允许在测试函数和类上定义自定义属性。
为此,您必须在定义测试函数后指定测试的属性。
class MyTestCase(unittest.TestCase):
def test_function(self):
self.assertEqual(1+1, 2)
test_function.custom_attr1 = True
test_function.custom_attr2 = ['foo', 'bar']
然后,您可以通过将-A
或--attribute
指定为nose2
命令行参数来运行一组筛选的测试,以列出要与测试套件匹配的属性。您甚至可以使用-E
或--eval-attribute
expression command-line argument,它允许更复杂的Python表达式来匹配测试属性。
e.g。 nose2 -v -A custom_attr1
将运行所有使用 truthy 值指定custom_attr1
的测试。
这对我来说还不够好,因为我不喜欢在定义后在测试中定义这些属性的想法。我想使用装饰器,但nose2
没有内置装饰器来执行此操作。
我转到了nose1 source code for its attrib
plugin并复制了attr
函数的来源。
def attr(*args, **kwargs):
"""Decorator that adds attributes to classes or functions
for use with the Attribute (-a) plugin.
"""
def wrap_ob(ob):
for name in args:
setattr(ob, name, True)
for name, value in kwargs.iteritems():
setattr(ob, name, value)
return ob
return wrap_ob
我把它放到test/attrib_util.py
文件中。现在我可以使用装饰器指定属性。我上面的原始测试类代码可以转换为(IMO)更简单:
from test.attrib_util import attr
class MyTestCase(unittest.TestCase):
@attr('custom_attr1', custom_attr2=['foo', 'bar'])
def test_function(self):
self.assertEqual(1+1, 2)
您会注意到属性可以指定为args或kwargs;所有参数都将获得默认值True
。
您甚至可以在测试类或基类上使用此attr
装饰器,并且属性将应用于其中定义的所有测试函数。这样可以非常方便地分离单元和功能测试。
from test.attrib_util import attr
@attr('functional')
class FunctionalTestCase(unittest.TestCase):
pass
class MyFunctionalCase(FunctionalTestCase):
def test_function(self):
print 'this will be considered a "functional" test function'
答案 2 :(得分:0)
如果您已经将测试分类到目录中(如您所述),您可以编写一个使用wantDirectory方法的插件。
import os.path
from nose.plugins import Plugin
class TestCategory(Plugin):
"""
Run tests in a defined category (unittest, functional, integration. Always
runs uncategorized tests.
"""
def wantDirectory(self, dirname):
dirname = os.path.basename(dirname)
if (dirname in ('unit', 'functional', 'integration') and
dirname != self.category):
return False
return None
您需要为此插件编写options()
和configure()
方法,以处理启用和禁用它以及收集用户的类别选择。运行nosetests时,您可以从以下三个类别中进行选择:
nosetests --category functional
由于一次只运行一个测试类别,因此您将获得每个测试类别的单独报告。当然,您可以通过不启用此插件来运行所有测试。
(作为一个不同的答案添加,因为它是一种完全不同的方法)。