我有一个非常复杂的tests.py
文件。
实际上,测试类和方法是在运行时生成w / type
(以考虑辅助文件中列出的数据)。我正在以下列方式做事(请参阅下面的更多代码):
klass = type(name, (TestCase,), attrs)
setattr(current_module, name, klass)
仅供参考,使用通常的django测试运行器,所有这些测试都会在执行./manage.py test myapp
时运行(感谢上面显示的setattr
)。
我想要做的只是运行部分测试,而不是手动列出他们的名字。
例如,我可以在类名或方法名中给每个测试“标签”,以便我可以对它们进行过滤。例如,我将执行:运行所有测试哪个方法名称包含字符串“test_postgres_backend _”
我尝试使用django-nose
因为nose
的{{1}}选项,它应该能够根据正则表达式选择测试,这是解决我问题的理想方法。
不幸的是,以下是使用django-nose作为django测试运行时发生的事情:
-m
没有自动查找./manage.py test myapp
生成的测试类(与django测试运行器相反)type
和./manage.py test -m ".*" myapp
都找不到任何测试,即使文件中存在普通./manage.py test myapp -m ".*"
类 所以:
TestCase
?-m
,您知道如何使django-nose
正常工作吗?将以下内容添加到空的-m
文件中:
myapp/tests.py
如果通过django test runnner运行此输出的运行(按字母顺序排列):
from django.test import TestCase
from sys import modules
current_module = modules[__name__]
def passer(self, *args, **kw):
self.assertEqual(1, 1)
def failer(self, *args, **kw):
self.assertEqual(1, 2)
# Create a hundred ...
for i in xrange(100):
# ... of a stupid TestCase class that has 1 method that passes if `i` is
# even and fails if `i` is odd
klass_name = "Test_%s" % i
if i % 2: # Test passes if even
klass_attrs = {
'test_something_%s' % i: passer
}
else: # Fail if odd
klass_attrs = {
'test_something_%s' % i: failer
}
klass = type(klass_name, (TestCase,), klass_attrs)
# Set the class as "child" of the current module so that django test runner
# finds it
setattr(current_module, klass_name, klass)
如果您更改为F.F.F.F.F.F.FF.F.F.F.F..F.F.F.F.F.FF.F.F.F.F..F.F.F.F.F.FF.F.F.F.F..F.F.F.F.F.FF.F.F.F.F..F.F.F.F.F..
测试跑步者,django_nose
上没有任何操作。
修复此问题后,我希望只能运行名称以./manage.py test myapp
结尾的测试方法(或其他类型的可重用过滤)
答案 0 :(得分:5)
您遇到的问题是Nose通过查看函数本身记录的名称来确定是否将方法包含到要运行的测试集中,而不是通过该属性来访问该函数。如果我将您的passer
和failer
重命名为test_pass
和test_fail
,则Nose可以找到测试。因此,函数本身必须以与-m
(或其默认值)给出的方式匹配。
以下是提供预期结果的修改后的代码:
from django.test import TestCase
from sys import modules
current_module = modules[__name__]
def test_pass(self, *args, **kw):
self.assertEqual(1, 1)
def test_fail(self, *args, **kw):
self.assertEqual(1, 2)
# Create a hundred ...
for i in xrange(100):
# ... of a stupid TestCase class that has 1 method that passes if `i` is
# even and fails if `i` is odd
klass_name = "Test_%s" % i
if i % 2: # Test passes if even
klass_attrs = {
'test_something_%s' % i: test_pass
}
else: # Fail if odd
klass_attrs = {
'test_something_%s' % i: test_fail
}
klass = type(klass_name, (TestCase,), klass_attrs)
# Set the class as "child" of the current module so that django test runner
# finds it
setattr(current_module, klass_name, klass)
# This prevents Nose from seeing them as tests after the loop is over.
test_pass = None
test_fail = None
如果没有 获得相同结果的另一种方法是在两个函数上定义 在文件的末尾: Nose在函数中查找这些函数的存在,如果存在并设置为某个值被认为是真的,则将该函数作为测试用例。 管理选择方法的逻辑可以在Nose的 我没有看到使用None
的最后两个赋值,Nose会将两个顶级函数视为模块级测试,并将另外运行到类中的测试中。< / p>
__test__
:def passer(self, *args, **kw):
self.assertEqual(1, 1)
passer.__test__ = 1
def failer(self, *args, **kw):
self.assertEqual(1, 2)
failer.__test__ = 1
# This prevents Nose from seeing them as tests after the loop is over.
passer = None
failer = None
selector.py
文件中找到wantMethod
method:def wantMethod(self, method):
"""Is the method a test method?
"""
try:
method_name = method.__name__
except AttributeError:
# not a method
return False
if method_name.startswith('_'):
# never collect 'private' methods
return False
declared = getattr(method, '__test__', None)
if declared is not None:
wanted = declared
else:
wanted = self.matches(method_name)
plug_wants = self.plugins.wantMethod(method)
if plug_wants is not None:
wanted = plug_wants
log.debug("wantMethod %s? %s", method, wanted)
return wanted
-m
以您希望的方式运行某些测试的明确方法。问题是-m
平等地匹配文件,directorie,模块,类和函数名称。如果您设置类似-m0$
然后 all 的内容,我刚刚列出的各个部分必须与要选择的测试的正则表达式匹配。 (Nose不会将它们组合在一起然后在组合上匹配。)可以在命令行上单独列出测试,但这不能替代正则表达式匹配。
答案 1 :(得分:2)
通常,您可以使用以下内容运行特定测试:
# assuming your tests are in core/tests.py
python manage.py test core.tests:CoreTestCase.my_specific_test
你尝试过这种方法吗?