早期写测试真的合理吗?
Is it really reasonable to write tests at the early stage?
我曾经在开发我的软件时编写测试,但我停止了它,因为我注意到,几乎总是,第一个 api 和我认为很好的结构在取得一些进展后变得笨拙。我每次都需要重写整个主程序和整个测试。
我相信这种情况在现实中很常见。所以我的问题是:
- 一开始写测试真的很常见吗,就像 TDD 中所说的那样?我只是一个业余程序员,所以我不了解真正的开发世界。
- 如果是这样,人们在改造软件时是否会(一次又一次)重写测试 api/structure? (除非他们足够聪明,一开始就想出最好的,不像我。)
纯粹主义者说是,但在实践中结果有点不同。有时我会编写六个测试,然后编写通过它们的代码。其他时候我会在编写测试之前先写几个函数,因为这些函数不能单独使用,否则测试会很困难。
是的,您可能会发现需要根据 API 更改重写测试。
而对于纯粹主义者来说,即使他们也会承认有些测试比 none 更好。
我不知道有谁会在您还不知道自己在构建什么时推荐 TDD。除非您以前创建过一个非常相似的系统,否则您首先制作原型,而不使用 TDD。然而,在没有将 TDD 过程发挥作用的情况下最终将原型投入生产是一个非常现实的危险。
一些常见的正确做法是……
一个。扔掉原型,重新开始使用 TDD(仍然可以几乎逐字地从原型中借用一些代码,只需按照实际的 TDD 周期重新实现)。
乙。将单元测试改造到原型中,然后从那里进行红色、绿色和重构。
but I stopped it because I noticed that, almost always, the first api and structures I thought great turn out to be clumsy after some progress
测试驱动开发应该可以帮助您进行设计。 API 即 "clumsy" 会在您为其编写测试时接缝笨拙。
Is it really common to write tests at first, like so said in TDD?
取决于开发者。我写的 99% 的内容都使用测试驱动开发。它有助于我编写的 API 和应用程序的设计。
If so, do people rewrite the tests again (and again) when they revamp the software api/structure?
取决于测试的级别。希望在大型重构期间(即当您重写一大块代码时)您有一些测试来涵盖您将要做的工作。一些单元测试将被丢弃,但集成和功能测试将非常重要。它们告诉您没有任何损坏。
您可能已经注意到我强调编写测试驱动开发而不是 "TDD"。测试驱动开发不仅仅是 "writing tests first",它允许测试驱动开发周期。你的 API 的设计将受到你编写的测试的强烈影响(人为的例子,单例或服务定位器将被 IoC 取代)。写出好的 APIs 需要练习和学习聆听您可以使用的工具。
Is it really reasonable to write tests at the early stage?
- 否,如果您编写的 top-down-design high level integrationtests 需要真实的数据库或互联网连接到其他网站才能工作
- 是的,如果您正在实施 bottom-up with unittesting(=单独测试模块)
"level" 越高,单元测试就越困难,因为您必须引入更多 mocking/abstraction。
在我看来,tdd 的架构优势仅在与单元测试结合使用时才适用,因为这推动了 Separation_of_concerns
当我开始 tdd 时,我不得不在更改 api/architecture 时重写许多测试。随着今天经验的增长,只有少数情况需要这样做。
您应该进行第一层测试来验证 API 的外部可见行为,而不考虑其内部结构。
在出现新的功能需求时更新此类测试不是问题。在您提到的示例中,很容易适应被抓取的新网站 - 您只需向测试添加新断言以说明获取的新数据。
事实上 "the scraping code had to be revamped entirely" 不应该影响这些更高级别测试的结构,因为从外部看,API 应该被消耗和以前一样。
如果这样的低级技术细节确实影响了您的高级测试,您可能缺少描述您获得的什么数据但隐藏了[=的详细信息的抽象19=]如何 检索它。
在编写实际代码之前编写测试意味着您了解应用程序的设计方式。这种情况很少见。
事实上,例如,我开始将所有内容写在一个文件中。它可能有几行或更多行。这样我就可以轻松快速地重新设计 api。后来当我决定喜欢它并且觉得它很好时,我开始重构它,将所有内容放在有意义的命名空间和单独的文件中。
完成后,我开始编写测试以验证一切正常并查找错误。
TDD 只是一个神话。不可能先写测试再写代码,尤其是刚开始的时候。
你永远要牢记 KISS 规则。如果你需要一些疯狂的东西来测试你自己的代码,比如假货或模拟,你已经失败了。
我曾经在开发我的软件时编写测试,但我停止了它,因为我注意到,几乎总是,第一个 api 和我认为很好的结构在取得一些进展后变得笨拙。我每次都需要重写整个主程序和整个测试。
我相信这种情况在现实中很常见。所以我的问题是:
- 一开始写测试真的很常见吗,就像 TDD 中所说的那样?我只是一个业余程序员,所以我不了解真正的开发世界。
- 如果是这样,人们在改造软件时是否会(一次又一次)重写测试 api/structure? (除非他们足够聪明,一开始就想出最好的,不像我。)
纯粹主义者说是,但在实践中结果有点不同。有时我会编写六个测试,然后编写通过它们的代码。其他时候我会在编写测试之前先写几个函数,因为这些函数不能单独使用,否则测试会很困难。
是的,您可能会发现需要根据 API 更改重写测试。
而对于纯粹主义者来说,即使他们也会承认有些测试比 none 更好。
我不知道有谁会在您还不知道自己在构建什么时推荐 TDD。除非您以前创建过一个非常相似的系统,否则您首先制作原型,而不使用 TDD。然而,在没有将 TDD 过程发挥作用的情况下最终将原型投入生产是一个非常现实的危险。
一些常见的正确做法是……
一个。扔掉原型,重新开始使用 TDD(仍然可以几乎逐字地从原型中借用一些代码,只需按照实际的 TDD 周期重新实现)。
乙。将单元测试改造到原型中,然后从那里进行红色、绿色和重构。
but I stopped it because I noticed that, almost always, the first api and structures I thought great turn out to be clumsy after some progress
测试驱动开发应该可以帮助您进行设计。 API 即 "clumsy" 会在您为其编写测试时接缝笨拙。
Is it really common to write tests at first, like so said in TDD?
取决于开发者。我写的 99% 的内容都使用测试驱动开发。它有助于我编写的 API 和应用程序的设计。
If so, do people rewrite the tests again (and again) when they revamp the software api/structure?
取决于测试的级别。希望在大型重构期间(即当您重写一大块代码时)您有一些测试来涵盖您将要做的工作。一些单元测试将被丢弃,但集成和功能测试将非常重要。它们告诉您没有任何损坏。
您可能已经注意到我强调编写测试驱动开发而不是 "TDD"。测试驱动开发不仅仅是 "writing tests first",它允许测试驱动开发周期。你的 API 的设计将受到你编写的测试的强烈影响(人为的例子,单例或服务定位器将被 IoC 取代)。写出好的 APIs 需要练习和学习聆听您可以使用的工具。
Is it really reasonable to write tests at the early stage?
- 否,如果您编写的 top-down-design high level integrationtests 需要真实的数据库或互联网连接到其他网站才能工作
- 是的,如果您正在实施 bottom-up with unittesting(=单独测试模块)
"level" 越高,单元测试就越困难,因为您必须引入更多 mocking/abstraction。
在我看来,tdd 的架构优势仅在与单元测试结合使用时才适用,因为这推动了 Separation_of_concerns
当我开始 tdd 时,我不得不在更改 api/architecture 时重写许多测试。随着今天经验的增长,只有少数情况需要这样做。
您应该进行第一层测试来验证 API 的外部可见行为,而不考虑其内部结构。
在出现新的功能需求时更新此类测试不是问题。在您提到的示例中,很容易适应被抓取的新网站 - 您只需向测试添加新断言以说明获取的新数据。
事实上 "the scraping code had to be revamped entirely" 不应该影响这些更高级别测试的结构,因为从外部看,API 应该被消耗和以前一样。
如果这样的低级技术细节确实影响了您的高级测试,您可能缺少描述您获得的什么数据但隐藏了[=的详细信息的抽象19=]如何 检索它。
在编写实际代码之前编写测试意味着您了解应用程序的设计方式。这种情况很少见。
事实上,例如,我开始将所有内容写在一个文件中。它可能有几行或更多行。这样我就可以轻松快速地重新设计 api。后来当我决定喜欢它并且觉得它很好时,我开始重构它,将所有内容放在有意义的命名空间和单独的文件中。
完成后,我开始编写测试以验证一切正常并查找错误。
TDD 只是一个神话。不可能先写测试再写代码,尤其是刚开始的时候。
你永远要牢记 KISS 规则。如果你需要一些疯狂的东西来测试你自己的代码,比如假货或模拟,你已经失败了。