Как написать модульные тесты с файлами, которые прямо или косвенно `импортируют greengrasssdk`

Всякий раз, когда файл импортирует import greengrasssdk модульные тесты не пройдены, потому что модуль greengrass_commonне существует на моей локальной машине, и я не могу установить его через pip.

Я выполняю тесты с PyCharm. Я пытаюсь протестировать лямбду Greengrass, которая не выполняется локально из-за той же проблемы зависимости (то же исключение). Но как только лямбда выдвигается в зеленую траву, она работает нормально.

Вот исключение:

    import greengrasssdk
  File "C:\Python27\lib\site-packages\greengrasssdk\__init__.py", line 6, 
in <module>
    from .Lambda import StreamingBody
  File "C:\Python27\lib\site-packages\greengrasssdk\Lambda.py", line 10, in 
<module>
     from greengrass_common.function_arn_fields import FunctionArnFields
ImportError: No module named greengrass_common.function_arn_fields

Упрощенный пример кода:

import greengrasssdk
import logging

greengrass_iot_client = greengrasssdk.client('iot-data')
logger = logging.getLogger('logger')

def handler(event, context):
    logger.info('Event handler invoked with event: ' + str(event))

Я получаю следующее сообщение об ошибке в тесте (Тест исключен в папке теста, но другие проблемы с зависимостями пока не показаны - я пишу это, потому что некоторые разработчики помещают свои тесты в файл кода Python. Я слышал, что эти тесты находятся за пределами файла исходного кода может привести к проблемам с импортом. Хотя этот случай отличается, поскольку это также происходит в исходном файле кода.)

import unittest
import mock
import function

Класс SimpleTest(unittest.TestCase):

# NONE OF THE THREE PATCH WORK  Not in combination nor single
@mock.patch('greengrass_common')
@mock.patch('greengrass_common.function_arn_fields')
@mock.patch('greengrasssdk')
def test_that(self):
    pass

Контрольный пример пуст для упрощения.

Я ожидаю, что код greengrass_common будет существовать вне кода Greengrass, чтобы я мог написать модульные тесты.

Я из мира Java, но поговорил с несколькими разработчиками Python. Мы действительно не нашли решение. (За исключением попытки поймать импорт в производственном коде), но это кажется первым шагом к плохому качеству программного обеспечения во всем проекте.

Я очень благодарен за идеи / решения / подходы и руководство.

Большое спасибо:).

1 ответ

Я просто столкнулся с той же проблемой, и для меня это сработало, окружив импорт оператором try except.

try:
    import greengrasssdk
    client = greengrasssdk.client('iot-data')
except Exception as e:
    import boto3
    client = boto3.client('iot-data')

Вы можете условно импортировать greengrasssdk, если обнаружите, что работаете на Greengrass, и использовать boto3, если это не так. Я написал быстрые тесты, которые работают для меня здесь, которые выглядят так:

import socket
host = socket.gethostname()

client = None

# Create an IoT data client with Greengrass SDK on Greengrass, boto3 locally
if host == 'sandbox':
  import greengrasssdk
  client = greengrasssdk.client('iot-data')
else:
  import boto3
  client = boto3.client('iot-data')

По сути, проверьте, является ли имя хоста "песочницей", а затем используйте Greengrass SDK, в противном случае используйте boto3.

Была эта проблема и я использовал патчер в моем conftest.py файл для исправления поверх Greengrass SDK, например

conftest.py

import pytest
from mock import MagicMock, patch

MockGreengrassSdk = MagicMock()

modules = {
    "greengrasssdk": MockGreengrassSdk
}
patcher = patch.dict("sys.modules", modules)
patcher.start()

Как только вы определили MockGreengrassSdk как MagicMockзатем вы можете смоделировать любой метод, который хотите. Единственное, в чем я не уверен, - это то, как вы измените это для каждого теста, если вам нужны разные результаты от SDK для каждого теста.

Я нашел способ создать фасад над greengrasssdkна котором я затем могу высмеять методы. В этом случае этот фасад должен импортироватьgreengrasssdk Именно здесь приведенный выше код предотвратит сбой ваших тестов.

В итоге:

  1. Создайте фасад над greengrasssdk методы, которые вы хотите использовать.

  2. В фасаде импорт greengrasssdk.

  3. Используйте код патчера в conftest.py файл (как указано выше) для исправления Greengrass SDK.

Надеюсь, это поможет.

Другие вопросы по тегам