You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python单元测试模块导入失败问题求助

Python unittest 测试文件导入问题

我是Python新手,写unittest时碰到了测试文件的导入问题。

文件夹结构

toyProjects
└── pythonProj
    ├── mainpack
    │   ├── __init__.py         
    │   ├── MyClass.py  
    │   └── setup.py
    └── tests
        ├── __init__.py        
        └── test_MyClass.py

另外pythonProj目录下还有一个mainfile.py(未在结构里展示),运行正常能找到所有文件,代码见下文。

各文件代码

MyClass.py

class MyClass:
    def __init__(self, x):
        self.x = x

    def someMethod(self):
        print("Called MyClass.someMethod");

setup.py

def myFunction():
    print("Called setup.myFunction");

test_MyClass.py 初始代码

import unittest

import setup
from MyClass import MyClass

class TestMyClass(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.my = MyClass(4);

    def test_something(self):
        self.my.someMethod();
        setup.myFunction();    

mainfile.py

from mainpack import setup
from mainpack.MyClass import MyClass

print("Program start");

setup.myFunction()

myInst = MyClass(4);
myInst.someMethod();

测试运行命令

我用下面的命令运行测试:

cd toyProjects\pythonProj\tests
python -m unittest test_MyClass.py

尝试过的导入方式及报错

我试了多种导入写法,都报错:

  • import setup → ModuleNotFoundError: No module named 'setup'
  • from MyClass import MyClass → ModuleNotFoundError: No module named 'MyClass'
  • from mainpack import setup → ModuleNotFoundError: No module named 'mainpack'
  • from ..mainpack import setup → Unresolved reference mainpack
  • import mainpack → ModuleNotFoundError: No module named 'mainpack'
  • from mainpack.setup import someFunction → Unresolved reference mainpack
  • from .. import mainpack → ImportError: attempted relative import with no known parent package

我查过相关资料,知道修改sys.path通常不是规范做法,希望学习正确的解决方式;如果实在没办法,也可以接受修改sys.path,但之前试的修改都没效果。


解决方案

方法1:从项目根目录运行测试(最规范)

不要进入tests目录,直接在pythonProj目录下运行测试命令:

cd toyProjects\pythonProj
python -m unittest tests/test_MyClass.py

然后修改test_MyClass.py里的导入语句,和mainfile.py保持一致:

import unittest

from mainpack import setup
from mainpack.MyClass import MyClass

class TestMyClass(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.my = MyClass(4);

    def test_something(self):
        self.my.someMethod();
        setup.myFunction();    

这种方式完全符合Python的包导入规范,不需要修改任何路径,因为项目根目录pythonProj会被加入Python的模块搜索路径,mainpack作为顶层包可以直接被导入。

方法2:使用相对导入(需保证测试包被正确识别)

如果一定要在tests目录下运行测试,需要把tests也当作一个包,并且确保Python能识别到它的父包。不过这种方式需要调整运行方式:

  1. 修改test_MyClass.py的导入为相对导入:
import unittest

from ..mainpack import setup
from ..mainpack.MyClass import MyClass

class TestMyClass(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.my = MyClass(4);

    def test_something(self):
        self.my.someMethod();
        setup.myFunction();    
  1. 从pythonProj目录下用包的方式运行测试:
cd toyProjects\pythonProj
python -m unittest tests.test_MyClass

注意不能直接在tests目录下运行,否则Python无法识别..对应的父包。

方法3:临时修改sys.path(不推荐但可行)

如果上面两种方式都没法用,可以在test_MyClass.py开头添加代码,把项目根目录加入sys.path:

import unittest
import sys
from pathlib import Path

# 获取项目根目录(pythonProj)的路径
project_root = Path(__file__).parent.parent
sys.path.append(str(project_root))

from mainpack import setup
from mainpack.MyClass import MyClass

# 后续测试代码不变
class TestMyClass(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.my = MyClass(4);

    def test_something(self):
        self.my.someMethod();
        setup.myFunction();    

然后可以继续在tests目录下用原来的命令运行测试。不过这种方式属于临时 hack,长期维护的话推荐用前两种规范方式。


内容的提问来源于stack exchange,提问作者MJL

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 01:55:16