运行 来自 Python 中子目录的所有测试

Run all tests from subdirectories in Python

我想在 Python 中将我所有的单元测试都提高到 运行,我已经束手无策了。我已经搜索了大约 30 个不同的帖子和单元测试文档,但仍然无法弄清楚。

首先我有两个测试 类 我可以单独 运行 并且所有测试都通过了:

文件:unittest.subfolder1.TestObject1.py

class TestObject1(unittest.TestCase):
  def test_case1(self):
    ...some code...
    ...some assertions...

if __name__ == '__main__':
  unittest.main()

文件:unittest.subfolder2.TestObject2.py

class TestObject2(unittest.TestCase):
  def test_case1(self):
    ...some code...
    ...some assertions...

if __name__ == '__main__':
  unittest.main()

从上面的顶级目录开始 'unittest' 我正在尝试 unittest.discover 查找和 运行 我所有的测试:

import unittest

loader = unittest.TestLoader()
suite = loader.discover('unittest')
unittest.TextTestRunner().run(suite)

当我这样做时,我收到错误`ModuleNotFoundError: No module named 'subfolder1.TestObject1'

我做错了什么?

不要命名你的目录unittest,它可能会与标准库冲突。

您还需要在所有目录(subfolder1 等)中创建一个名为 __init__.py 的文件,以便它们成为包并可以导入其内容。

所以我必须自己解决问题,但至少我可以使用上述文件结构将它们全部 运行。它要求我每次给它一个新的文件路径时都要重新实例化TestLoader和TestSuite,所以首先我需要在unittest目录中收集所有相关的文件路径。

import os
import unittest
import traceback


class UnitTestLauncher(object):

  def runTests(self):
    #logging.INFO("Running unit tests...")


    lsPaths = []

    #Find all relevant subdirectories that contain unit tests
    #Exclude 'unittest' directory, but include subdirectories, with code `path != 'unittest'`
    for path,subdirs,files in os.walk('unittest'):
      if "pycache" not in path and path != 'unittest':
        lsPaths.append(path)

    #loop through subdirectories and run individually
    for path in lsPaths:
      loader = unittest.TestLoader()
      suite = unittest.TestSuite()
      suite = loader.discover(path)
      unittest.TextTestRunner().run(suite)

这个解决方案并不完美,每个不同的目录都作为一行输出出现,因此您必须手动查看每一行以查找失败的测试。

一个好的方法是从命令行 运行 子目录中的所有测试。为了在子目录中找到以下文件"TestObject1.py, TestObject2.py, ...",您可以在命令行中运行以下命令:

python -m unittest discover -p 'Test*.py'

此外,__init__.pyimportmodule 中是必需的目录:Python unittest discovery with subfolders

文件 unittest.subfolder1.TestObject1.py 和 unittest.subfolder2.TestObject2.py

中需要 import unittest

也可以显式定义目录,其中发现以-s参数开始:

python -m unittest discover [options]

-s directory     Directory to start discovery ('.' default)
-p pattern       Pattern to match test files ('test*.py' default)

如果您使用的是 unittest2,它附带一个脚本 unit2。命令行用法为:

unit2 discover unit2 -v test_module

老问题但是,哦,很新。我是 Python 的新手,来自强类型语言,虽然语言本身还不错,但使生态系统中的一切正常运行的约定、工具和解决方法会让你抓狂。我为来自不同子目录的 运行 单元测试而苦苦挣扎,这就是我解决它的方式。 首先,将您测试的代码打包成一个包。像这样组织您的目录:

Work
|
+---PkToTest
|   |
|   +--- __init__.py
|   +--- a.py
|   +--- <other modules>.py
|
+---Tests (for PKToTest)
    |
    +--- test_a.py

PkToTest 由于 init.py 文件而成为一个包。在 test_a.py 中确保您的 sys.path 将包含 PkToTest 的路径(绝对路径而非相对路径)。我通过以下方式做到了:

import sys
sys.path.insert(0, "<absolute path to parent of PkTotest directory>")

import unittest
from PkToTest import a

class aTestSuite(unittest.TestCase):
    def test1(self):
       self.assertEqual(a.fnToTest(), ...)

在我的项目中,所有文件夹都是文件夹(不是模块)并且它们具有以下结构:

文件夹 > 子文件夹 > 子文件夹 > 测试 > test_xxxx.py
文件夹 > 子文件夹 > 子文件夹 > xxxx.py

所以我从这里修改了答案,也参与了 How do I run all Python unit tests in a directory? 并提出了这个:

import os, unittest

testFolderPaths = []

for path, subdirs, files in os.walk(os.getcwd()):
    for file in files:
        if file.startswith("test_") and file.endswith(".py"):
            testFolderPaths.append(path)

for path in testFolderPaths:
    print(f"Running tests from {path}...")
    loader = unittest.TestLoader()
    suite = loader.discover(path)
    runner = unittest.TextTestRunner()
    result = runner.run(suite)
    print(f"RUN {result.testsRun} Tests. PASSED? {result.wasSuccessful()}")

如果任何测试失败,它将抛出错误并显示具体失败的测试。

正在测试所有子目录

给定一个结构:

my_package
|
|
controller
|-- validator.py
|
validator
|-- controller.py
|
test
|-- controller
|
  |-- __init__.py (MAKE SURE THIS EXISTS OR unittest MODULE WOULD NOT KNOW)
  |-- test_controller.py
  |
|-- validator
|
  |-- __init__.py (MAKE SURE THIS EXISTS OR unittest MODULE WOULD NOT KNOW)
  |-- test_validator.py
  |

然后 运行

python -m unittest discover -s my_package/test

这个是做测试的,-s表示以my_package/test为起始目录