目录
前言:
使用黑盒测试在Go中重写Bash脚本是一种将脚本转化为更稳定、可维护和可扩展的解决方案。
测试是任何应用程序不可或缺的一部分,编写自动化测试对于确保代码安全至关重要。 但是,当你用完全不同的语言重写程序时,会怎么做? 你如何确保你的新旧程序做同样的事情?在本文中,我将描述我们将 Bash 脚本集合更改为组织良好的 Go 库的过程,以及我们如何确保在此过程中没有任何问题。
开始
在 Flipp,我们有自己的微服务平台,它允许打包和部署代码,作为持续交付流水线的一部分。 还提供了额外的功能,比如权限验证(所以我们不会部署会失败的东西,因为它没有读取或写入资源的权限)。这些脚本是用 Bash 编写的。 Bash 是与 Linux 可执行文件交互的好方法。 它非常快,并且不需要安装任何特定的编程语言,因为没有编译或解释通过 shell 本身。 但是 Bash 使用起来很挑剔,很难测试,并且没有像大多数编程语言那样的“标准库”。
我们本可以继续使用 Bash。但是,不断出现的主要痛点是对几乎所有内容都要使用环境变量。 当你编写 Bash 时,无法判断某个特定的环境变量是否是脚本的输入,它是否是由于某些外部进程而恰好设置的,或者它是否是脚本应该使用的局部变量 “自己的。”
此外,如果将脚本分成文件以便平台可以使用它们,将无法阻止用户在不告诉你的情况下调用它的一小部分。 如果想尝试弃用某个功能,这几乎是不可能的,因为一切都是对世界开放的。在进行任何类型的重大更改时,我们唯一的选择基本上是发布一个新版本,“在生产中对其进行测试”,并在这些测试完成后将其提升为默认版本。 当有几十个使用这些脚本的服务时,这工作得很好。 一旦膨胀到几百个,它就变得不那么理想了。因此不得不重写这些东西,以便它们实际上是可维护的。
准备工作
我们决定用 Go 重写脚本。 它不仅是我们已经在 Flipp 用于高吞吐量 API 服务的语言,还允许轻松编译到需要的任何目标架构,并附带一些很棒的命令行库,如 Cobra。 此外,这意味着我们可以使用配置文件定义部署的行为,而不是使用大量混乱的环境变量。但问题仍然存在 —— 我们如何测试这个东西? 单元和功能测试通常在重构之前使用,因此可以确保输入和输出匹配。 但我们正在谈论用一种完全不同的语言重写它。 怎么能确定没有破坏东西?
我们决定采用三步法:
- 通过让测试框架覆盖所有测试用例来描述现有脚本的行为。
- 用现在仍然能测试通过的方式重写 Go 中的脚本。 以这样一种方式编写,它可以将环境变量或配置文件作为其输入。