我有一堆需要评估的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条件。但我想,你明白了。我想知道如何生成测试用例或测试涵盖所有条件的代码。
答案 0 :(得分:3)
开始编写测试,但包含一个覆盖工具。您可以安装coverage
package并直接使用它,也可以与nose
或zope.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输出的示例:
这表明覆盖率为100%。