Python,导入模块进行测试

23

我在尝试设置一个简单测试时遇到了很大的困难。

我的项目结构如下:

project:
   models:
      __init__.py
      user.py
      constants.py
      test:
         test.py

我想要测试 user.py,通过运行test.py

user.py

from sqlalchemy import Column, Integer, String, Text
from sqlalchemy.orm import relationship
from .models.constants import *
from .models import Base

class User(Base):
    __tablename__ = 'users'

    uid = Column(Integer, primary_key=True, autoincrement=True)
    name = Column(String, nullable=False)
    email = Column(String, nullable=False)
    picPath = Column(String, unique=True)
    description = Column(Text)

    def __repr__(self):
        return "<User(uid=%s, name=%s)>" %(self.uid, self.name)

test.py

from ..user import User, Group

def _TestUser():
    TEST_DB_URI = "postgresql://project:password@localhost:5432/projectdbtest"
    SessionMaker = sessionmaker()
    engine = create_engine(TEST_DB_URI)
    SessionMaker.configure(bind=engine)

    session = SessionMaker()
    user = User("test subject", "testsubject@gmail.com", "~/testsubject.jpg", "I am a test subject")
    session.add(user)
    session.commit()

然而,当我运行python3 -m test.py时,出现以下错误:

SystemError: 父模块“”未加载,无法执行相对导入

我认为我可能需要将模块包添加到Python路径中?


2
请点击这里 - Mauro Baraldi
2个回答

30

以下是一些简化我的测试并且对我非常有效的方法。

始终从项目根目录进行测试

最初,我认为我的测试用例应该可以从任何目录使用。

实际上,没有理由让测试用例以这种方式灵活,决定仅从项目根目录运行所有测试用例会极大地简化解决方案。

对许多程序员来说可能很明显,但对于我来说,这是朝着简化测试迈出的重要一步。

将测试目录与包代码分开

将生产代码与测试代码混合似乎是有道理的,但很快就会变得混乱无序。

最后,我决定在项目中使用单独的tests(复数形式)目录,并且这对我非常有效。

优点如下:

  • 测试“紧贴”在手边(请参见与py.test相关的下一部分),可以手动或从其他工具(如tox)中使用。
  • 不需要在包目录中寻找测试目录,它们只是存放在单独的地方。
  • 在进行测试时感到安全-因为你不再依赖主代码。

注意:尽量始终使用名称tests,不要使用test。遵循这个简单规则将简化您的工作,因为您将始终知道测试目录的真实名称。

使用pytest测试框架

有多种测试框架(unittestnosenose2pytest),实际上所有框架都提供了你所需的基础功能。

无论如何,我发现pytest(使用py.test命令)非常有趣,原因如下:

  • 可以运行大多数在其他框架中编写的测试(unittest,nose...)
  • 非常容易创建第一个测试函数。
  • 测试函数可以保持非常简单,而出色的固定装置将把所需的值注入其中。一旦尝试过它,就不会使用其他方法。
  • 可以自然地扩展测试套件
  • 非常适合开始原型编码并逐步发展到生产代码:
    • 在测试函数中开始
    • 将其移出测试函数,放入同一测试文件的独立函数中
    • 移到外部模块(大部分测试代码不需要更改)
  • 避免在测试套件目录中使用 __init__.py

    参见选择测试布局/导入规则以了解说明并遵循建议避免使用 __init__.py

    简而言之,事情会更简单。

    请注意,其他方法也可以使用,并且没有错 - 我只想分享对我非常有效的方法。


    4
    这是一个非常有争议的观点:“将测试目录与软件包代码分开”。 - trexinf14s

    1

    最近我也遇到了同样的问题。

    在测试文件夹中添加以下__init__.py文件,可以解决我的问题:

    import os
    import sys
    PROJECT_PATH = os.getcwd()
    sys.path.append(PROJECT_PATH)
    

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接