python unittest ModuleNotFoundError: Нет модуля с именем <...> - PullRequest
0 голосов
/ 27 ноября 2018

Я пытался создать простой проект Python с flask и unittest.Структура довольно проста:

classes
  |-sysinfo
      |static
      |templates
         |- index.html
         |- layout.html
      |__init__.py
      |sysinfo.py
      |printinfo.py
  tests
  |test_sysinfo.py
README.md
requirments.txt

Очень простой класс в printinfo.py:

 #!/usr/bin/python
import psutil
import json
class SysInfo:
.......
    def displayInfo(self):
        .......
        return json.dumps(self.__data)

И простой колб-сервер работает с sysinfo.py:

from flask import Flask, flash, redirect, render_template, request, session, abort
from printinfo import SysInfo
import json
obj1 = SysInfo("gb")
app = Flask(__name__)
@app.route('/')
def index():
    var = json.loads(obj1.displayInfo())
    return render_template('index.html',**locals())
@app.route('/healthcheck')
def healthcheck():
    return "Ok"
@app.route("/api/all")
def all():
    return obj1.displayInfo()
if __name__ == '__main__':
   app.run(host='0.0.0.0', port=80)
del obj1

Я запускаю его с python sysinfo.py, оставаясь в папке classes/sysinfo, и все работает нормально.

Поэтому я решил запустить unittest для своего приложения.Вставьте classes/tests (также пробовал classes/sysinfo/tests) файл test_sysinfo.py с кодом:

import unittest
import printinfo
from sysinfo import sysinfo
import json
import sys
class TestFlaskApi(unittest.TestCase):
    def setUp(self):
        self.app = sysinfo.app.test_client()
    def simple_test(self):
        response = self.app.get('/health')
        self.assertEqual(
            json.loads(response.get_data().decode(sys.getdefaultencoding())),
            {'healthcheck': 'ok'}
        )
if __name__ == "__main__":
    unittest.main()

И когда я запустил его, я вижу ошибку:

Error Traceback (most recent call last):
   File "\Python\Python37-32\lib\unittest\case.py", line 59, in testPartExecutor
     yield   File "\Python\Python37-32\lib\unittest\case.py", line 615, in run
     testMethod()   File "\Python\Python37-32\lib\unittest\loader.py", line 34, in testFailure
     raise self._exception ImportError: Failed to import test module: test_sysinfo Traceback (most recent call last):   File
 "\Python\Python37-32\lib\unittest\loader.py", line 154, in
 loadTestsFromName
     module = __import__(module_name)   File "\classes\sysinfo\tests\test_sysinfo.py", line 2, in <module>
     import printinfo ModuleNotFoundError: No module named 'printinfo'

Я прочитал несколькостатьи, некоторые темы здесь, на StackOverflow, насколько я понимаю, это связано со структурой проекта.Я пытался создать setup.py и setup.cfg.Мне удалось запустить его с этой настройкой, но тестирование по-прежнему не работает.

Не могли бы вы помочь мне с минимальной настройкой, применимой для моего случая?Весь материал, который я нашел, был написан для конкретного случая или слишком общего.Я не могу применить это для моего случая.

Ответы [ 2 ]

0 голосов
/ 29 ноября 2018

Только что последовал урок Flask.Создано conftest.py и test_factory.py.Запустите Ok с pytest:

import pytest
from sysinfo import create_app
from sysinfo import printinfo

@pytest.fixture
def app():
    app = create_app({
        'TESTING': True
    })

    with app.app_context():
        printinfo.SysInfo("gb")

    yield app

Возможно, такую ​​же настройку можно использовать с unittest.Не пробовал.

0 голосов
/ 28 ноября 2018

Следуйте инструкциям по фляге. Я редактирую файл __init__.py, чтобы запустить приложение отсюда:

from flask import Flask, flash, redirect, render_template, request, session, abort
from . import printinfo
import json
import os

obj1 = printinfo.SysInfo("gb")

def create_app(test_config=None):
    # create and configure the app
    app = Flask(__name__, instance_relative_config=True)
    app.config.from_mapping(
        SECRET_KEY='dev'
    )

    obj1 = printinfo.SysInfo("gb")

    @app.route('/')
    def index():
        var = json.loads(obj1.displayInfo())
        return render_template('index.html', **locals())

    @app.route('/healthcheck')
    def healthcheck():
        return "Ok"

    @app.route("/api/all")
    def all():
        return obj1.displayInfo()

    #del obj1
    return app

Также необходимо установить переменные среды для Flask: Для Linux и Mac:

export FLASK_APP=sysinfo
export FLASK_ENV=development

Для Windows cmd используйте set вместо export:

set FLASK_APP=sysinfo
set FLASK_ENV=development

и запустите приложение:

flask run

Оно запускает приложение на локальном хосте через порт 5000 с момента разработки env.В любом случае мне нужно было добавить from . import printinfo в __init__.py.

Не пробовал тестировать, но думаю, что оно должно работать.Если интересно, скоро обновлю.

...