python - 如何测试使用请求的复杂功能?
问题描述
我想测试基于其他人创建的 API 的代码,但我不确定我应该怎么做。
我创建了一些函数来将 json 保存到文件中,因此我不需要每次运行测试时都发送请求,但是我不知道如何在原始(检查)函数接受输入 arg 的情况下使其工作(problem_report) 是 API 提供的某个类的一个实例,它有这个 issue_report.get_correction(corr_link)方法。我只是想知道这是否是我编写错误代码的标志,因为我无法为此编写测试,或者我应该在我的测试文件中重写这个函数,就像我在下面提供的代码末尾显示的那样。
# I to want test this function
def check(problem_report):
corrections = {}
for corr_link, corr_id in problem_report.links.items():
if re.findall(pattern='detailCorrection', string=corr_link):
correction = problem_report.get_correction(corr_link)
corrections.update({corr_id: correction})
return corrections
# function serves to load json from file, normally it is downloaded by API from some page.
def load_pr(pr_id):
print('loading')
with open('{}{}_view_pr.json'.format(saved_prs_path, pr_id)) as view_pr:
view_pr = json.load(view_pr)
...
pr_info = {'view_pr': view_pr, ...}
return pr_info
# create an instance of class MyPR which takes json to __init__
@pytest.fixture
def setup_pr():
print('setup')
pr = load_pr('123')
my_pr = MyPR(pr['view_pr'])
return my_pr
# test function
def test_check(setup_pr):
pr = setup_pr
checked_pr = pr.check(setup_rft[1]['problem_report_pr'])
assert checker_pr
# rewritten check function in test file
@mock.patch('problem_report.get_correction', side_effect=get_corr)
def test_check(problem_report):
corrections = {}
for corr_link, corr_id in problem_report.links.items():
if re.findall(pattern='detailCorrection', string=corr_link):
correction = problem_report.get_correction(corr_link)
corrections.update({corr_id: correction})
return corrections
我不确定我是否提供了足够的代码和解释来理解问题,但我希望如此。我希望你能告诉我这是否正常,某些函数很难测试,如果这是单独重写它们的好习惯,那么我可以在测试函数中模拟函数。我还想我可以编写具有类似功能的新类,但 API 非常大,而且过程会很长。
解决方案
我对您的问题的理解如下:您有一个check
您认为难以测试的功能,因为它依赖于problem_report
. 为了使其更好地可测试,您已将代码复制到测试文件中。您将测试复制的代码,因为您可以将其修改为更易于测试。而且,您想知道这种方法是否有意义。
答案是否定的,这没有意义。您不是在测试真正的功能,而是完全不同的代码。好吧,代码可能不会开始完全不同,但在短时间内副本和原件会出现偏差,确保副本始终与原件相似将是维护的噩梦。改进代码的可测试性是另一回事:您可以对check
函数进行更改以提高其可测试性。但是,在测试和生产代码中都应该使用完全相同的结果函数。
那么如何更好地测试功能check
呢?首先,您确定使用原始problem_report
对象真的不能在您的测试中合理使用吗?(这里有一些标准可以帮助您决定:python 测试用例要模拟什么?)。现在,让我们假设您得出的结论是您不能明智地使用原始problem_report
.
在这种情况下,这里的接口很简单,可以定义一个 mocked problem_report
。请记住,Python 使用鸭子类型,因此您只需创建一个具有成员的类,该links
成员具有items()
方法。另外,您的模拟problem_report
类需要一个方法get_correction()
。除此之外,您的模拟不必生成与problem_report
. 该items()
方法可以简单地返回一个列表列表,例如[["a",2],["xxxxdetailCorrectionxxxx",4]]
. 相同的参数适用于get_correction
,例如,它可以简单地返回它的参数或派生值,比如它的负数。
对于上面的示例(items()
返回[["a",2],["xxxxdetailCorrectionxxxx",4]]
并get_correction
返回其参数的负数),预期结果将是{4: -4}
. 无需模拟真实correction
物体。而且,您可以创建您的模拟版本,problem_report
而无需从文件中读取数据 - 模拟可以完全从单元测试代码中设置。
推荐阅读
- c# - 寻求 C# ASP.NET Core Web App 项目的帮助
- docker - 在 docker 上等待用户输入 golang cli app
- css - 针对移动设备的 GridView CSS 更改
- javascript - 如何将图像的响应高度或宽度添加到容器中?
- azure - Azure CDN 规则引擎将 www 添加到裸域
- javascript - 尝试使用 React-Router-Dom 时出现问题
- javascript - 将 div 移动到另一个 div
- django - 没有错误消息,使用 slug 和 get_absolut_url() 重定向到 DetailView
- angular - SwaggerUI windows 身份验证流程
- python - pybuilder:构建失败,在测试用例中报告错误