我的项目如下所示:
|- 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/
我尝试过的:
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):
# ...
python -m unittest ...
python -m unittest ...
,否则失败python -m unittest ...
,但否则会失败我想我可以将基本测试用例与包的其余部分一起安装,以实现绝对导入。但是,我不想发送与我的测试相关的任何内容。
我重新创建了你的目录结构:
$ 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
主要区别似乎是我正在将
TestBase
绝对导入到 test_thing.py
中:
from tests.base_test_case import TestBase