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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16863742/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 23:51:11  来源:igfitidea点击:

Run unittest from Python program via command line option

pythonunit-testingpython-2.7software-packaging

提问by RyPeck

Here is my set up -

这是我的设置 -

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

I would like to be able to run my unit tests by calling a command line option in prog.py, this way when I deploy my project I can deploy the ability to run the unit tests at any time.

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

python prog.py --unittest

What do I need in prog.py, or the rest of my project for this to work?

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

采纳答案by amillerrhodes

Perhaps thisis what you're looking for. Implement a load_testsfunction in test_prog.pyand use the following code in prog.pyto load and run the tests:

也许就是你要找的。实现一个load_tests函数test_prog.py并使用以下代码prog.py加载和运行测试:

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

回答by Carlos V

You must make sure that you consistently follow some naming conventions (which you seem to be doing):

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

  1. All tests are named with the same prefix (test_is the norm), followed by the name of the module you wish to test.

    prog.py=> test_prog.py

  2. Tests reside in test/directory.

  1. 所有测试都使用相同的前缀(test_是规范)命名,后跟您要测试的模块的名称。

    prog.py=> test_prog.py

  2. 测试驻留在test/目录中。

Then you can do something like this:

然后你可以做这样的事情:

prog.py

程序.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)


What we are doing, is:

我们正在做的是:

  • Checking the command arguments to see if --unittestis present (since that's the only time you want to run the tests).

  • If it is, then we create the test_prog.py- following the naming conventions we have set.

  • Then we pass that to the TestLoader().discoverfunction.

    discover(...)starts at the specified directory and finds all test modules (recursing into subdirectories ) that match the pattern provided.

    In our case, it will look inside the test/directory for any module named test_prog.py. When it does, it loads it and creates a TestSuite with the TestCases that we want to run.

  • Lastly, we manually test unittestto run the suiteobtained in the previous step.

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

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

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

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

    在我们的例子中,它将在test/目录中查找任何名为test_prog.py. 当它这样做时,它会加载它并使用我们想要运行的测试用例创建一个测试套件。

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



Normally, unittestwill do all of this for us in the background, but since we are trying to run a specific test module, we have to tell exactly how and where to get it from.

通常,unittest会在后台为我们完成所有这些工作,但是由于我们正在尝试运行特定的测试模块,因此我们必须确切地告诉我们如何以及从何处获取它。

Also, note that you will have to do this for everyfile where you want to do this at.

另外,请注意,您必须对要在其中执行此操作的每个文件执行此操作。

回答by Jace Browning

The Python unittestmodule contains its own test discoveryfunction, which you can run from the command line:

Pythonunittest模块包含自己的测试发现功能,您可以从命令行运行该功能:

$ python -m unittest discover

To run this command from within your module, you can use the subprocessmodule:

要从您的模块中运行此命令,您可以使用该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'])

If your module has other command-line options you probably want to look into argparsefor more advanced options.

如果您的模块有其他命令行选项,您可能需要查看argparse更高级的选项。