Language agnostic 我应该对“工作”有多严格;尽可能做最简单的事情”;在做TDD时
对于TDD,您必须Language agnostic 我应该对“工作”有多严格;尽可能做最简单的事情”;在做TDD时,language-agnostic,tdd,Language Agnostic,Tdd,对于TDD,您必须 创建失败的测试 尽可能做最简单的事情来通过考试 添加更多测试变体并重复 当模式出现时重构 通过这种方法,你假设可以涵盖所有的情况(至少在我脑海中是这样),但我想知道我在这里是否过于严格,是否有可能“提前思考”一些场景,而不是简单地发现它们 例如,我正在处理一个文件,如果它不符合某种格式,我将抛出一个InvalidFormatException 所以我的第一个测试是: @Test void testFormat(){ // empty doesn't do anyth
InvalidFormatException
所以我的第一个测试是:
@Test
void testFormat(){
// empty doesn't do anything nor throw anything
processor.validate("empty.txt");
try {
processor.validate("invalid.txt");
assert false: "Should have thrown InvalidFormatException";
} catch( InvalidFormatException ife ) {
assert "Invalid format".equals( ife.getMessage() );
}
}
我运行它,它失败了,因为它没有抛出异常
所以我想到的下一件事是:“尽可能做最简单的事情”,所以我:
啊!!(虽然真正的代码有点复杂,但我发现我自己做过几次类似的事情)
我知道,我最终必须添加另一个文件名和其他测试,这将使这种方法变得不切实际,并迫使我重构到有意义的东西(如果我正确理解TDD的意义,这就是发现使用所揭示的模式),但是:
Q:我是不是把“做最简单的事…”这句话看得太字面了?很多评论:
- 如果验证
时抛出异常,则无法捕获它“empty.txt”
- 不要重复你自己。您应该有一个测试函数来决定验证是否引发异常。然后调用该函数两次,得到两个不同的预期结果
- 我没有看到任何单元测试框架的迹象。也许我想念他们?但是仅仅使用
无法扩展到更大的系统。当您从验证中得到一个结果时,您应该有一种方法向测试框架宣布一个给定名称的测试成功或失败assert
- 我对检查文件名(而不是内容)构成“验证”的想法感到震惊。在我看来,这有点太简单了
例如,如果验证是“必须是XML”,那么您的测试用例只是一些不符合XML的字符串,并且您的实现使用XML库,并且(如果需要)将其异常转换为为为“验证”功能指定的异常。当然,您对规则的解释过于文字化。 这听起来应该像“做最简单的可能有用的事情…”
另外,我认为在编写实现时,您应该忘记您试图满足的测试主体。您应该只记住测试的名称(它应该告诉您测试的内容)。通过这种方式,您将被迫编写足够通用的代码,使其变得有用。我认为您的方法很好,如果您对它感到满意的话。你没有浪费时间写一个愚蠢的案例,用一种愚蠢的方式解决它——你为真正想要的功能编写了一个严肃的测试,并让它通过——正如你所说的——可能工作的最简单的方式。现在以及将来,当您添加越来越多的实际功能时,您将确保您的代码具有所需的行为,即在一个特定的格式错误的文件上抛出正确的异常。接下来要做的是让这种行为成为现实——你可以通过编写更多的测试来推动这一点。当编写正确的代码比再次伪造代码更简单时,您就可以编写正确的代码了。这种评估因程序员而异——当然,有些人会认为第一次失败的测试是在什么时候编写的
您使用的是非常小的步骤,这是我和其他一些TDER最舒适的方法。如果你对更大的步骤更满意,那也没关系——但要知道,在那些大步骤绊倒你的情况下,你总是可以求助于更细粒度的流程。就像一个方法应该只做一件事一样,一个测试应该只测试一件事(行为)。为了解决给定的示例,我将编写两个测试,例如,
test\u no\u exception\u for\u empty\u file
和test\u exception\u for\u invalid\u file
。第二种可能确实是几次测试——每种残疾一次
TDD过程的第三步应解释为“添加新的试验变量”,而不是“添加新的试验变量”。事实上,单元测试应该是原子的(只测试一件事),并且通常遵循AAA模式:排列-动作-断言。首先验证测试失败是非常重要的,以确保它确实在测试某些东西
我还要将读取文件和验证其内容的责任分开。这样,测试可以将缓冲区传递给validate()函数,并且测试不必读取文件。通常,单元测试无法访问文件系统,这会使它们的速度减慢 我也是一名TDD新手,正在努力解决这个问题。在研究过程中,我发现罗伊·奥舍洛夫(Roy Osherove)是我发现的第一个也是唯一一个“可能工作的最简单的事情”的具体和有形的定义(甚至罗伊也承认这只是一个开始) 简言之,罗伊说: 看看你刚才写的代码
public void validate( String fileName ) throws InvalidFormatException {
if(fileName.equals("invalid.txt") {
throw new InvalidFormatException("Invalid format");
}
}