下载安卓APP箭头
箭头给我发消息

客服QQ:3315713922
论坛 >编程语言 >提高你的Python能力:理解单元测试 (下)

提高你的Python能力:理解单元测试 (下)

希尔瓦娜斯发布于 2018-01-17 10:29查看:739回复:1

解决问题

一次失败的测试使我们修改了代码。一旦我们改好了这个错误(将s_prime中的一行改为for element in range(2, number):),我们就得到了如下输出:

image.png

现在错误已经改了,这是不是意味着我们应该删掉test_is_five_prime这个测试方法(因为很明显,它将不会一直能通过测试)?不应该删。由于通过测试是最终目标的话单元测试应该尽量少的被删除。我们已经测试过is_prime的语法是有效的,并且,至少在一种情况下,它返回正确的结果。我们的目标是要建立一套能全部通过的(单元测试的逻辑分组)测试,虽然有些一开始可能会失败。

test_is_five_prime用于处理一个“非特殊”的素数。让我们确保它也能正确处理非素数。将以下方法添加到PrimesTestCase类:

image.png

请注意,这时我们给assert调用添加了可选的msg参数。如果该测试失败了,我们的信息将被打印到控制台,并给运行测试的人提供额外的信息。

边界情况

我们已经成功的测试了两种普通情况。现在让我们考虑边界情况下、或者那些不寻常或意外的输入的用例。当测试一个其范围是正整数的函数时,边界情况下的实例包括0、1、负数和一个很大的数字。现在让我们来测试其中的一些。

添加一个对0的测试很简单。我们预计?is_prime(0)返回的是false,因为,根据定义,素数必须大于1。

image.png

可惜呀,输出是:

image.png

0被错误的判定为素数。我们忘记了,我们决定在数字范围中跳过0和1。让我们增加一个对他们的特殊检查。

image.png

现在测试通过了。我们的函数应该怎样处理一个负数?在写这个测试用例之前就知道输出结果是很重要的。在这种情况下,任何负数都应该返回false。

image.png

这里我们觉得检查从-1到-9的所有数字。在一个循环中调用test方法是非常合法的,在一个测试中多次调用断言方法也可以。我们可以在下面用(更详细)的方式改写代码。

image.png

这两个是完全等价的。除了当我们运行循环版本时,我们得到了一个我们不太想要的信息:

image.png

嗯···我们知道测试失败了,但是是在哪个负数上失败的?非常没用的是,Python的单元测试框架并没有打印出预期值和实际值。我们可以移步到两种方式上,并用其中之一来解决问题:通过msg参数,或通过使用一个第三方的单元测试框架。

使用msg参数来assertFalse仅仅能够使我们认识到我们可以用字符串的格式设置来解决问题。

image.png

从而给出了如下输出信息:

image.png

妥善地修复代码

我们看到,失败的负数是第一个数字:-1。为了解决这个问题,我们可以为负数增再增加一个特殊检查,但是编写单元测试的目的不是盲目的添加代码来检测边界情况。当一个测试失败时,我们应该退后一步并且确定解决问题的最佳方式。在这种情况下,我们就不该增加一个额外的if:

image.png

应当首先使用如下代码:

image.png

在后一个代码中,我们发现如果参数小于等于1时,两个if语句可以合并到一个返回值为false的语句中。这样做不仅更加简洁,并且很好的贴合了素数的定义(一个比1大并且只能被1和它本身整除的数)。

第三方测试框架

我们本来也可以通过使用第三方测试框架解决这个由于信息太少导致测试失败的问题。最常用的两个是py.test和nose。通过运行语句py.test -l(-l为显示局部变量的值)可以得到如下结果。

image.png

正如你所看到的,一些更有用的信息。这些框架提供了比单纯的更详细的输出更多的功能,但问题是仅仅知道它们能存在和扩展内置unittest测试包的功能。


收藏(0)0
查看评分情况

全部评分

此主贴暂时没有点赞评分

总计:0

回复分享

版主推荐

    共有1条评论

    • IT宅男
    • mr jack
    • Mr ken
    • Mright
    • cappuccino
    • YUI
    • 课课家运营团队
    • 课课家技术团队1
    • 酸酸~甜甜
    • 选择版块:

    • 标题:

    • 内容

    • 验证码:

    • 标题:

    • 内容

    • 选择版块:

    移动帖子x

    移动到: