当您有一个好的测试套件在您的代码库上运行时,您可以自信地升级您的依赖项

每天‬分享‬最新‬软件‬开发‬,Devops,敏捷‬,测试‬以及‬项目‬管理‬最新‬,最热门‬的‬文章‬,每天‬花‬3分钟‬学习‬何乐而不为‬,希望‬大家‬点赞‬,加‬关注‬,你的‬支持‬是我‬最大‬的‬动力‬。

始终保持您的依赖关系是最新的。如果不升级,就会错过 bug 修复、安全补丁和新特性。如果您使用的软件包的版本很快将不再受支持,那么您甚至可能面临“生命终结”的最后期限。

如果升级依赖关系如此重要,为什么很多开发人员不这样做呢?他们可能不知道怎么做,或者他们可能不理解升级的好处,或者他们可能觉得没有时间。或者,他们可能会害怕。

为什么开发人员害怕升级他们的依赖关系?因为他们觉得可能会弄坏什么东西。他们为什么害怕打碎什么东西?因为他们没有合适的测试。

当您有一个好的测试套件在您的代码库上运行时,您可以自信地升级您的依赖项。

在本文中,我们将讨论语义版本控制、升级依赖关系时的陷阱,以及如何有把握地升级依赖关系。我们还将使用一个小应用程序来演示一个好的测试套件如何帮助您在部署应用程序之前捕捉依赖性升级带来的重大变化。

语义版本控制

让我们简要讨论一下语义版本控制以及它是如何工作的。JavaScript 包通常遵循语义版本控制,语义版本控制由三个数字组成,分别表示包的主版本、次版本和补丁版本。因此,如果一个包被设置为版本2.4.1,那么它就是主版本2、次版本4和补丁版本1。

补丁版本通常包括 bug 修复和安全补丁。次要版本可以包括新特性。但是补丁版本和次要版本都不应该破坏或更改包的现有 API。主要版本可能伴随着重大更改,通常是通过删除一个 API 方法或重大修改代码的底层架构来实现的。

升级依赖项时的陷阱

如果软件包开发人员正确地遵循语义版本控制,那么这些软件包的消费者通常可以安全地升级应用程序中的次要版本和补丁版本,因为根据定义,在这些版本中不允许进行破坏性的更改。然而,一些包维护人员可能没有很好地遵循这个标准,或者可能在没有意识到的情况下意外地发布了破坏性的更改,所以您永远不能确定。但一般来说,升级补丁和依赖项的次要版本应该进行得很顺利。

这是你需要更加小心的主要版本。当将软件包从一个主要版本升级到下一个主要版本时,查看更改日志或发布说明以查看更改内容总是一个好主意。

有时候,主要版本中的重大更改不会影响到您,比如您没有使用现在已经删除的 API 方法。其他时候,更改将是相关的,您将需要遵循迁移指南,以查看为了正确使用新的主要版本需要进行哪些更改。对于大规模的重大变更,有时开发人员会非常友好地为您提供一个代码,一个执行大部分或全部变更的脚本。

好消息是,升级依赖项,甚至主要版本,不需要是一个可怕的经验。

用信心升级依赖关系

在升级依赖项时,具有高代码覆盖率的测试套件将使您受益匪浅。如果测试很好地覆盖了代码,那么测试应该会让您相信升级后应用程序仍然能够正常工作。如果所有测试都通过了,那么您应该相信升级进行得很顺利。如果有任何测试失败,您就知道应用程序应该关注哪些领域。

如果你的应用程序还没有测试,现在就开始编写吧!一组好的测试可以发挥很大的作用ーー不仅在升级依赖关系时,而且在重构现有代码、编写新特性和修复 bug 时也是如此。

即使有一个好的测试套件,在升级依赖项之后进行少量的手动测试也是一个好主意,作为一种附加的安全措施。毕竟,在您的测试覆盖率中可能存在空白,或者您没有考虑到的边缘情况。

如果您确实在手工测试期间发现了测试套件中的缺陷,那么您应该为您发现的问题编写一个快速测试,然后去修复这个问题。这样,您现在就有了一个自动化测试,以确保您发现的特定 bug 不会在将来再次发生。

演示时间

