简体   繁体   English

跨应用程序/测试的python导入更优雅的解决方案?

[英]More elegant solution for python imports across app/tests?

I'm trying to keep my code reasonably organized by putting tests in a separate directory from my app. 我试图通过将测试放在与应用程序不同的目录中,以合理地组织代码。 However, imports work either for the app or for the tests, but not both. 但是,进口的工作无论是对应用程序测试,但不能同时使用。 Here's a contrived example that illustrates my current problem: 这是一个人为的例子,说明了我当前的问题:

myapp/
  app/
    main.py
    settings.py
    moods.py
  test/
    test_moods.py

Contents of files as follows: 文件内容如下:

main.py main.py

import settings
from moods import Moods

words = Moods(settings.EXAMPLE)
print(words.excited())

settings.py settings.py

EXAMPLE = "Wow$ Python$"
DELIM = "$"

moods.py 心情

import settings

class Moods:
    def __init__(self, text):
        self.text = text

    def excited(self):
        return self.text.replace(settings.DELIM, "!!!")

test_moods.py test_moods.py

import sys, os, unittest
sys.path.insert(0, os.path.abspath('..'))

from app.moods import Moods

class TestMood(unittest.TestCase):
    def setUp(self):
        self.words = Moods("Broken imports$ So sad$")

    def test_mood(self):
        self.assertEqual(self.words.excited(), "Broken imports!!! So sad!!!")
        with self.assertRaises(AttributeError):
            self.words.angry()

if __name__ == "__main__":
    unittest.main()

In the current state, from myapp/ I can run the following successfully: 在当前状态下,可以从myapp/成功运行以下命令:

>> python3 app/main.py
Wow!!! Python!!!

But when I try to run tests, the import fails in moods.py: 但是,当我尝试运行测试时,导入在moods.py中失败:

>> python3 -m unittest discover test/
ImportError: Failed to import test module: test_moods
[ stack trace here pointing to first line of moods.py ]
ImportError: No module named 'settings'

If I modify line 1 of moods.py to read from app import settings , the test will pass, but normal execution of the app fails because it sees no module app . 如果我将moods.py的第1行修改为from app import settings读取,则测试将通过,但该应用程序的正常执行失败,因为它看不到模块app

The only solutions I can think of are 我能想到的唯一解决方案是

  1. Putting the tests in the same directory as the code (which I was trying to avoid) 将测试与代码放在同一目录中(这是我试图避免的)
  2. Adding the sys.path.insert(0, os.path.abspath('..')) to each file in my app to make the imports work the same as the test ones do (which seems messy) sys.path.insert(0, os.path.abspath('..'))到我应用程序中的每个文件中,以使导入工作与测试文件相同(看起来很杂乱)

Is there are more elegant way to solve this import problem? 有没有更优雅的方法来解决此导入问题?

You should have both app and test directory in PYTHONPATH . 您应该在PYTHONPATH同时具有apptest目录。

One way is to replace this: 一种方法是替换为:

sys.path.insert(0, os.path.abspath('..'))

from app.moods import Moods

with this: 有了这个:

sys.path.insert(0, os.path.abspath('../app'))

from moods import Moods

Or you can set the PYTHONPATH environament variable before running the tests. 或者,您可以在运行测试之前设置PYTHONPATH环境变量。

Why? 为什么? Because when you run main.py , then app is in the path, not app/.. , so you want to have the same when running tests. 因为当您运行main.py ,那么app在路径中,而不是app/.. ,因此您希望在运行测试时使用相同的路径。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM