2

每当导入文件import greengrasssdk时,单元测试都会失败,因为该模块greengrass_common在我的本地计算机上不存在,我无法通过 pip 安装它。

我正在使用 PyCharm 执行测试。由于相同的依赖问题(相同的异常),我尝试测试的 Greengrass lambda 不会在本地执行。但是一旦将 lambda 推到 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 开发人员交谈过。我们并没有真正找到解决方案。(除了尝试在生产代码中捕获导入),但这似乎是整个项目中软件质量不佳的第一步。

我非常感谢想法/解决方案/方法和指导。

非常感谢 :)。

4

3 回答 3

0

我刚刚遇到了同样的问题,对我来说,它通过使用 try except 语句包围导入来工作。

try:
    import greengrasssdk
    client = greengrasssdk.client('iot-data')
except Exception as e:
    import boto3
    client = boto3.client('iot-data')
于 2019-06-05T08:31:28.963 回答
0

也有这个问题,并使用我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为 a MagicMock,你就可以模拟出你想要的任何方法。我唯一不确定的是,如果您希望每次测试从 SDK 获得不同的结果,您将如何更改每次测试。

我解决这个问题的方法是创建一个外观,greengrasssdk然后我可以在其上模拟方法。在这种情况下,外观必须导入greengrasssdk,上面的代码将阻止您的测试失败。

总之:

  1. greengrasssdk在您要使用的方法上创建一个外观。

  2. 在门面导入greengrasssdk.

  3. 使用conftest.py文件中的修补程序代码(如上)修补 Greengrass SDK。

希望有帮助。

于 2019-05-10T12:16:03.893 回答
0

如果您检测到您正在 Greengrass 上运行,则可以有条件地导入 greengrasssdk,如果不是,则使用 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。

于 2019-02-12T20:42:21.437 回答