错误:找不到:(使用Moto,Boto3和Python进行python测试没有名称
目前,在我的本地计算机上的Python文件上运行测试很难将其部署到AWS(我只想在本地计算机上运行测试)。
使用Unitest,Boto3,Moto和Pytest实施了测试。
2个文件包含在同一目录中,称为
正在测试的主文件(lambda_function.py) 测试文件(test_api_login.py)
查看错误输出 编辑
/usr/bin/python3 "/Applications/PyCharm CE.app/Contents/plugins/python-ce/helpers/pycharm/_jb_pytest_runner.py" --target test_api_login.py::test_login_to_api
Testing started at 12:24 PM ...
Launching pytest with arguments test_api_login.py::test_login_to_api --no-header --no-summary -q in /Users/myk/Documents/DUMP/apiLogin
============================= test session starts ==============================
collecting ... collected 1 item
test_api_login.py::test_login_to_api::test_my_test FAILED [100%]
test_api_login.py:16 (test_login_to_api.test_my_test)
moto/core/models.py:118: in wrapper
result = func(*args, **kwargs)
/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/unittest/mock.py:1322: in patched
with self.decoration_helper(patched,
/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/contextlib.py:113: in __enter__
return next(self.gen)
/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/unittest/mock.py:1304: in decoration_helper
arg = exit_stack.enter_context(patching)
/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/contextlib.py:425: in enter_context
result = _cm_type.__enter__(cm)
/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/unittest/mock.py:1377: in __enter__
self.target = self.getter()
/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/unittest/mock.py:1552: in <lambda>
getter = lambda: _importer(target)
/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/unittest/mock.py:1224: in _importer
thing = __import__(import_path)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
import requests
import json
import boto3
ssm = boto3.client('ssm', region_name="us-east-1")
base_url_obj = ssm.get_parameters(Names=["/prof-svc-int/dev/api-base-url"])
> BASE_URL = base_url_obj['Parameters'][0]['Value']
E IndexError: list index out of range
lambda_function.py:8: IndexError
============================== 1 failed in 3.28s ===============================
Process finished with exit code 1
请参见要测试的主文件的代码(lambda_function.py)
import requests
import json
import boto3
ssm = boto3.client('ssm', region_name="us-east-1")
base_url_obj = ssm.get_parameters(Names=["/prof-svc-int/dev/api-base-url"])
BASE_URL = base_url_obj['Parameters'][0]['Value']
username_obj = ssm.get_parameters(Names=["/prof-svc-int/dev/api-username"])
USERNAME = username_obj['Parameters'][0]['Value']
password_obj = ssm.get_parameters(Names=["/prof-svc-int/dev/api-password"])
PASSWORD = password_obj['Parameters'][0]['Value']
def lambda_handler(event, context):
username = USERNAME
password = PASSWORD
message = ''
code = 400
headers = {"Accept": "application/json", "Content-Type": "application/json"}
try:
url = f"{BASE_URL}v0/login"
data = {"username": username, "password": password}
r = requests.post(url, headers=headers, data=json.dumps(data))
message = r.json()
except Exception as e:
message += f'An error occurred {str(e)}'
if "token" in message:
token = message['token']
print("token >> " + token)
put_response = ssm.put_parameter(
Name='/prof-svc-int/dev/api-token',
Value=token,
Type='String',
Overwrite=True
)
print("put_response >> ", put_response)
code = 200
output = OutputObj(code,
message)
json_str = json.dumps(output.__dict__)
result = json.loads(json_str)
return result
class OutputObj:
def __init__(self, statusCode, body):
self.statusCode = statusCode
self.body = body
请参阅test文件的代码(test_api_login.py) 编辑
import unittest
from unittest.mock import patch
from moto import mock_ssm
@mock_ssm
@patch("lambda_function.lambda_handler.base_url_obj")
@patch("lambda_function.lambda_handler.BASE_URL")
@patch("lambda_function.lambda_handler.username_obj")
@patch("lambda_function.lambda_handler.USERNAME")
@patch("lambda_function.lambda_handler.password_obj")
@patch("lambda_function.lambda_handler.PASSWORD")
class test_login_to_api(unittest.TestCase):
@mock_ssm
def test_my_test(self):
with patch('lambda_function.lambda_handler') as mock_post:
mock_post.return_value.statusCode = 200
out = mock_post
code = out.code
self.assertEqual(code, 200)
if __name__ == "__main__":
unittest.main()
Currently having difficulty running tests on a python file on my local machine meant to be deployed to AWS(I want to run the tests only on my local machine).
The tests were implemented using unittest, boto3, moto and pytest.
2 files are contained in the same directory called
Main file being tested (lambda_function.py)
Test File (test_api_login.py)
See the errors output
EDITED
/usr/bin/python3 "/Applications/PyCharm CE.app/Contents/plugins/python-ce/helpers/pycharm/_jb_pytest_runner.py" --target test_api_login.py::test_login_to_api
Testing started at 12:24 PM ...
Launching pytest with arguments test_api_login.py::test_login_to_api --no-header --no-summary -q in /Users/myk/Documents/DUMP/apiLogin
============================= test session starts ==============================
collecting ... collected 1 item
test_api_login.py::test_login_to_api::test_my_test FAILED [100%]
test_api_login.py:16 (test_login_to_api.test_my_test)
moto/core/models.py:118: in wrapper
result = func(*args, **kwargs)
/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/unittest/mock.py:1322: in patched
with self.decoration_helper(patched,
/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/contextlib.py:113: in __enter__
return next(self.gen)
/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/unittest/mock.py:1304: in decoration_helper
arg = exit_stack.enter_context(patching)
/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/contextlib.py:425: in enter_context
result = _cm_type.__enter__(cm)
/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/unittest/mock.py:1377: in __enter__
self.target = self.getter()
/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/unittest/mock.py:1552: in <lambda>
getter = lambda: _importer(target)
/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/unittest/mock.py:1224: in _importer
thing = __import__(import_path)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
import requests
import json
import boto3
ssm = boto3.client('ssm', region_name="us-east-1")
base_url_obj = ssm.get_parameters(Names=["/prof-svc-int/dev/api-base-url"])
> BASE_URL = base_url_obj['Parameters'][0]['Value']
E IndexError: list index out of range
lambda_function.py:8: IndexError
============================== 1 failed in 3.28s ===============================
Process finished with exit code 1
See the code for the main file being tested (lambda_function.py)
import requests
import json
import boto3
ssm = boto3.client('ssm', region_name="us-east-1")
base_url_obj = ssm.get_parameters(Names=["/prof-svc-int/dev/api-base-url"])
BASE_URL = base_url_obj['Parameters'][0]['Value']
username_obj = ssm.get_parameters(Names=["/prof-svc-int/dev/api-username"])
USERNAME = username_obj['Parameters'][0]['Value']
password_obj = ssm.get_parameters(Names=["/prof-svc-int/dev/api-password"])
PASSWORD = password_obj['Parameters'][0]['Value']
def lambda_handler(event, context):
username = USERNAME
password = PASSWORD
message = ''
code = 400
headers = {"Accept": "application/json", "Content-Type": "application/json"}
try:
url = f"{BASE_URL}v0/login"
data = {"username": username, "password": password}
r = requests.post(url, headers=headers, data=json.dumps(data))
message = r.json()
except Exception as e:
message += f'An error occurred {str(e)}'
if "token" in message:
token = message['token']
print("token >> " + token)
put_response = ssm.put_parameter(
Name='/prof-svc-int/dev/api-token',
Value=token,
Type='String',
Overwrite=True
)
print("put_response >> ", put_response)
code = 200
output = OutputObj(code,
message)
json_str = json.dumps(output.__dict__)
result = json.loads(json_str)
return result
class OutputObj:
def __init__(self, statusCode, body):
self.statusCode = statusCode
self.body = body
See the code for test File (test_api_login.py)
EDITED
import unittest
from unittest.mock import patch
from moto import mock_ssm
@mock_ssm
@patch("lambda_function.lambda_handler.base_url_obj")
@patch("lambda_function.lambda_handler.BASE_URL")
@patch("lambda_function.lambda_handler.username_obj")
@patch("lambda_function.lambda_handler.USERNAME")
@patch("lambda_function.lambda_handler.password_obj")
@patch("lambda_function.lambda_handler.PASSWORD")
class test_login_to_api(unittest.TestCase):
@mock_ssm
def test_my_test(self):
with patch('lambda_function.lambda_handler') as mock_post:
mock_post.return_value.statusCode = 200
out = mock_post
code = out.code
self.assertEqual(code, 200)
if __name__ == "__main__":
unittest.main()
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
导入文件时,对
ssm.get_parameters
进行了执行。但是
mock_ssm
仅在之后开始,并且仅在测试期间处于活动状态。绝对确定boto3/ssm方法正确模拟的一种方法是在模拟函数内导入
lambda_function
:这将确保呼叫
ssm.get_parameters
在模拟处于活动状态时执行。请注意,就目前而言,您仍然会遇到SSM参数不存在的问题。作为测试的一部分,您必须先创建这些参数(使用
boto3.client(..)。put_parameter
)才能读取。The call to
ssm.get_parameters
is executed the moment the file is imported.But
mock_ssm
only starts afterwards, and is only active for the duration of the test.One way to be absolutely sure that the boto3/SSM-methods are mocked correctly, is to import the
lambda_function
inside the mocked function:This will ensure that the call to
ssm.get_parameters
is executed while the mock is active.Note that, as it stands, you'll still run into the problem that the SSM parameters do not exist. As part of your tests, you would have to create these parameters first (using
boto3.client(..).put_parameter
) before they can be read.