我是单位测试的新手(现在在现实世界中最近毕业)。我对编写测试需要多长时间感到困惑。
让我们举一个基本的例子。我写了一个函数:
def add(a, b)
return a + b
我想测试它的整数输入和无限精度的浮点数。例如,测试用例名称可能是test_add_negative_integer_to_negative_integer。
的假设
在边界处测试边缘情况代表所有其他情况。
的边缘/边界
数字类型= {integer,float}
数值= {负,零,正}
测试用例数
重复组合(假设参数顺序不重要)。
C(3 + 2 - 1,2)* C(2 + 2 - 1,1)= 18 测试用例满足假设条件。
为数字类型集添加另一个值会产生 36个不同的测试用例。
我做错了吗?
答案 0 :(得分:2)
您的考试目标是什么?
是否涵盖了所有可能的输入?如您所列,需要18个测试用例才能完全覆盖所有组合,但这些组合是否必要?
风险分析与确定代码的详尽测试必然相辅相成。这种方法存在缺陷的技术风险和业务风险是什么?如果它是一个关键风险,则可能需要所有18种组合。此外,某种the w3 spec也非常有用。
IMO,对于单元测试,我发现覆盖率是一个很好的指导指标,可以提供高度的信心,同时避免所有组合。如果您使用coverage作为目标,那么此方法只需要一个单元测试。
如果这是一项关键功能,并且需要所有组合,我建议使用数据驱动方法。这是一种干净的方式来指定所有18个测试用例并使用相同的代码驱动每个测试。它解决了必须编写18个单独的<form #form="ngForm">
<div *ngFor="item in items">
<input name="product-{{item.id}}"
[(ngModel)]="item.qty"
validateQuantity
#qtyInput>
<button (click)="addItemToCart(item)"
[disabled]="!qtyInput.valid">Add to cart</button>
</div>
<button (click)="addAll()"
[disabled]="!form.valid">Add all</button>
</form>
。
test_this_and_this
数据驱动测试也是一个很好的组织工具。如果您发现自己正在与非技术测试人员合作,那么能够创建测试驱动程序,然后让非技术设计人员使用所有相关业务相关测试用例的CSV,并将其作为数据驱动的输入提供测试
答案 1 :(得分:2)
我认为您的问题的答案很简单:应用 TDD 流程,您会发现问题会自动消失。
更具体地说,您可以先为“添加(a,b)”功能编写第一个测试。对于“add”方法的初始空实现,这可以使用单行测试方法完成。测试(例如add(1, 2) == 3
)将按预期失败。
在第一次测试通过后,只有这样,你才会尝试写第二次测试。
以下是此过程工作原理的关键:第二个测试首先需要因有效原因而失败。 “有效理由”将与当前“添加”实施尚未实现的一些其他业务要求直接相关。如果您找不到这样的要求,那么就不会进行第二次测试。
重复上述步骤,直到无法添加新测试。您将看到需要更少数量的测试才能完全覆盖所需的功能。
答案 2 :(得分:1)
单元测试是一种编写/测试代码的实用方法(TDD首先编写单元测试以帮助您开发代码)。
您应该考虑以下几点:
仅测试您的代码。测试其他人的API(在您的情况下,系统的API)就像您描述的那样是一个沉孔(它不再是单元测试)。这只需要一次测试:验证调用add
+
的时间是否正确。
仅测试可能会破坏的内容。吸血鬼和二传手和简单包装(就像你在这里一样)不太可能被你或你的一个队友打破。错误发生在某些地方(即,圈复杂度,奇怪的耦合,有大量流失的代码),这是你想要大部分测试的地方。
最后,如果你正在编写系统+
的代码,你可能想要所有这18个测试,但可能不是,整数有一定的对称性。
请记住,单元测试是为了帮助您开发和维护代码。如果它没有帮助,请尝试少做。
我的单位测试代码通常是生产代码的1 1/2倍。