Go中的软件架构:使用提示、代码覆盖和CI的可维护性

115 阅读4分钟

欢迎来到涵盖质量属性/非功能要求的系列的另一个帖子部分,这次我说的是使用Linting、代码覆盖率和持续集成的Maintainability

什么是可维护性?

Maintainability 可维护性是指修改我们系统的难度,这意味着增加新功能、进行改进或修复缺陷的难易程度。在《构建进化架构》中,有一个概念叫做 "健身函数",它允许我们定义可测量的工件,用于收集数据,当随着时间的推移进行修改时,我们可以参考,最终目的是使这些工件成为我们构建管道的一部分。

例如,我们可以实现一个健身函数来收集我们的服务延迟,也许使用OpenTelemetry,然后这个函数可以作为基线,在部署新的变化时进行比较,这样我们就可以根据我们从服务寿命开始收集的具体指标来确定部署的东西是使我们的系统变得更好还是更坏。

当使用健身函数时,关键是要使用持续集成来不断行使这些规则,这意味着每次有新的变化被推入我们的版本控制系统时,就会触发一个自动进程来运行这些函数,一些著名的持续集成服务包括Jenkins CIGitlab CICircle CI和我将在这个例子中使用的Github Actions

Examples of Continuous Integration Services

选择一个特别的服务主要取决于你的使用情况、预算和现有的第三方集成。所有这些都提供了一种方法来配置工作步骤,使用某种配置文件来决定执行的构建过程,以及一种生成工件的方法,以便在你使用Github、Bitbucket或Gitlab的情况下,使其回到你的版本控制系统中。

添加健身函数来衡量Go的可维护性

我在这篇文章中实现的适配功能是我认为任何专业项目所需的最低限度的功能。测试代码覆盖率提示

Fitness Functions: Testing, Code Coverage and Linting

关于测试,我以前在其他文章中从不同的角度介绍过,例如在测试REST APIs时,在测试第三方HTTP请求时,以及在使用Repository Pattern做一些集成测试时。

在做Go项目的时候,我遵循Go团队的建议,特别是涉及到以下方面。

  • 避免使用断言包,以及
  • 使用表驱动的测试

我还尽可能地减少对第三方的依赖,我很少使用以下列表以外的软件包。

关于代码覆盖率,我之前讨论过如何使用go工具链中的test 命令来生成该工件,根据你使用的版本控制系统,你可能需要配置它来读取输出,这样生成的值就可以在你的Pull Requests或Commit details中获得,例如在Gitlab CI中,如果配置正确,你可以看到覆盖的行以及总的百分比。

在这篇文章中,我使用了一个名为Codecov的第三方服务,它可以很好地与Github集成,并在创建的拉动请求中显示覆盖率的详细信息,以及一个漂亮的类似洋葱的图表,显示整个项目的每个Go包的覆盖率。

最后,关于Linting,Go中事实上的工具是golangci-lint,这个工具包括多个linters的集合,请参考我目前对项目的配置,我通常将以下配置作为默认配置,然后开始为每个linter或异常添加具体设置。

linters:
  enable-all: true
  disable:
    - exhaustivestruct # Should be configured to handle Args-like types.
    - goerr113
    - gofumpt # Prefer `gofmt` rules / some rules conflict with `wsl`
    # The following are deprecated linters, added to avoid intial warning when running
    - golint
    - interfacer
    - maligned
    - scopelint

最后,为了连接所有这三个健身功能,剩下的就是配置我们的持续集成服务,在这种情况下是Github Actions,为了做到这一点,有两个工作流程,其中一个是 测试,其中也包括代码覆盖率,另一个为 造林.

有了这些,每次我们推送新的提交到我们的远程仓库时,Github Actions工作流都会触发,以表明我们的改变是改善了还是恶化了我们项目的状态。

结论

Maintainability 如果没有关于代码库状态的基线,就很难实现,测试代码覆盖率提示应该是创建任何新项目时需要实施的最低限度的健身功能,这些将允许负责的团队遵循相同的准则,并保持整个实施的一致性。