通过命令行选项从Python程序运行unittest



这是我的设置-

project/
    __init__.py
    prog.py
    test/
        __init__.py
        test_prog.py

我希望能够通过调用prog.py中的命令行选项来运行我的单元测试。这样,当我部署我的项目时,我可以随时部署运行单元测试的能力。

python prog.py --unittest

我需要在prog.py或项目的其余部分中做什么才能使其工作?

Python unittest模块包含自己的测试发现函数,您可以从命令行运行该函数:

$ python -m unittest discover

要在模块中运行此命令,可以使用subprocess模块:

#!/usr/bin/env python
import sys
import subprocess
# ...
# the rest of your module's code
# ...
if __name__ == '__main__':
    if '--unittest' in sys.argv:
        subprocess.call([sys.executable, '-m', 'unittest', 'discover'])

如果你的模块有其他命令行选项,你可能想看看argparse更高级的选项。

也许这就是您正在寻找的。在test_prog.py中实现load_tests函数,并在prog.py中使用以下代码来加载和运行测试:

import unittest
import test.test_prog
suite = unittest.TestLoader().loadTestsFromModule(test.test_prog)
unittest.TextTestRunner().run(suite)

您必须确保始终遵循一些命名约定(您似乎正在这样做):

  1. 所有测试都以相同的前缀命名(test_是规范),后面跟着您希望测试的模块的名称。

    prog.py => test_prog.py

  2. 测试位于test/目录。

然后你可以这样做:

prog.py

import sys
...
... do module stuff here...
...
if __name__ == "__main__":
    # Check if we want to run the tests for this file
    if "--unittest" in sys.argv:
        import unittest
        test_filename = 'test_' + __file__
        test_directory = 'test'
        suite = unittest.TestLoader().discover(test_directory, pattern=test_filename)
        unittest.TextTestRunner(verbosity=2).run(suite)

我们正在做的是:

  • 检查命令参数以查看--unittest是否存在(因为这是您唯一想要运行测试的时间)。

  • 如果是,那么我们创建test_prog.py -遵循我们设置的命名约定。

  • 然后我们将其传递给TestLoader().discover函数。

    discover(…)从指定的目录开始查找与所提供模式匹配的所有测试模块(递归到子目录中)。

    在我们的示例中,它将在test/目录中查找任何名为test_prog.py的模块。当它完成时,它会加载它并创建一个包含我们想要运行的TestCases的TestSuite。

  • 最后,我们手动测试unittest以运行在上一步中获得的suite


通常,unittest将在后台为我们做所有这些,但由于我们试图运行特定的测试模块,我们必须准确地告诉如何以及从哪里获得它。

另外,请注意,您必须为每个文件执行此操作。

我刚刚在文件系统中删除了项目下的.idea隐藏目录。

我重新启动PyCharm,重新打开项目,这个问题解决了。

最新更新