什么是在python中测试if-elif-else条件的有效方法

时间:2015-02-06 21:51:23

标签: python if-statement testing

我有一堆需要评估的python程序。该程序的基本框架包含一堆嵌套的If-elif-else语句。我想知道,测试(生成测试用例)以测试程序的最有效方法是什么。

以下是该计划的要点

if month == 1:
    if day <= 20:
        print("Capricorn")
    else:
        print("Aquarius")

elif month == 5:
    if day <= 21:
        print("Taurus")
    else:
        print("Gemini")
else:
    if day <= 21:
        print("Sagittarius")
    else:
        print("Capricorn") 

它包含更多的elif条件。但我想,你明白了。我想知道如何生成测试用例或测试涵盖所有条件的代码。

6 个答案:

答案 0 :(得分:3)

开始编写测试,但包含一个覆盖工具。您可以安装coverage package并直接使用它,也可以与nosezope.testrunner等测试运行器一起使用。

它会告诉您测试是否未能执行任何代码行;在运行测试后,代码覆盖率报告会为您提供覆盖百分比和错过的确切行。

您甚至可以使用其他工具(如duvet)来查看可能遗漏的行,或者与Jenkins或TeamCity等持续集成工具集成以跟踪一段时间内的覆盖率。

答案 1 :(得分:1)

对于这样的问题,有很多排列和组合,你应该创建一个包含所有 1 可能输入和预期输出的矩阵,然后创建一个可以迭代所有输出的通用测试用例。表的行。

为什么是矩阵?因为这是可视化此类场景的最简单方法。例如,如果您收集了24个不同的测试,那么很难有人快速回答诸如“您是否涵盖2月29日案例?”之类的问题。使用表中的所有日期和期望值,回答这些问题变得微不足道,并且在代码更改时添加其他测试用例也很简单。

例如,您首先要为每个月创建一行,因为您的代码似乎基于日历。然后,对于每个月,您将为所有重要条件创建行 - 月初,月末,特殊日期(即:如果20应该给出与21日不同的结果,等等)。

您的表可能在概念上看起来像这样:

| # month | day | sign
| 1       | 1   | capricorn
| 1       | 20  | capricorn
| 1       | 21  | aquarius
| 5       | 1   | taurus
| 5       | 21  | taurus
| 5       | 22  | gemini

......等等。然后,编写一个可以读取每一行的测试,调用该函数,并将输出与预期结果进行比较。

1 “全部”我并不一定意味着全部。您需要定义正常情况和边缘情况,但您不一定要测试每个可能的日期。

答案 2 :(得分:1)

我建议把它制作成桌面驱动:

testtable = {1: (20, "Capricorn", "Aquarius"),
             5: (21, "Taurus", "Gemini")}

def test(month, day):
    vals = testtable.get(month,
                         (21, "Sagittarius", "Capricorn"))  # default
    print( vals[1 + (day <= vals[0])] )

test(1, 20)  # --> Aquarius
test(1, 21)  # --> Capricorn
test(3, 21)  # --> Capricorn
test(3, 22)  # --> Sagittarius
test(5, 21)  # --> Gemini
test(5, 22)  # --> Taurus

答案 3 :(得分:0)

测试几乎总是基于提供输入和期望输出。但在实现测试之前,您需要指定使用代码的接口。它是一个提供API的库吗?然后直接测试API。也就是说,明确定义外部代码将调用的那些函数或方法,然后以与外部代码使用它们完全相同的方式测试它们。或者它是命令行工具?然后测试命令行行为。

如何确保在嵌套条件结构中测试所有不同的代码路径?仔细思考,使用coverage analysis tool 评估

答案 4 :(得分:0)

如果你想检查星座,你可以使用类似的东西:

monthday = month * 100 + day
if monthday <= 120:
    print("Capricorn")
elif monthday <= 219:
    print("Aquarius")
and so on

答案 5 :(得分:0)

有一些工具,例如coverage.py,可以向您显示您的测试用例是否涵盖了所有代码。但是,当一个程序开始有这么多特殊情况时,最好考虑重新组织它。

在这种情况下,数据的存储方式可以产生重大影响。这将使用单个if语句:

执行所有逻辑
def classify(month, day):
    x = 100*month + day
    data = [(120, 218, "Aquarius"), (219, 320, 'Pisces'), (321, 419, "Aries"), (420, 520, "Taurus")]
    for start, end, sign in data:
        if start <= x <= end:
            return sign

现在我们只有一个if语句要测试,生成测试用例变得非常简单。

详细信息

上面的关键是将日历日期转换为可以轻松测试的单个数字。人们可以选择一年中的一天。我选择了100*month+day,因为人类很容易理解和检查。

(上面的占星数据显然不完整。其余日期和标志的数据为here。)

使用python-coverage

的快速操作方法

以下内容将生成一个很好的交互式网页,显示测试脚本test.py涵盖或未涵盖哪些陈述:

python-coverage erase
python-coverage run test.py
python-coverage html "--omit=/usr/share/*"
firefox ./htmlcov/index.html

html输出的示例:

enter image description here

这表明覆盖率为100%。