估计的阅读时间:6分钟
我最近很高兴讨论和演示我关于a live stream的“Test-Driven Development in Go”书的一些关键概念。这篇文章总结了此1小时编码会话所涵盖的要点。了解这些测试必需品将有很长的路要走,可以帮助您成为TDD从业者。
继续阅读以了解为什么您应该关心测试和TDD!
关键原则
我渴望探索GO中TDD的主题,因为它是我很难理解的语言部分之一,尽管它很简单。 Go s testing
软件包中只有几个功能,但是我不确定如何使用它们,而且似乎很难构建任何测试设置。弄清楚测试过程需要花费一些时间,尤其是因为大多数教程旨在学习语言基础,而不是测试基础知识。我热衷于专门分享我的知识,自己发现新概念,并为以TDD
作为工作过程编写可测试代码的详尽指南。这就是为什么我进行了一本专门用于测试技术的书和TDD的应用。
这本书是围绕以下四个基本原则结构的:
- 编写可测试的代码以对您在中编写的语言的透彻理解开始:我们需要了解GO的主要结构和概念,以便能够编写可测试的代码。我们需要清楚地低估诸如包装结构,依赖注入,并发等等等概念。
- tdd很难,因为很难清楚地了解我们在问题模棱两可时要实现的目标:写作测试很容易,因为我们使用与编写源代码相同的技术。取而代之的是,对我们要实现的工作的不清楚理解以及对技术解决方案的过度关注是使练习TDD难以实现的。
- 工程师应拥有各个级别测试其产品的所有权,而不仅仅是单位:测试博客和演示通常只关注单元测试。虽然这使开发人员可以轻松地使用较小的范围编写测试,但工程师应在各个级别上拥有测试所有权。这有一个好处,可以使我们对用户最终如何与我们的产品进行互动,同时也以真正的DevOps方式赋予我们对产品的所有权。
- 练习TDD可以帮助您组织工作,并专注于用户问题的解决方案:TDD过程涉及与源代码一起编写测试。这鼓励我们为专注于要求和投入的代码结构做出有意识的决策,而不是过度依恋技术解决方案。
测试通常在测试金字塔中进行组织:
- 在金字塔的底部,我们有单位测试,它仅测试一个孤立的行为或功能。他们是最快,最多的。
- 在中间,我们进行了集成测试,它将多个组件的行为一起测试。它们是对单位测试的补充,因为它们确保多个单元不仅可以单独一起工作。
- 在金字塔的顶部,我们进行了端到端测试,它测试了整个应用程序。他们通常专注于验证应用程序揭示正确的面向用户的功能。
方法
红色绿色 - 反射器方法是TDD的工作过程。这是下图中描述的三个步骤。一开始,在源代码和测试代码之间进行交换可能会很麻烦,但是它将很快成为第二天性。该方法的三个步骤是:
- 红色阶段:基于提供的要求,我们首先用指定的输入和预期输出编写测试。我们运行此测试以确保其失败。这有助于我们以后避免任何误报。
- 绿色阶段:交换为源代码,我们编写足够的代码以满足先前的书面测试并实现所需的功能。我们重新运行此测试以确保它现在通过。
- 重构阶段:虽然测试和实施成功地满足了我们一直关注的要求,但我们可以花时间在重构阶段进行任何改进。
- 该过程重复,直到我们成功地实现了该单元所需的所有功能。
测试应专注于测试输出,而不是实施。如果测试紧密地耦合实现问题,则在更改或重构时,它们可能会变得脆弱。测试应尽可能弹性。
单元测试必需品
现在建立了过程和主要机制,我们可以开始研究如何实施我们的第一个测试。我们从单位测试的测试金字塔的底部开始。
GO功能,结构,变量和界面是在GO包中组织的。除非出口大写字母,否则它们的可见性仅限于包裹。目录通常只包含一个包装,但有些例外。这些例外之一是测试包。这些软件包以_test
后缀结尾,并且必须匹配在同一目录中也定义的源软件包的名称。这些软件包的行为就像其他任何外部软件包一样,只能访问源软件包的导出名称。
这是一种非常有力的机制。使用测试包的使用可确保我们仅测试软件包的外部可见功能,这使得我们的测试成为了我们正在创建的软件包的第一批消费者。然后,我们可以清楚地确定需要重写或澄清的裸露功能的哪些部分。
在GO中,测试只是符合某些限制的常规功能:
func TestName(t *testing.T) {
// implementation
}
- 测试名称以
Test
前缀开头,然后在骆驼盒中的测试名称。 - 测试功能以
*testing.T
类型的单个参数。 - 测试在
_test.go
文件中进行。
testing
软件包揭示了方法记录和失败测试。 t.Error
方法未能通过测试,但继续运行测试套件,而t.Fatal
方法使测试失败并停止执行整个测试套件。 t.Errorf
和t.Fatalf
方法对应物,允许我们传递格式的消息。
i演示了红绿色 - 反应器方法,其中一个简单的示例和live stream from timestamp 09:10中的单元测试。
集成测试
单元测试没有足够的范围来确保成功交付功能要求。通常,他们的实施需要多个单元或组件共同努力,并提供其专业功能以构建解决方案。在这些情况下,集成测试通常是扩展范围的有用方法:
- 集成测试涵盖一个或多个组件,以确保单个组件作为合并实体效果很好。在微服务世界中,不同的组件甚至可能由不同的团队提供。这些单独单元之间的集成通常是错误或中断的原因。
- 虽然特定组件的逻辑通过其单位测试验证,但集成测试的目的是在组件之间的接缝处行使条件。
- 集成测试的优点是允许我们测试更大的范围,而无需运行整个应用程序的复杂性。由于它们位于金字塔的中间,它们不需要整个应用程序准备运行和测试。
实施集成测试所需的代码与单位测试没有任何不同。我在live stream from timestamp 44:38中使用httptest
进行了写作集成测试。
端到端测试
此流不涵盖端到端测试。我可能会将未来的博客列入此主题,但是与此同时,我建议您探索BDD testing with koude12和contract testing with koude13。
。分开的话
让我开始工作,然后看看如何测试它。
通常,我们觉得测试代码比源/实现代码的重要性低。这种思维方式导致复杂的,无与伦比的代码,这些代码充满了错误。花费时间取消划分复杂的代码结构以进行以后测试的时间比逐步做出决策需要更长的时间,以确保它们易于测试和实施提供的解决方案。
因此,我鼓励每个人都花时间改进和磨练他们的测试实践。您不会对结果感到失望。