Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
跨应用程序/测试的python导入更优雅的解决方案?_Python_Unit Testing - Fatal编程技术网

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

跨应用程序/测试的python导入更优雅的解决方案?,python,unit-testing,Python,Unit Testing,我试图通过将测试放在我的应用程序的一个单独目录中来合理地组织我的代码。但是,导入可以用于应用程序或测试,但不能同时用于两者。下面是一个人为的例子,说明了我当前的问题: myapp/ app/ main.py settings.py moods.py test/ test_moods.py 文件内容如下: main.py import settings from moods import Moods words = Moods(settings.EXAM

我试图通过将测试放在我的应用程序的一个单独目录中来合理地组织我的代码。但是,导入可以用于应用程序或测试,但不能同时用于两者。下面是一个人为的例子,说明了我当前的问题:

myapp/
  app/
    main.py
    settings.py
    moods.py
  test/
    test_moods.py
文件内容如下:

main.py

import settings
from moods import Moods

words = Moods(settings.EXAMPLE)
print(words.excited())
EXAMPLE = "Wow$ Python$"
DELIM = "$"
import settings

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

    def excited(self):
        return self.text.replace(settings.DELIM, "!!!")
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()
设置.py

import settings
from moods import Moods

words = Moods(settings.EXAMPLE)
print(words.excited())
EXAMPLE = "Wow$ Python$"
DELIM = "$"
import settings

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

    def excited(self):
        return self.text.replace(settings.DELIM, "!!!")
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()
moods.py

import settings
from moods import Moods

words = Moods(settings.EXAMPLE)
print(words.excited())
EXAMPLE = "Wow$ Python$"
DELIM = "$"
import settings

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

    def excited(self):
        return self.text.replace(settings.DELIM, "!!!")
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()
测试情绪.py

import settings
from moods import Moods

words = Moods(settings.EXAMPLE)
print(words.excited())
EXAMPLE = "Wow$ Python$"
DELIM = "$"
import settings

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

    def excited(self):
        return self.text.replace(settings.DELIM, "!!!")
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()
在当前状态下,从
myapp/
我可以成功运行以下操作:

>> python3 app/main.py
Wow!!! Python!!!
但当我尝试运行测试时,在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'
如果我将moods.py的第1行修改为从应用程序导入设置中读取
,测试将通过,但应用程序的正常执行将失败,因为它没有看到模块
app

我能想到的唯一解决办法是

  • 将测试放在与代码相同的目录中(我试图避免这样做)
  • sys.path.insert(0,os.path.abspath('..'))
    添加到我的应用程序中的每个文件,以使导入的工作方式与测试导入的工作方式相同(这看起来很混乱)

  • 有没有更优雅的方法来解决这个导入问题?

    您应该在
    PYTHONPATH
    中同时拥有
    app
    test
    目录

    一种方法是替换此选项:

    sys.path.insert(0, os.path.abspath('..'))
    
    from app.moods import Moods
    
    为此:

    sys.path.insert(0, os.path.abspath('../app'))
    
    from moods import Moods
    
    或者,您可以在运行测试之前设置
    PYTHONPATH
    environment变量


    为什么??因为当您运行
    main.py
    时,
    app
    在路径中,而不是
    app/.
    ,所以您希望在运行测试时拥有相同的路径。

    您应该在
    PYTHONPATH
    中同时拥有
    app
    test
    目录

    一种方法是替换此选项:

    sys.path.insert(0, os.path.abspath('..'))
    
    from app.moods import Moods
    
    为此:

    sys.path.insert(0, os.path.abspath('../app'))
    
    from moods import Moods
    
    或者,您可以在运行测试之前设置
    PYTHONPATH
    environment变量


    为什么??因为当您运行
    main.py
    时,
    app
    在路径中,而不是
    app/。
    ,所以您希望在运行测试时具有相同的路径。

    Hmm。。。到目前为止,这一解决方案似乎是最有希望的。它是干净的,并保持对测试文件的路径修改。但是,它不起作用。实现上面建议的代码更改会产生:
    importorror:没有名为“moods”的模块。
    Ok。。。奇怪的是,设置
    os.path.abspath('app')
    起了作用。我想这是因为我从父目录运行测试,并且它知道应用程序目录?@vastlysuperiorman如果你从父目录运行,那么
    app
    是正确的路径,是的。嗯。。。到目前为止,这一解决方案似乎是最有希望的。它是干净的,并保持对测试文件的路径修改。但是,它不起作用。实现上面建议的代码更改会产生:
    importorror:没有名为“moods”的模块。
    Ok。。。奇怪的是,设置
    os.path.abspath('app')
    起了作用。我想这是因为我正在从父目录运行测试,并且它知道app目录?@vastlysuperiorman如果您正在从父目录运行,那么
    app
    是正确的路径,是的。