Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/277.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 当行为不容易定义时,如何对函数进行单元测试?_Python_Python 2.7_Unit Testing_Python Unittest - Fatal编程技术网

Python 当行为不容易定义时,如何对函数进行单元测试?

Python 当行为不容易定义时,如何对函数进行单元测试?,python,python-2.7,unit-testing,python-unittest,Python,Python 2.7,Unit Testing,Python Unittest,我有一个方法来计算两次之间ms的数量 def time_diff(orig_time): return int((time.time() - orig_time) * 1000) 其用途类似于: orig = time.time() # do stuff time_duration = time_diff(orig) 我理解,从可重复性的角度来看,这并不一定理想,因为time.time() 从实用的角度来看,这个函数已经足够好了。我不需要精确,我知道我失去了精确性 然而,我的问题是当

我有一个方法来计算两次之间ms的数量

def time_diff(orig_time):
    return int((time.time() - orig_time) * 1000)
其用途类似于:

orig = time.time()
# do stuff
time_duration = time_diff(orig)
我理解,从可重复性的角度来看,这并不一定理想,因为
time.time()

从实用的角度来看,这个函数已经足够好了。我不需要精确,我知道我失去了精确性

然而,我的问题是当我去测试依赖于此功能的服务时

看来我有几个选择:

class ReportingTest(TestCase):

    def test_time_diff_badly(self):
        # this approach is bad and I should not even consider it

        orig = time.time()

        self.assertEqual(
            time_diff(orig),
            0)

    @patch('time.time')
    def test_time_diff_mocked(self, time_mock):
        time_mock.return_value = 0

        self.assertEqual(
            time_diff(0.0015),
            1.5)

    def test_time_diff_threshold(self):        
        orig = time.time()
        dt = time_diff(orig)

        self.assertLessEqual(dt, 0.10)
        self.assertGreaterEqual(dt, 0)
第一个显然是坏的。我没有什么价值可以持续回报。模仿似乎是可行的,基于阈值的方法也是可行的。不过我并不真的喜欢嘲笑,因为如果我这样做的话,编写测试似乎有点毫无意义


有没有更好的方法来测试这个函数?

没有单元测试来发现bug;它的存在是为了捕捉以后引入的bug。如果你的测试看起来很琐碎,不要担心

以下是一些改进当前测试的方法:

  • 不要假设调用了
    time.time()
    。这是当前测试所依赖的一个实现细节,因此请采取措施确保 如果这种情况发生变化,你的测试就会失败

    time_mock.assert_called()
    
    根据模拟的内容,您可能希望验证调用它的次数,或者用什么参数调用它,但这样做的目的是在基本假设发生变化时尝试使测试失败

  • 使用不同的返回值编写多个测试。特别是在这种情况下,
    time.time()
    永远不会两次返回同一个值,因此请尝试预测它可能返回哪些可能导致问题的值类。例如,您假设
    time.time()
    将返回一个大于
    orig\u time
    的值,但它可能不会返回


  • 单元测试不存在以发现bug;它的存在是为了捕捉以后引入的bug。如果你的测试看起来很琐碎,不要担心

    以下是一些改进当前测试的方法:

  • 不要假设调用了
    time.time()
    。这是当前测试所依赖的一个实现细节,因此请采取措施确保 如果这种情况发生变化,你的测试就会失败

    time_mock.assert_called()
    
    根据模拟的内容,您可能希望验证调用它的次数,或者用什么参数调用它,但这样做的目的是在基本假设发生变化时尝试使测试失败

  • 使用不同的返回值编写多个测试。特别是在这种情况下,
    time.time()
    永远不会两次返回同一个值,因此请尝试预测它可能返回哪些可能导致问题的值类。例如,您假设
    time.time()
    将返回一个大于
    orig\u time
    的值,但它可能不会返回


  • 您可以将函数定义为
    def time\u diff(orig\u time,end\u time):
    并在代码中将end\u time传递为
    time.time()
    ,但在测试中作为固定值传递end time作为可选参数可能更好:
    def time\u diff(orig\u time,end\u time=None)
    --这避免了编辑所有调用它的代码。您可以将函数定义为
    def time\u diff(orig\u time,end\u time):
    并在代码中将end\u time传递为
    time.time()
    ,但在测试中作为固定值,最好将end time作为可选参数传递:
    def time\u diff(orig_time,end_time=None)
    ——这避免了编辑调用它的所有代码。