2017-10-20 111 views
1

如果该对象不断变化,如何模拟返回的日期时间对象?py.test:嘲讽不断变化的日期时间对象

例如,我有一些代码查询API,获取一些时间序列数据并将其作为一系列日期时间对象返回。

因此,从查询API返回的数据看起来类似:

{ 
    'from_date': 1497881400000.0, 
       'group_by': [], 
       'message': '', 
       'query': 'avg:system.load.norm.5{role:lb}', 
       'res_type': 'time_series', 
       'resp_version': 1, 
       'series': [{'aggr': 'avg', 
            'attributes': {}, 
            'display_name': 'system.load.norm.5', 
            'end': 1497709799000, 
            'expression': 'avg:system.load.norm.5{role:lb}', 
            'interval': 1, 
            'length': 60, 
            'metric': 
            'avg:system.load.norm.5{role:lb}', 
            'pointlist': [[1497881400000.0, 
            0.06923198629355053], 
            [.. 60 more points]], 
            'query_index': 0, 
            'scope': 'role:lb', 
            'start': 1497709742000, 
            'unit': [None, None]}], 
       'status': 'ok', 
       'to_date': 1497709800000 
} 

和我的代码做到这一点:

from typing import NamedTuple 

class SampleMetric(NamedTuple): 
    query: str 
    time: datetime.datetime 
    value: int 

pointlist = api_query['series'][0]['pointlist'] 
return [SampleMetric(query=metric, 
          time=datetime.datetime.fromtimestamp(
           point[0]/1000), 
          value=point[1]) for point in pointlist] 

这在上述API数据的情况下会是这个样子:

[SampleMetric(query='avg:system.load.norm.5{role:lb}', time=datetime.datetime(2017, 10, 20, 11, 2), value=231.8605833053589), 
SampleMetric(query='avg:system.load.norm.5{role:lb}', time=datetime.datetime(2017, 10, 20, 11, 3), value=243.17432022094727),...] 

因此,我可以很容易地创建一个模拟api对象,返回一个字典作为我们的e xample在上面做了,但我真的很努力地模拟返回的日期时间对象。

time=datetime.datetime(2017, 10, 20, 11, 2)

谁能给我如何做到这一点,请任何想法?目前我已经解决了这个问题,只有一个时间点指向我的返回数据并对时间值进行了硬编码,但我认为这不是真正的世界测试,因为它应该返回60个结果。

忽略在这个例子中使用的实际值,我知道他们是错误的,但这只是为了说明的目的,因为我努力解释我的意思。

+0

如果您可以给出您想要测试的一些简单代码的具体示例,并描述测试难写的原因,那么您会得到更有帮助的答案。我猜想你的意思,但我不确定。 –

回答

1

我不确定你的意思是什么“不断变化”,所以我会采取两个猜测,并回答他们两个。

我的第一个猜测是你想知道当结果取决于当前时间时如何编写单元测试。这使得输出不断变化,所以测试很难写。

为了解决这个问题,我将当前时间作为明确的输入参数传递给我正在测试的代码,或者我嘲笑datetime.now()方法。这样,单元测试总是基于同一时间进行计算,并且应该始终得到相同的结果。这也使得测试有趣的边缘情况变得更加容易,例如夏令时的变化。您可以为每个有趣的场景分别编写一个单独的测试用例,每个用户都有不同的“当前时间”。

我的第二个猜测是,你问如何为你的输入数据创建一组60个不同的日期时间值。我可能会计算前几个条目的一些有趣值,然后用for循环或range()表达式生成剩余的值。