在编写自动化测试时,我遇到了在一种方法中包含多个验证点的情况,但后来我也读到/听说过一个测试应该只进行一个验证。您遵循哪种方法,为什么?
nb 我有我的指针,可以用一种方法进行多次验证,一旦我得到满意的答案,我会详细说明它们。看起来我提出了一个更主观/争论的问题。
在编写自动化测试时,我遇到了在一种方法中包含多个验证点的情况,但后来我也读到/听说过一个测试应该只进行一个验证。您遵循哪种方法,为什么?
nb 我有我的指针,可以用一种方法进行多次验证,一旦我得到满意的答案,我会详细说明它们。看起来我提出了一个更主观/争论的问题。
我将多个验证合并到一个测试中,但只在测试执行的一个时间点允许它们。测试工具从失败的验证中优雅地恢复(验证不应该更改状态 IMO;如果收集数据更改状态,则收集数据作为测试的一部分或使该验证成为另一个测试)并继续执行其他验证。
为什么要进行多次验证?
为什么他们只在测试中的某一时刻出现?
编辑添加: 我刚刚意识到臭名昭著的“Given-When-Then”格式遵循相同的规则。您有一个测试(“When”部分),在“when”完成后,您可以使用“and”关键字验证多个“then”语句。所以有一种方法可以解决这个问题。
我个人喜欢原子测试,通常设计为只测试一两件事,大多数验证在测试用例本身中被显式调用。这样您就可以轻松地在顶层查看正在验证的内容,例如(来自 parkcalc)。
[TestMethod]
public void InvalidTextAsExitDate()
{
Parking.Calculate(ParkingType.LongTermSurfaceParking, "12:00", "AM", "today", "12:00", "AM", "INVALID");
Verify.SpecificErrorIsShown(ErrorMessages.EnterCorrectDate);
}
[TestMethod]
public void OnlySpecifyEntryDate()
{
Parking.Calculate(ParkingType.LongTermSurfaceParking, "12:00", "AM", "today", "12:00", "AM", "");
Verify.VerifyResult(ParkingType.LongTermSurfaceParking, "12:00", "AM", "today", "12:00", "AM", "");
}
每当我将验证推到较低级别时,我总是在想,“这到底是在验证什么。”,例如
[TestMethod]
public void OnlySpecifyExitDate()
{
Parking.CalculateAndVerify(ParkingType.LongTermSurfaceParking, "12:00", "AM", "", "12:00", "AM", "today");
}
然后下一个级别是
public static void CalculateAndVerify(ParkingType parkingType, string inTime, string inAMPM, string inDate, string outTime, string outAMPM, string outDate)
{
Calculate(parkingType, inTime, inAMPM, inDate, outTime, outAMPM, outDate);
Verification.Verify.VerifyResult(parkingType, inTime, inAMPM, inDate, outTime, outAMPM, outDate);
}
我的框架的完整工作示例解决方案可在https://github.com/teknologika/stax
在一个测试中组合太多东西的另一个缺点是,失败可能会阻止其他验证的发生。
假设您结合了三个验证,而第二个验证失败。你的自动化会停止吗?还是继续三连?三是有多重要?如果您可以在没有经过验证的情况下生活,那么合并将节省时间。但是,如果三个被验证是重中之重,我会把它自己放在一边,慢慢来。
对于单元测试,我非常喜欢每次测试测试一件事。原因是这样的:当测试失败时,我希望测试尽快将我指向损坏的代码。
如果一个测试测试多个东西,那么测试的名称不足以指向损坏的代码。我必须寻找其他信息,例如堆栈跟踪,它可以引导我找到一行测试代码。然后我必须查看测试代码行,看看它在做什么,以及在什么上下文中。现在,这不是我遇到过的最可怕的问题,但是...
如果测试测试一件事,那么失败测试的名称通常足以为我指明正确的方向。不总是,但经常。
出于不同的原因,我也更喜欢让每个验收测试都成为一件事。但在这里,我的理由主要是清晰。我希望每个验收测试都能清晰地描述它正在测试的功能或责任。我想看看为什么这个测试很重要。测试做的事情越多,就越难理解测试的重点。
我更有可能放松对验收测试的偏好,尤其是通过 GUI 或浏览器进行测试时。启动和拆卸有时需要很长时间。如果我在每个测试中做更多的事情,那么我执行的那些长时间运行的设置和拆卸就会更少,因此套件运行时间会更少。另一方面,每个测试都需要更长的时间来运行,如果该测试嵌入到更大的“创建一个 frobozz,编辑它,保存它,删除它”测试中,就不可能只测试“创建一个新的 frobozz”的东西.