python - 运行特定的 Django 测试(使用 django-nose?)

标签 python django unit-testing nose

我有一个非常复杂的 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-m选项,它应该能够根据正则表达式选择测试,这是我的问题的理想解决方案。

不幸的是,这里是使用 django-nose 作为 django 测试运行器时发生的事情:

  • ./manage.py test myapp没有自动找到 type -生成测试类(与 django 测试运行器相反)
  • 都不是./manage.py test -m ".*" myapp也不./manage.py test myapp -m ".*"找到任何测试,即使正常TestCase类存在于文件中

所以:

  • 除了尝试使用 django-nose -m 之外,您还有其他解决我的一般问题的方法吗? ?
  • django-nose ,你知道如何制作-m吗?工作?

麦克韦

将以下内容添加到一个空的 myapp/tests.py文件:

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)

如果通过 django 测试运行器运行此输出(按 alphab 顺序):
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 结尾的测试方法(或其他某种正则表达式过滤)

最佳答案

您遇到的问题是 Nose 通过查看记录在函数本身上的 name 来确定是否将方法包含到要运行的测试集中,而不是访问函数的属性。如果我将您的 passerfailer 重命名为 test_passtest_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

如果没有对 None 的最后两个赋值,Nose 会将这两个顶级函数视为模块级测试,并将在之外运行它们到类。

获得相同结果的另一种方法是在您的两个函数上定义 __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

Nose 在函数中寻找这些函数的存在,如果存在并设置为一个值被认为是真实的,它将将该函数作为测试用例。

控制方法选择的逻辑可以在 Nose 的 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 平等地匹配文件、目录、模块、类和函数名称。如果您设置类似 -m0$ 的内容,那么所有 我刚刚列出的各个部分必须与要选择的测试的正则表达式相匹配。 (Nose 不会将它们组合起来,然后在组合上进行匹配。)可以在命令行上单独列出测试,但这是正则表达式匹配的糟糕替代品。

关于python - 运行特定的 Django 测试(使用 django-nose?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29776211/

相关文章:

json - 如何更改为字符串并从 Django 模板/上下文中删除 '?

python - 将 Django 模型对象转换为 dict 并且所有字段都完好无损

javascript - 我如何使用 Jasmine 通过 id 检查元素是否存在?

unit-testing - 集成测试/单元测试 : Doing too many integration tests?

python - Python中nan和 'nan'的区别

python - 据说部署 django 的最佳方式是使用 wsgi,我想知道为什么?

python - Pandas :时间戳系列中的唯一天数

c++ - 在单独的 cpp 文件中 boost 单元测试

python - 我可以通过更改算法来增加随机性吗?

python - 如何修补 python 方法以运行测试用例?