处理用Python进行NumPy测试的断言

时间:2018-12-07 08:05:07

标签: python unit-testing numpy exception assert

了解某人的代码并满足此要求:

有一个功能:

 def some_func():
       print("Hello")
       assert(len(y)==len(p))
       print("First assert")
       assert(p.all()<=0.99999)
       print("Second assert")
       return 1

接下来,致电assert_raises:

np.testing.assert_raises(AssertionError, some_func, np.asarray([1, 2, 3]), np.asarray([1, 2, 3, 4, 5]))

在输出中,我们只是获得Hello,而没有异常消息:

Hello

接下来,调用函数assert_array_less:

np.testing.assert_array_less(some_func(np.asarray([1, 2, 3]), np.asarray([1, 2, 3])), np.inf)

在输出中,我们得到Hello First断言,然后是错误消息和AssertionError异常:

Hello
First assert
---------------------------------------------------------------------------
AssertionError  Traceback (most recent call last)
<ipython-input-26-df1a32b4f5a0> in <module>()
      9 np.testing.assert_raises(AssertionError, some_func, np.asarray([1, 2, 3]), np.asarray([1, 2, 3, 4, 5]))
     10 
---> 11 np.testing.assert_array_less(some_func(np.asarray([1, 2, 3]), np.asarray([1, 2, 3])), np.inf)

<ipython-input-26-df1a32b4f5a0> in some_func(a, b)
      3     assert(len(a)==len(b))
      4     print("First assert")
----> 5     assert(a.all()<=0.99999)
      6     print("Second assert")
      7     return 1

AssertionError: 

问题:

为什么在1种情况下,尽管在some_func()中首先调用了断言,但代码只是停止并且没有引发异常?

为什么第二个与第一个不一样,并抛出异常?

1 个答案:

答案 0 :(得分:1)

根据您显示的错误消息,我猜您的some_func函数的实际定义是:

def some_func(a, b):
    print("Hello")
    assert(len(a)==len(b))
    print("First assert")
    assert(a.all()<=0.99999)
    print("Second assert")
    return 1

鉴于此,这是您assert通话期间发生的情况的确切摘要:

  • 您致电

    np.testing.assert_raises(AssertionError, some_func, np.asarray([1, 2, 3]), np.asarray([1, 2, 3, 4, 5]))
    
    • np.testing.assert_raises函数依次调用

      some_func(np.asarray([1, 2, 3]), np.asarray([1, 2, 3, 4, 5]))
      
      • 运行some_func的第一行,并显示Hello
      • 接下来,some_func试图断言ab的长度是相同的。但是,a的长度为3,b的长度为5,因此断言失败。这导致抛出AssertionError。此时,some_func的执行终止,控制权返回到assert_raises
    • assert_raises通过传递给它的第一个参数被告知期望AssertionError。它认为确实抛出了AssertionError,因此从它的角度来看一切都很好。它处理AssertionError(防止它创建将向用户显示的错误消息),并且assert_raises的执行正常结束。
  • 下一次致电

    np.testing.assert_array_less(some_func(np.asarray([1, 2, 3]), np.asarray([1, 2, 3])), np.inf)
    
    • 再次运行some_func的第一行并显示Hello
    • 这次len(a)==len(b)==3,所以assert通过了,some_func的执行正常地继续进行。
    • 接下来运行some_func的第三行并显示First assert
    • a中的每个值都不为零,因此a.all()True。布尔值True的数字值为1。因此,a.all()<=0.99999False,因此assert失败。此时,将引发AssertionError,并终止some_func的执行。
  • 这次,some_func在顶级范围内运行(如果成功完成,则将调用np.testing.assert_array_less并将返回值some_func传递给它)。与上次调用some_func不同的是,没有任何封闭函数可以处理提出的AssertionError。这意味着AssertionError将传播并产生可见的错误消息,该错误消息将被打印在First assert下面。

这就是整个故事。