给定一个短暂的 sprint,放弃 TDD 以在 sprint 中“完成任务”是否可以接受。
例如,给定的工作可能需要 1/3 的 sprint 来围绕现有实现设计对象模型。在这种情况下,您很可能最终得到已实现的代码,例如在 sprint 进行到一半时,没有任何测试(在此“设计”阶段实施单元测试会增加大量工作,并且测试可能会被丢弃几次,直到最终“设计”已确定)。
然后,您可能会在第二周花一两天时间在事后添加单元/集成测试。
这可以接受吗?
给定一个短暂的 sprint,放弃 TDD 以在 sprint 中“完成任务”是否可以接受。
例如,给定的工作可能需要 1/3 的 sprint 来围绕现有实现设计对象模型。在这种情况下,您很可能最终得到已实现的代码,例如在 sprint 进行到一半时,没有任何测试(在此“设计”阶段实施单元测试会增加大量工作,并且测试可能会被丢弃几次,直到最终“设计”已确定)。
然后,您可能会在第二周花一两天时间在事后添加单元/集成测试。
这可以接受吗?
我想说的是,如果您完成了一个原本无法完成的项目,那么绕过任何流程几乎总是可以接受的。这些流程应该可以帮助您,但如果您的流程没有帮助,请不要使用它(当然,在与团队其他成员讨论之后)。
然而,绕过 TDD 很容易导致完全相反的效果 - 您可能会编写错误代码,在您需要发布之前需要重写,因为最终测试会显示您应该尽早发现的关键问题,因此在这样做之前请仔细考虑。
如果您确实跳过单元测试来获得一些东西并且很幸运它可以工作,那么您应该将其视为应该尽快偿还的技术债务。
对很多人来说,2 周的迭代并不短。我们中的许多人都在进行一周的迭代。Kent Beck 甚至试图鼓励日常部署——清理开发流程是有优势的,因此它可以响应迅速。
永远不要降低 TDD 质量来获取东西- 以后清理起来要困难得多,你最终只会教客户他们可以迫使你快速、肮脏、被黑的版本。他们看不到由此产生的废话代码——他们也无法维护它。如果有人试图让我这样做,我会辞职......而且我拒绝在“没有时间正确测试”的地方工作。这不是一个有效的借口。
注意:当我写 TDD 时,我包括功能测试。这些很重要,因为它们应该根据可识别的用户故事来练习对客户有意义的场景。我通常从功能测试开始编写一个故事,因为它是最重要的测试——“测试客户得到他们所描述的......”所有其他测试可能都需要协商,但是当我领导团队时,我至少希望每个故事一个功能测试,或者它(正如 Scrum 人所说)“未完成!” ;-)
不要以为您可以稍后再添加测试 - 这样做要困难得多。(我已经尝试过两种方式——相信我。)在你进行的过程中进行测试确实更便宜——即使你必须重构和重写,或者随着系统的发展而丢弃一些。
如果没有始终如一的代码覆盖率,您就无法获得高质量的代码。
代码测试覆盖率是这里的重要词汇。涵盖可能破坏的内容,而不仅仅是无数无意义的测试——涵盖您需要担心的事情的关键测试。
如果你不能及时把它弄出来,这是一个问题,你需要想想为什么?
如果您无需测试就可以准确地编写代码,那为什么还要使用单元测试呢?单元测试应该帮助您更快地编写代码或帮助编写更好的代码。如果两者都没有,请不要使用单元测试。
以我的经验,编写适当的单元测试所花费的时间至少与编写它测试的代码一样长,所以我很难看到你将如何在“一两天”内编写测试。
也就是说,什么是“可接受的”取决于很多事情。不要将测试视为宗教问题。测试的存在是为了让您对代码有一定程度的信心。您只需要意识到,通过上述测试,您也会增加风险。有时这是合适的,有时则不是。
需要注意的两个极端:
说你会在以后编写测试,然后永远不会去处理它。这是“向未来借钱”,你很快就会积累更多的债务,而你无法偿还。
在测试上花费的时间超过了应有的时间。某些风险非常小,如果出现问题的预期成本低于编写测试的成本,那么对它们进行测试就没有任何意义。
在我看来,这可能是一个危险的权衡取舍。虽然在某些时候它可能是可以接受的,但它确实开创了一个难以推翻的先例。我知道我在哪里工作,对于一些复杂的事情,我们往往必须实施几次才能最终实现一个好的实施,因为在我们的项目中经常会出现更好的想法。
通常,在构建测试时,可以发现缺少的需求,并且可以在获得大量代码之前初步绘制更完整的设计,否则会有一堆代码可能想要尝试重用而不是扔掉并从头开始构建更好的东西。
关键是能够在第二周完成这些测试,而不是专注于似乎是优先工作项目的新事物。虽然这对某些人来说可能很好,但对于其他人来说,这可能是灾难的根源,IME。
根据您的描述,您并没有真正做 TDD,因为测试并没有推动设计。更多的是你在做单元测试,这仍然是一件好事。
就基本问题而言,您是否可以放弃测试,实际上这是只有(团队的)经验才能指导您的事情,就权衡而言。通常你会后悔,但有时一个快速的坏黑客比根本不交付要好。
也许我遗漏了一些东西,但是您要么根据普遍认可的原则进行 TDD,要么像 TDD 货物崇拜者一样运作。
如果您的团队/公司已决定使用 TDD,并打算坚持下去,您要么需要更长的 sprint,要么需要减少要在 2 周内完成的功能量。
在这个“设计”阶段实施单元测试会增加大量的工作量,并且测试可能会被丢弃几次,直到最终的“设计”确定下来
我发现测试驱动设计让我更快地进入最终的“设计”:迭代次数更少,而且通常第一枪就是最后一枪。通常需要设计迭代,因为程序的设计没有任何现实检查,随后的实施努力和使用尝试推动了重新设计。使用 TDD,现实检查始终到位。这足以确保您不会错过标记并且必须重新设计事物。
如果您不交付代码,那么您作为开发人员有什么好处?最重要的是将代码呈现在用户面前。如果是意味着牺牲一部分过程来完成一个项目,那就去做吧。CEO 不会因为你实施 TDD 而不是发货而给你奖金。
好的测试会使完成所需的时间加倍。如果管理团队责备你花费更长的时间,那么,这就是现实生活项目中金属撞击肉的地方,不是吗?
我发现 TDD 是狂热者的做法,浪费时间使测试失败、编译错误、重构测试和代码致死,等等。最后,只要您获得良好的代码测试覆盖率,您就可以通过在功能编译并开始工作后立即创建单元测试来节省时间。
这是一项业务决策,而不是技术决策。代码需要真正工作还是看起来像工作一样?
这是可以接受的一次:
您有一个几乎没有人使用的新产品,而您的销售主管将参加一些行业会议来展示它。您相信她会围绕您留下的任何错误跳舞。会议将建立对您的产品的兴趣,并且销售将在接下来的 3-6 个月内流动。贵公司在银行有 8 个月的现金。
这是一次不能接受的情况:
您的代码控制 5,000 家医院的 X 射线硬件。您正在推出一个新版本。你不想杀人。如果你犯了大错,你的公司将被遗忘。
需要在开发速度与质量之间进行权衡。这是一个商业决策。让我们希望您有一位愿意理解这一点的经理。