如何将要测试的模块导入测试模块

时间:2019-04-27 14:43:17

标签: python-3.x python-import directory-structure cookiecutter

问题

我的项目有一个目录结构,该结构遵循使用此cookiecutter模板创建的Python软件包的标准: https://github.com/audreyr/cookiecutter-pypackage#quickstart

目录结构为

const express = require("express");
const cors = require("cors");
const app = express();
const server = require("http").Server(app);
const io = require("socket.io")(server);

// parse application/json [ With Express ]
app.use(express.json());
// application/x-www-form-urlencoded parser [ With Express ]
const urlencodedparser = express.urlencoded({ extended: false });

// Use Cors As Middleware
app.use(cors());

app.get("/", (req, res) => {
  res.send("Hello World");
});

server.listen(8080, () => console.log("Server Started on Port 8080"));

// Connect to io Socket(s)
io.on("connection", socket => {
  // Join Rooms
  socket.on("join-room", room => {
    console.log(room.roomName);
    socket.join(room.roomName);
    socket.on("send-msg", info => {
      if (info.roomName === room.roomName) {
        io.to(room.roomName).emit("send-msg", { msg: info.msg });
      } else {
        return;
      }
    });
  });
  // Leave Rooms
  socket.on("leave-rooms", room => {
    socket.leaveAll();
  });
});

project_name ├── project_name │ ├── __init__.py │ └── module1.py └── tests └── test_module1.py 的第一行代码是:

test_module1.py

但是我得到一个from project_name import module1

据我所知,这应该起作用,因为名为ModuleNotFoundError: No module named 'project_name'的文件夹是一个程序包,可以通过project_name文件的存在来确保。

我一直很难理解这样的导入是如何工作的。对于我的项目,我一直都希望将测试与要测试的模块放在同一文件夹中。我知道这是不好的做法,但这是我可以实际导入模块的唯一方法。

我已经尝试过的东西

我尝试将带有__init__.py文件的文件夹重命名为其他名称,然后导入,因为我认为这可能与名称均为__init__.py的父文件夹和子文件夹有关。这没有用,同样的错误。

即使Cokkiecutter模板没有该文件夹,我也尝试通过在其中创建project_name文件的方式将测试文件夹放入包中。 我在很多地方都读到不鼓励将测试文件夹放入程序包中,但有些人建议采用这种结构。那也不起作用。

我已经彻底搜索了这个看似非常标准的问题的解决方案,有些链接在这里:

我最后的尝试是使用Cookiecutter启动一个项目,因此从一开始就可以正确设置所有内容。但是,我仍然得到__init.py__

我不想要的

我不想修改ModuleNotFoundError,因为似乎答案很多。对于这种常见问题,必须有一种更清洁的方法。

我在做什么错?

编辑一些其他信息(请参阅@Nicholas的问题):

init .py”的内容为

sys.path

这是由Cookiecutter模板生成的。

# -*- coding: utf-8 -*- """Top-level package for project_name.""" __author__ = """my_name""" __email__ = 'my_email' __version__ = '0.1.0' 内部,我在test_module1发生之前添加了以下内容:

ModuleNotFoundError

import sys import os print(sys.path) print(os.getcwd()) 打印一个列表,其中第一个元素是sys.path目录。

tests

我不知道第一个元素中的小写字母'c'是否重要。

['c:\\Users\\...\\project_name\\tests', 'C:\\Users\\...\\Miniconda3\\python37.zip', 'C:\\Users\\...\\Miniconda3\\DLLs', 'C:\\Users\\...\\Miniconda3\\lib', 'C:\\Users\\...\\Miniconda3', 'C:\\Users\\...\\Miniconda3\\lib\\site- packages', 'C:\\Users\\...\\Miniconda3\\lib\\site-packages\\win32', 'C:\\Users\\...\\Miniconda3\\lib\\site-packages\\win32\\lib', 'C:\\Users\\...\\Miniconda3\\lib\\site-packages\\Pythonwin'] 打印根目录os.getcwd()。还带有小写字母“ c”。

1 个答案:

答案 0 :(得分:1)

您应该创建一个虚拟环境并安装项目,以使测试模块正确解析导入语句。

在项目根目录(即包含子目录project_name和子目录project_name的目录tests中,创建一个setup.py(或pyproject.toml)文件包元数据。有关该部分的详细信息,请参见here

从现在包含安装程序(setup.py)的同一项目根目录中,创建并激活venv并安装您的项目:

python3 -m venv .venv
source .venv/bin/activatate  # linux/macOS
# .\Scripts\activate.bat  # windows
pip install --editable .
pip install pytest
pytest

如果由于某种原因您不想为您的项目创建安装程序,则可以从项目目录运行pytest,如下所示:

python3 -m pytest

与简单的pytest命令不同,这会将当前工作目录添加到sys.path中,从而可以在测试中解析导入语句。