现在让我们考虑一个小的演示应用程序,它将帮助这些抽象的想法变得更加具体。这里我们有一个非常有用的应用程序,今天是我的生日。这个应用程序是最好的,最简单的,最快的方式来决定今天是否是你的生日。只要输入你的出生日期和今天的日期,应用程序就会告诉你今天是不是你的生日。

insomnia 加快版(用Insomnia来提升依赖性ーー充满信心)(1)

演示应用程序: “今天是我的生日”

好吧,我开玩笑的。但是,我们需要一个简单的应用程序演示的目的,所以我们在这里。

这个应用程序是用一个 Node.js 和 Express 后端以及一个简单的 HTML、 CSS 和普通的 JavaScript 前端构建的。我使用 date-fns 包处理日期,并使用 Insomnia 编写 API 测试。我能够使用 Inso CLI 从命令行运行 API 测试,我甚至已经将它们集成到 GitHub Actions 的持续集成管道中。很漂亮,我知道。你可以在 GitHub 上查看这个应用程序的所有代码。

代码中决定今天是否是你生日的相关部分转载如下:

JavaScript

const format = require('date-fns/format'); const express = require('express'); const Router = express.router(); router.get('/', function (req, res) { if (!req.query.birthday) { return res.JSON({ data: 'Please provide your birthdate' }); } const todaysDate = new Date(req.query.today) || new Date();

我们编写的三个测试的输出如下:

insomnia 加快版(用Insomnia来提升依赖性ーー充满信心)(2)

三项Insomnia测试都通过了

因此,让我们考虑一下在升级我们的应用程序使用的 date-fns 版本时可能要做些什么。首先,我特意使用了 v1.30.1,这样以后我们就可以升级到 v2.28.0。从 v1升级到 v2是一个重要的发行版,有着重大的变化,我们需要确保我们的应用程序在升级之后仍然能够正常工作。如果我们的应用程序在升级后坏了,人们怎么知道今天是他们的生日?

我们首先将 package.json 文件中 date-fns 的版本从 v1.30.1更改为 v2.28.0。然后,我们将运行纱线安装安装的新版本。

之后,我们可以进行测试,看看情况如何:

insomnia 加快版(用Insomnia来提升依赖性ーー充满信心)(3)

升级 date-fns 包后有两个测试失败

哦,不,我们有一些失败者!我们的三个测试中有两个失败了,看起来我们的 API 有一个糟糕的 JSON 响应。虽然处理失败的测试并不有趣,但是我们的测试已经证明在将 date-fns 从 v1升级到 v2时能够检测到一个问题。

如果我们进一步研究,就会发现 date-fns 中的以下错误: “ RangeError: 使用‘ DD’代替‘ DD’(in‘ MM-DD’)格式化每月的天数。”

回顾我们的代码,我们确实使用了 MM-DD 作为日期格式。查阅 date-fns 2.0.0版本的更改日志,我们可以看到其中一个突破性的变化是,在同时格式化月份和日期时,大写 DD 的使用已经被小写 DD 所取代。谢谢你的建议,更换日志!

现在我们可以在代码中进行简单的更改,如下所示:

JavaScript

const format = require('date-fns/format'); const express = require('express'); const router = express.Router(); router.get('/', function (req, res) { if (!req.query.birthday) { return res.json({ data: 'Please provide your birthdate' }); } const todaysDate = new Date(req.query.today) || new Date(); const birthDate = new Date(req.query.birthday); const todaysMonthAndDay = format(todaysDate, 'MM-dd'); const birthdayMonthAndDay = format(birthDate, 'MM-dd'); const isTodayMyBirthday = todaysMonthAndDay === birthdayMonthAndDay; return res.json({ data: isTodayMyBirthday }); }); module.exports = router;

然后我们将再次运行测试套件,瞧,所有三个测试都再次通过了。订单已经恢复,我们已经成功地升级了我们应用程序中的一个依赖项

结论

升级依赖关系很重要。不断更新意味着您拥有最新的 bug 修复、安全补丁和特性。通过定期更新您的依赖项(可能是每月一次或每季度一次) ,您可以避免在最后一分钟需要升级报废软件包的恐慌。

请记住,测试可以帮助您自信地升级。那你还在等什么?去写一些测试和升级你的应用程序的依赖现在!

,