【问题标题】:How do I run unit tests in package directory如何在包目录中运行单元测试
【发布时间】:2018-03-23 10:22:11
【问题描述】:

我有一个 python 代码库,我将一个模块(文件)重构为一个包(目录),因为文件变得有点大且难以管理。但是,我无法使用新结构让我的单元测试按照需要运行。

我将单元测试文件直接放在它测试的代码旁边(这是一项要求,不能更改 - 没有单独的 test 目录):

app/
+-- app.py
+-- config.py
+-- config_test.py
+-- model/
|   +-- __init__.py
|   +-- base.py
|   +-- base_test.py
|   +-- square.py
|   +-- square_test.py
+-- test.py
+-- web.py
+-- web_test.py

以前,model 包是带有model_test.py 测试套件的model.py 模块。

有一个顶级测试运行器 - test.py 并且工作正常。它在model 目录中找到测试用例并成功运行它们(它使用unittestdiscovery 功能 - 请参阅test.py 的帖子末尾):

$ python test.py

不过,我也希望能够直接运行model目录下的测试用例:

$ python model/base_test.py

这不起作用,因为测试在包目录中。代码中的导入失败是因为测试套件直接导入时它们不在模块中,或者搜索路径错误。

例如,在model/square.py 中,我可以通过以下两种方式之一导入base.py

from model import Base

from .base import Base

model 被导入时,这两个都可以正常工作。但是在model 测试套件中,我无法导入square,因为square 无法导入base

square_test.py 包含如下导入:

import unittest
from square import Square
... test cases ...
if __name__ == '__main__':
    unittest.main()

对于square.py (from model import Base) 中的第一类导入,我得到错误:

ModuleNotFoundError: No module named 'model'

很公平,sys.path/home/camh/app/model 并且其中没有 model 模块。

对于square.py (from .base import Base) 中的第二种导入,我得到错误:

ImportError: attempted relative import with no known parent package

我无法弄清楚如何进行导入,以使我能够在被测单元旁边进行测试并且可以直接运行。我想要直接运行的测试套件,因为我不想运行整个测试集,而只是针对单个测试:

$ python model/square_test.py SquareTest.test_equal_sides

我无法对我的测试运行器执行此操作,因为它只使用发现来运行所有测试,并且发现与指定单独的测试套件或测试函数不兼容。

我的测试运行者 (test.py) 只是:

import os, sys
sys.argv += ['discover', os.path.dirname(sys.argv[0]), '*_test.py']
unittest.main(module=None)

【问题讨论】:

  • 我只在app中使用了nosetests -vw .,当鼻子会为你做这件事时,保留一个单独的test.py有什么好处?
  • 或使用nosetests -vv model/square_test.py进行特定测试
  • @Gang 我没有使用nose。需要test.py,因为我需要将标准发现模式修改为*_test.py。我宁愿坚持使用标准的 python 单元测试模块,而不是使用单独的测试框架。

标签: python unit-testing


【解决方案1】:

您可以使用参数从命令行调用unittest 模块:

python -m unittest model.square_test

如果您使用的是 python3,您也可以使用文件名:

python3 -m unittest model/square_test.py

【讨论】:

  • 我可以使用 python3 表单并运行特定的测试吗?我可以做python -m unittest model.square_test.SquareTest.test_equal_sides,但我不能让它与文件名一起工作。如果我想使用第一种形式运行多个单独的测试,它会有点麻烦。
【解决方案2】:

建议:

添加app/__init__.py,并将app 视为包而不是model

一种方法是用于所有测试,使用显式from app.model.square import Square

相对导入应该没问题,只要在app/目录下使用nosetests -vw .即可。

这些都在删除app/test.py的代价下

重构后的另一个常见错误是.pyc 没有全部删除并重新生成。

【讨论】:

    猜你喜欢
    • 2010-12-16
    • 2016-07-13
    • 1970-01-01
    • 1970-01-01
    • 2015-04-12
    • 2014-04-08
    • 2020-11-09
    • 2021-09-25
    • 1970-01-01
    相关资源
    最近更新 更多