Python Unittest - 如何正确处理不同文件夹和共享基础测试用例中的测试?

问题描述 投票:0回答:1

我的项目如下所示:

|- src/
|  |- my_package/
|     |- __init__.py
|     |- ...
|
|- tests/
|  |- group1/
|  |  |- __init__.py (empty)
|  |  |- test_thing_1.py
|  |- ...
|  |- base_test_case.py
|
|- pyproject.toml

这里

test_thing_1.py
(和其他测试文件)依赖于
base_test_case.py
中的基本 TestCase 类。
我应该如何将这个基类导入到测试文件中?


更多细节。使用上面的结构,您可以通过先安装源然后运行

unittest
:

来运行测试
pip install -e .
python -m unittest discover tests/

每个测试文件(例如

test_thing_1.py
)都可以将包源作为适当的全局导入来访问(
src/
目录可以防止不明确的包):

from mypackage import MyClass


class SomeTestCase(TestBase):
    # ...

但现在我也有一个基本测试用例,我将为每个真实的测试用例扩展:

# file: base_test_case.py


class TestBase(unittest.TestCase):
    # ...

我想在子文件夹中组织我的测试。没关系,只要每个文件夹包含一个

__init__.py
文件即可。

现在:如何在我的测试文件中导入

TestBase
,以便测试能够稳健地运行:

  • python tests/group1/test_thing_1.py
  • python -m unittest discover tests/group1/
  • 来自 PyCharm

我尝试过的:

from mypackage import MyClass

# OR:
from ..base_test_case import TestBase
# OR:
from .base_test_case import TestBase
# OR:
from base_test_case import TestBase


class SomeTestCase(TestBase):
    # ...
  • 第一个适用于在 PyCharm 内触发测试,但运行失败
    python -m unittest ...
  • 第二个适用于运行
    python -m unittest ...
    ,否则失败
  • 第三个适用于
    python -m unittest ...
    ,但否则会失败

我想我可以将基本测试用例与包的其余部分一起安装,以实现绝对导入。但是,我不想发送与我的测试相关的任何内容。

python python-import python-unittest
1个回答
0
投票

我重新创建了你的目录结构:

$ tree . -I __pycache__ -I my_package.egg-info
.
├── pyproject.toml
├── src
│   └── my_package
│       └── __init__.py
└── tests
    ├── base_test_case.py
    └── group1
        ├── __init__.py
        └── test_thing1.py

4 directories, 5 files

my_package.__init__.py
有以下内容:

class MyClass:
    def times2(self, value):
        return value * 2

base_test_case.py
有:

import unittest


class TestBase(unittest.TestCase):
    expected = 22
    test_value = 11

test_thing1.py
有:

from my_package import MyClass
from tests.base_test_case import TestBase


class SomeTestCase(TestBase):
    def test_times2(self):
        my_class = MyClass()
        self.assertEqual(my_class.times2(TestBase.test_value), TestBase.expected)

并且

pyproject.toml
有:

[project]
name = "my_package"
version = "1.0.0"

[build-system]
requires = ["setuptools >= 61.0"]
build-backend = "setuptools.build_meta"

[tool.setuptools.packages.find]
where = ["src"]
include = ["my_package*"]
namespaces = false

在命令行上我这样做:

$ pip install -e .
Obtaining file://$HOME/PycharmProjects/78297862
  Installing build dependencies ... done
  Checking if build backend supports build_editable ... done
  Getting requirements to build editable ... done
  Installing backend dependencies ... done
  Preparing editable metadata (pyproject.toml) ... done
Building wheels for collected packages: my_package
  Building editable for my_package (pyproject.toml) ... done
  Created wheel for my_package: filename=my_package-1.0.0-0.editable-py3-none-any.whl size=1203 sha256=b962da340d5bcc9fe909c2e58bf60a028a8475a4fe1f3a122cefb8d16f92c92c
  Stored in directory: /tmp/pip-ephem-wheel-cache-6ekafjm5/wheels/a8/9c/cc/682ba2654943278b924e62dcc738360a832c1757bfcf5393a9
Successfully built my_package
Installing collected packages: my_package
Successfully installed my_package-1.0.0

如果我运行您问题中的两种命令行变体,我会得到:

(.venv) 78297862$ python -m unittest discover tests/
.
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK
(.venv) 78297862$ python -m unittest discover tests/group1/
.
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK

它也在 PyCharm 内部工作。

主要区别似乎是我正在将

TestBase
绝对导入到
test_thing.py
中:

from tests.base_test_case import TestBase
© www.soinside.com 2019 - 2024. All rights reserved.