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 获取有关资源的数据并将其分配给对象。这很简单,但是...

我的问题是:如何测试这样的方法?或者我应该在这里测试什么?

我考虑了将结果腌制(保存)到硬盘的可能性。然后我可以在测试中加载它并与用 load_from_ckan() 初始化的对象进行比较。但 CKAN 是社区驱动的平台,此类测试的这种行为将是不可预测的。

如果有任何关于自动化测试哲学的书籍(比如测试什么,不测试什么,如何使测试有意义等),请给我一个链接。

4

3 回答 3

2

对于任何测试,关键问题确实是 -出什么问题?

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

  • 有问题的 Web API 可能会停止工作。但是您已经使用assert r.ok.
  • 您或其他人可能会在将来对代码进行错误更改(例如错误输入变量),这会破坏它。
  • API 可能会更改,因此它不再返回您需要的字段或格式。

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

于 2013-02-06T23:49:28.173 回答
1

通常,如果您想针对此类外部服务进行测试,您将需要使用模拟/虚拟对象来伪造外部服务的 api。这必须在运行时通过方法的参数或类的构造函数或其他类型的间接进行配置。另一个更复杂的选择是在测试期间对全局变量进行修补,例如“导入请求;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

Constructing the result in your test gives you a lot more flexibility than pickling results and returning them because you can fabricate error conditions or focus in on specific formats your code might not expect but you know could exist.

Overall you can see how complicated this could become so I would only start adding this sort of testing if you are experiencing repeated errors or other difficulties. This will just more code you have to maintain.

于 2013-02-07T00:08:04.263 回答
0

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

于 2013-02-06T23:45:35.600 回答