Nose: 测试指定包中的所有模块

4 投票
3 回答
3545 浏览
提问于 2025-04-17 02:03

我有一个包含多个子包的包,其中一个子包是用来测试的,叫做 tests。因为这个子包的名字已经很清楚地表明里面的模块是测试模块,所以我不想让模块的名字被测试相关的命名规则搞得乱七八糟,这些规则是 nose 需要用来找测试的。我想要的设置是这样的:

- foo
  - __init__.py
  ...
  - bar
    - __init__.py
    ...
  - baz
    - __init__.py
    ...
  - tests
    - __init__.py
    - something.py

现在,默认情况下,nose 不会运行在 foo.tests.something 中找到的测试。我知道 nose 可以用 -i 选项来定义正则表达式,以便在其他地方搜索测试。所以 nose -i something 可以解决这个问题。不过,我在 tests 包里有很多模块,不想一个个地明确命名。 nose -i tests\..* 也不行,因为看起来 nose 只匹配模块的基本名称。作为最后的办法,我可以运行 nose --all-modules,但这样也会检查 foo.barfoo.baz,我想避免这种情况。

那么,我该如何指示 nose 在指定包(在我这里是 tests)中的所有模块里寻找测试呢?我可以为这个任务写一个 nose 插件,但我在寻找一个标准的解决方案。

3 个回答

-1

使用Nose:

nosetests --all-modules

如果你用的是py.test,可以在setup.cfg(配置文件)里加上这个:

[pytest]
python_files=*.py

查看这个文档:pytest文档

4

如果你在测试文件的名字前加上一个 test_ 的前缀(比如把 something.py 改成 test_something.py),那么运行 nose 时,它会默认识别这些文件。

你说“我不想让模块名字被测试名称的模式弄得乱七八糟”,但是“something”这个名字并不能清楚地说明这个文件的内容,因为这个文件是用来测试某个东西的。那为什么不使用这种简单明了、标准的命名方式来命名你的测试呢?

3

你应该可以把文件导入到你的 __init__.py 文件中,这样它们就能被识别了。我之前是这样设置的:

- app:
  - __init__.py
  - models.py
  - views.py
  - tests:
    - __init__.py
    - models.py # contain tests
    - views.py # contain tests

tests/__init__.py 文件里,我有以下内容:

from app.tests.models import *
from app.tests.views import *

这样做虽然有点违背了使用正则表达式查找测试的一个好处(这是nose的一个目标),但还是能正常工作。

如果你想避免方法名称和正则表达式匹配,可以使用 @istest 这个装饰器来标记某个函数为测试。我没有尝试过对那些不符合正则表达式的模块(py文件)使用这个装饰器,但我怀疑如果没有上面的导入,它是行不通的。

另外,我现在不再在 __init__.py 中做导入了,而是把我的测试方法和文件名都加上前缀 test_,把类名加上后缀 Test。我发现这样做让代码更容易理解,因为即使在一个测试类里,可能还有一些设置方法和辅助方法(比如生成器)。

撰写回答