最佳实践:自动化Web API测试

3
我已经用Python编写了一个程序,它使用两个不同的API与两个不同的服务(CKAN和MediaWiki)交互以获取数据。 特别地,有一个名为Resource的类,它请求上述服务的数据并对其进行处理。
在某个时刻,我得出结论,我的应用需要测试。问题是,我在网上和书中找到的所有示例都没有涉及这种情况。
例如,在Resource类中,我有一个方法:
def load_from_ckan(self):
    """
        Get the resource
        specified by self.id
        from config.ckan_api_url 
    """
    data = json.dumps({'id': self.id})
    headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
    url = config.ckan_api_url + '/action/resource_show'
    r = requests.post(url, timeout=config.ckan_request_timeout, data=data, headers=headers)
    assert r.ok, r
    resource = json.loads(r.content)
    resource = resource["result"]
    for key in resource:
        setattr(self, key, resource[key])
load_from_ckan 方法从 CKAN API 获取有关资源的数据并将其分配给对象。虽然它很简单,但是...
我的问题是:如何测试这样的方法?或者说,在这里应该测试什么?
我考虑过将结果保存到硬盘上(pickle),然后在测试中加载并与使用 load_from_ckan() 初始化的对象进行比较。但是 CKAN 是社区驱动的平台,这种测试行为将是不可预测的。
如果存在任何关于自动化测试哲学的书籍(例如要测试什么,不要测试什么,如何使测试有意义等),请给我一个链接。
3个回答

2

在任何测试中,关键问题实际上是——会发生什么问题?

在您的情况下,看起来有三个风险:

  • 涉及的Web API可能停止工作。但是,您已经通过assert r.ok检查了这一点。
  • 您或其他人可能会在将来对代码进行错误更改(例如,错别字变量),从而导致其出现故障。
  • API可能会更改,因此不再返回所需的字段或格式。

感觉您可以为后两者编写相当简单的测试,具体取决于您实际依赖于此API的数据:例如,如果您期望JSON具有名为“temperature”的字段,它是一个浮点摄氏度数字,则可以编写一个测试调用您的函数,然后检查self.temperature是否是'float'的实例,并且值在合理的范围内(-30到50?)。这应该让您确信API和您的函数都按照设计工作。


检查返回对象的属性是个好主意,谢谢!我将会检查这个对象是否包含了我后面在代码中使用的所有属性。 - Ivan Ermilov

1
通常,如果您想测试像这样的外部服务,则需要使用模拟/虚拟对象来模拟外部服务的api。这必须在运行时通过方法参数、类构造函数或其他类型的间接方式进行配置。另一个更复杂的选项是在测试期间猴子补丁全局变量,例如“import requests; request.post = fake_post”,但这可能会创建更多问题。
因此,例如,您的方法可以采用以下参数:
def load_from_ckan(self, post=requests.post):
    # ...
    r = post(url, timeout=config.ckan_request_timeout, data=data,
        headers=headers)
    # ...

在测试期间,您将编写自己的POST函数,返回从CKAN返回的JSON结果。例如:

 def mock_post(url, timeout=30, data='', headers=None):
     # ... probably check input arguments
     class DummyResponse:
         pass
     r = DummyResponse()
     r.ok = True
     r.content = json.dumps({'result': {'attr1': 1, 'attr2': 2}})
     return r

构建测试结果比将结果进行封存并返回更加灵活,因为您可以制造错误条件或聚焦于特定格式,而这些格式可能不在您的代码预期范围内,但您知道它们确实存在。
总体而言,您可以看到这可能会变得非常复杂,因此我建议只有在遇到重复错误或其他困难时才开始添加此类测试。这只会增加您需要维护的代码量。

0

此时,您可以测试是否正确解析了来自CKAN的响应。因此,您可以从CKAN中提取JSON并确保它返回您感兴趣的属性数据。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接