Как написать модульные тесты с файлами, которые прямо или косвенно `импортируют greengrasssdk` - PullRequest
0 голосов
/ 21 января 2019

Всякий раз, когда файл импортирует 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.Мы действительно не нашли решение.(За исключением попытки поймать импорт в производственном коде), но это кажется первым шагом к плохому качеству программного обеспечения во всем проекте.

Я очень благодарен за идеи / решения / подходы и рекомендации.

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

Ответы [ 3 ]

0 голосов
/ 10 мая 2019

Имелась и эта проблема, и используйте патчер в моем файле 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.

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

0 голосов
/ 05 июня 2019

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

try:
    import greengrasssdk
    client = greengrasssdk.client('iot-data')
except Exception as e:
    import boto3
    client = boto3.client('iot-data')
0 голосов
/ 12 февраля 2019

Вы можете импортировать 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.

...