【问题标题】:Faking a time stamp from time.time() in Nose在 Nose 中从 time.time() 伪造时间戳
【发布时间】:2016-03-03 21:51:59
【问题描述】:

我正在构建一个设备对象来轮询来自 python 中连接设备的数据,并且我正在尝试使用nose 测试对象的交互作用及其所有功能。在使用time.time() 编写时间戳时,我通常会遇到一个问题,因为每次调用函数时,结果值都是不同的,这严重破坏了一些测试,例如这个数据收集函数:

def getData(self, data):
    if type(data) is not type({}):
        #print "Bad Type!"
        raise TypeError
    else:
        #print "Good Type!"
        self.outD = {}
        datastr = ""
        for key, value in data.iteritems():
            self.outD[key] = value
        self.outD["timestamp"] = time.time()
        self.outD["id"] = self.id
        self._writeCSV()

当我测试这个函数的输出并比较生成的 CSV 文件时,它总是由于时间戳而失败。我可以通过添加测试标志在我的设备对象中将它分出来,但我想知道鼻子是否有内置的方法来处理这样的问题,其中函数的结果可以用给定值或本地函数替换来伪造time.time() 电话。这可能吗?

【问题讨论】:

    标签: python unit-testing timestamp nose


    【解决方案1】:

    您可以使用unittest.mock。示例:

    import time
    from unittest import mock
    
    @mock.patch('time.time', mock.MagicMock(return_value=12345))
    def test_something():
        assert time.time() == 12345
    

    产生以下输出:

    $ nosetests3 -v
    test.test_something ... ok
    
    ----------------------------------------------------------------------
    Ran 1 test in 0.006s
    
    OK
    

    尽管mockunittest 包的一部分,但它实际上是无关的并且适用于任何测试框架。

    对于 Python mock package from PyPI。

    【讨论】:

    • 如果可能的话,我宁愿坚持只用鼻子。
    • @Dom:你仍然可以使用鼻子。我的例子是鼻子。如果您只想使用鼻子,那么答案是“你不能”或“编写自己的模拟模块”
    【解决方案2】:

    这是从 A.C. 先前的答案中得出的。没有必要显式创建MagicMock。其次,还必须断言 mock 的用途以证明其用途。

    import time
    import unittest.mock
    
    @unittest.mock.patch('time.time', return_value=12345)
    def test_foo(mock_time):
        assert time.time() == 12345
        mock_time.assert_called_once()
    

    这是用 Python 3.7 测试的。

    【讨论】:

    • 我不相信“模拟的使用也必须被断言”。当然可能是,并且取决于可能重要的测试,但如果不是,测试不会失败。
    【解决方案3】:

    您可以简单地将 time.time() 函数分配给您自己的函数,并使用您自己的函数以适当的方式定义时间:

    time.time = my_time_function
    

    分配给自己的函数可以在单元测试开始时发生,而在结束时会再次恢复原始函数:

    class MyTests(unittest.TestCase):
        def get_time(self):
            return self.emulated_time
    
        def setUp(self):
            # Define the emulated time
            self.emulated_time = time.mktime(
                    time.strptime("2020-01-18 02:02:05", "%Y-%m-%d %H:%M:%S"))
    
            # Register the time.time function and patch it then
            self.time_method = time.time
            time.time = self.get_time
    
        def tearDown(self):
            # Restore the time.time function
            time.time = self.time_method
        
        def test_time_span(self):
            # Register the start time, do something, emulate a time update of 1
            # second, and check that the execution duration is one second
            start_time = time.time()
            # <do something here>
            self.emulated_time += 1
            self.assertEqual(time.time(), start_time+1)
    

    此示例在 Python 3.6.8 上进行了测试。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-07-06
      • 2014-09-19
      • 1970-01-01
      • 2021-12-17
      • 2019-08-02
      • 2013-05-09
      • 2018-05-25
      相关资源
      最近更新 更多