“我只是修改了一个 if 条件,没有想到它致使持续集成失败,部署也所以失败,还影响了 QA 测试其它功能。”css
Web 应用的质量提高,是一个很是有意思的话题。咱们明知道有一系列的手段能够提高代码质量,可是限于多种缘由,咱们并不会去作。在我工做的第一个项目里,因为你们都是年轻人(Junior Consultant),咱们实施了一系列的基础措施,来提高应用质量,诸如写测试、追求测试覆盖率、运行预提交脚本等等。前端
在最近的这个项目里,咱们面临着相似的问题——须要提高项目的代码质量。因而,便想写一篇文章介绍一个相关的内容。这篇文章大体能够分为这几个部分:git
那么,让咱们继续回到老生常谈的 “Web 应用的质量问题”。bash
Web 应用一般面临着上线和质量之间的博弈——只要不影响用户体验,小的 Bug 每每对于项目来讲能够 “容忍” 的。这样一来讲能够早些上线,实现用户价值。除此还有其开发的影响:一个是敏捷方式的开发周期,一个则是能够屡次上线。markdown
故而,Web 开发与一些特殊领域及行业的软件开发不一样,在这些特殊的行业里,一个开发成本上亿的软件,可能只会运行、部署一次,不会有第二次机会,如原子弹的控制系统。还有一些类型的案例,就是智能汽车上的自动驾驶系统,稍有不慎就是车损人忙。至关于 Web 应用虽然更新困难,可它们仍是能远程更新的。可是在这些系统上,它们就更追求系统的质量,而不是开发速度。Web 应用部署失败能够回滚,虽然会带来必定的钱力损失,可是极少带来生命危险。app
所以在质量和速度方面,在 Web 开发上所以保持着一个微妙的平衡。编辑器
可软件开发不只仅只有质量和速度的问题,还有一个产品问题——即,能作出符合用户需求的产品。因而,就变成了质量-速度-需求,一个更复杂的平衡。为了交付出更符合用户需求的产品,就不得不常常作一些需求变动。而取决于这些变动的时间,它每每会影响到代码质量和开发速度——实现一个需求的时间越短,那么其测试的时间越短,Bug 出现的可能性就更高。过去我遇到过,今晚上线,下午临时改需求。可想而知,测试人员是没有时间测试的。函数
在这个时候,持续集成只能显式地告诉咱们,咱们的测试挂了,咱们的某些功能 broken 了,咱们不该该部署这个新版本。然而并非持续集成出问题了,咱们就不能部署,咱们仍然仍是能部署的。工具
Blabla,那么问题来了,最有效的方式呢?post
用于保证这个项目的质量,在代码提交以后,会通过一系列的测试:
若是只是宏观来看一个项目的测试的话,那么在一个敏捷项目里,测试能够分为这么几个阶段:
若是一个 Web 应用能通过这么一系列的测试,那么它的质量在必定程度上是获得保障的。因此,开发人员若是不想活得过久,就能够 “不负责任” 地直接把功能扔给测试人员。笑~
但是,在有一些公司时吧,Bug 率但是会影响绩效的,又或者是有这么多 Bug 看上去不那么专业,等等 blabla。
言而总之,总而言之,开发人员本身写测试会更友好一些。按照测试金字塔理论来讲,咱们须要三种类型的测试:
对于一个前端项目来讲,咱们一般只须要两种:单元测试
和 E2E 测试
。实际上,理论上应该还有 UI 组件的测试
,可是通常而言,咱们在选用 UI 组件的时候,会考虑到组件的稳定性。
但是在多数国内公司里,写测试每每是不可能的。退而求次,咱们就须要一种更简单而友好的方式,来作这样的事情。
在代码提交以前,咱们还能够进行一些常见的操做:
现代的编辑器(使用相应插件)、IDE 能够提升很好的技术手段,在开发的过程当中静态代码分析,并随时提升建议。如 Intellij IDEA 和 WebStorm 就会根据 TSLint,来提醒开发者 TypeScript 代码的一些规范问题。
这些分析工具主要进行一些代码上的分析,如《全栈应用开发:精益实践》一书所说,通常会进行以下一系列的风格检测:
而这些规范,若是没有强制,那就是个游戏。因而,咱们一般会依赖于 Git Hooks 来作这样的事。对于一个使用 Git 来管理源码的项目来讲,Git Hooks 能够作这么一些事情,能够在 .git/hooks
目录下查看:
applypatch-msg post-merge pre-auto-gc prepare-commit-msg
commit-msg post-receive pre-commit push-to-checkout
post-applypatch post-rewrite pre-push update
post-checkout post-update pre-rebase
post-commit pre-applypatch pre-receive
复制代码
通常而言,咱们只会在两个阶段作相应的事情:
pre-commit
,预本地提交。一般会在该提交以前,进行一些语法和 lint 的检测。pre-push
,预远程提交。一般会在该提交以前,运行一些测试。因而,在咱们的这个前端项目里,咱们就又写了这两个 scripts
。对应的实现以下:
{ "precommit": "lint-staged", "prepush": "ng test && ng build --prod" } 复制代码
在 precommit
时,咱们配合 lint-staged
和 prettier
来进行代码格式化:
"lint-staged": { "src/app/*.{css,scss}": [ "stylelint --syntax=scss", "prettier --parser --write", "git add" ], "{src,test}/**/*.ts": [ "prettier --write --single-quote", "git add" ] } 复制代码
事实上,使用 ng lint --fix
也是一个不错的方式。
随后,咱们在 push 代码以前,即 prepush
,进行了测试及 Angular 的构建 production 的脚本。因为单元测试运行得至关的快,它能够在几分钟内完成,快速对问题作出响应。而不是等到持续集成出问题时,再去修复。
可是 Git 提升了这一种的种选项,也提供了一个 --no-verify
的参数。它可让开发者不须要进行上面的验证,就能提交代码。
咱们每每没法阻止别人作这样的事情,特别是当出现多个团队协做的时候。
本来,我想将标题取为 “有风险的提交”,可是我以为危险的提交更为可靠。
常见的有要去吃饭了、要下班了、要开会了等等,临走前提交了一下代码。功能可能自己没有问题,可是它 block 后续的一系列行为。
固然了出现不可坑的因素,如地震、火灾等的时候,就不须要考虑这些事情了。
只是有了这些规范和实践,能够帮助咱们开发出更稳定的 Web 应用。
开发速度和质量,是一个难以平衡的天平。在不一样的时间里,咱们应该作不一样的技术决策。