无论何时导入文件import greengrasssdk
,单元测试都会失败,因为模块greengrass_common
在我的本地计算机上不存在,并且我无法通过pip进行安装。
我正在使用PyCharm执行测试。我尝试测试的Greengrass lambda由于相同的依存关系问题(相同的异常)未在本地执行。但是,只要将lambda推入草丛中,它就可以正常工作。
这里是例外:
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开发人员交谈。我们没有真正找到解决方案。 (除了尝试在生产代码中捕获导入),但这似乎是整个项目中不良软件质量的第一步。
我非常感谢您的想法/解决方案/方法和指导。
非常感谢:)。
答案 0 :(得分: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')
基本上检查主机名是否报告为“ sandbox”,然后使用Greengrass SDK,否则使用boto3。
答案 1 :(得分: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
定义为MagicMock
之后,您就可以模拟出要使用的任何方法。我唯一不确定的是,如果您希望每个测试的SDK结果不同,您将如何更改每个测试的结果。
解决这个问题的方法是在greengrasssdk
上创建一个立面,然后可以在其上模拟方法。在这种情况下,facade必须导入greengrasssdk
,这是上面的代码将阻止测试失败的地方。
总结:
在要使用的greengrasssdk
方法上创建外观。
在外观中导入greengrasssdk
。
使用conftest.py
文件中的修补程序代码(如上所述)通过Greengrass SDK进行修补。
希望有帮助。
答案 2 :(得分:0)
我只是遇到了同样的问题,对我来说,它通过使用tryexcept语句将导入包围起来。
try:
import greengrasssdk
client = greengrasssdk.client('iot-data')
except Exception as e:
import boto3
client = boto3.client('iot-data')