在 Nose 中伪造 time.time() 的时间戳
Faking a time stamp from time.time() in Nose
我正在构建一个设备对象以从 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 文件时,由于时间戳的原因,它总是失败。我可以通过添加测试标志在我的设备对象中将它分出,但我想知道 nose 是否有内置的方法来处理这样的问题,其中函数的结果可以用给定值或本地函数替换来伪造time.time()
电话。这可能吗?
您可以使用 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
尽管 mock
是 unittest
包的一部分,但它实际上是不相关的并且适用于任何测试框架。
对于 Python < 3.3,您可以使用 mock
package from PyPI.
这是从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.
测试的
您可以简单地将 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.
上测试
我正在构建一个设备对象以从 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 文件时,由于时间戳的原因,它总是失败。我可以通过添加测试标志在我的设备对象中将它分出,但我想知道 nose 是否有内置的方法来处理这样的问题,其中函数的结果可以用给定值或本地函数替换来伪造time.time()
电话。这可能吗?
您可以使用 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
尽管 mock
是 unittest
包的一部分,但它实际上是不相关的并且适用于任何测试框架。
对于 Python < 3.3,您可以使用 mock
package from PyPI.
这是从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.
测试的您可以简单地将 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.
上测试