-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Sharing: Write a blog again #28
Comments
文章目录
回顾 Preface咳咳,上回我们完成了 Udacity 的第一个代码作业,同时也留下了一些痛点没有解决,这篇文章,我们将着重解决这些痛点:
以上几个问题,其实提的都是团队开发规范的问题。在公司的大项目中,由于要协调多人的团队开发(说白了就是对人布朗运动的不信任),我们需要一些约定和规范,比如每个方法代码不能超过多少行、循环不能超过多少层,等。这里,我们更多是使用这些工具 来增强开发体验,把尽可能多的工程活动(流水线、checkstyle、单元测试)都自动化起来,通过它们来提供 快速反馈 及 强化开发信心。 以上问题的解决方式分别为:
极致的开发体验 Superb Developer Experience触手可及的任务列表管理 GHI + Issues: Tasking List Management in Hand这是我新发现的工作流,尚不是很成熟,但令人眼前一亮。它主要解决的问题是更随手可得的 tasking 列表管理。开始每项工作之前,我们一定要分解出一个任务列表,而这个任务列表,你要保持更新,做完了一项要从任务列表中删掉;同时,这个任务列表一定需要更触手可及。前面的文章 是直接编辑 Github Issue,这样既分散精力, Github 也不是一个好的编辑器。如何让 Github issue 更触手可及呢?我想到了命令行。记得之前前端早读课推送过一篇文章,提到 ghi 这个工具,我就一搜,发现这是一个完美的 Github issue 命令行工具。 使用了 ghi + Github issue 来描述任务列表以后,这个工作流就变成:
如上,Github 上(或在其他地方)分解出来的任务列表,最后变成 Github issues,被 持续交付的最后一公里 Travis Dashboard: One Last Mile of Continuous Delivery持续交付(Continuous Delivery)的目标是,每一次提交、构建都是完整可交付的产品代码。实现上,大多 CI/CD 工具都提供了监控界面,这样我们可以快速看到某次是失败还是成功,了解产品的健康状况。为什么我们提倡保持每次提交的代码都是 ready for production 的状态,并且任何时候提交挂了就要马上修复呢?这样一方面可以让我们对产品保持信心,一方面也是让软件开发变得更简单,降低了调试成本。试想,如何一个构建最近20次都是挂的,你怎么知道导致构建失败的问题是什么呢?你怎么知道这20次提交中有无引入新的 bug 呢?你又怎么知道新增的代码有无测试和代码检查的覆盖呢?如果允许一个产品长期是挂球的状态,长此以往必然使开发对产品、对日常开发失去信心,充满沮丧。反之,如果我们保持流水线每次都是绿的,那么即使某一次提交把它挂掉了,我们也能很快找出这个提交、定位问题,很快地修复问题,从而对维护代码的质量起到正反馈的作用。 这里我使用的是 Travis Pipeline,它是对个人免费的产品,并且配置简单,界面相当友好。可以看到上面的提交历史中有一次红掉的提交,这样你很快就可以定位到,是 #25 的 issue、添加了 ESLint 的 提交、样式检查自动化 Git Hooks + ESLint: Automated Commit Message & Styling Check提交信息也是一门小学问。好的提交信息可以简易地代替代码阅读,让你就像在读小说一样读代码库,找 bug 的时候(什么?你问有了上面的持续集成/交付(CI/CD)实践为什么还需要找 bug?这是一个好问题!)也可以通过阅读提交信息来快速定位可能有问题的提交。另外,当团队大了以后,每个人可能有不同的提交信息书写习惯,此时团队间统一提交信息格式就尤为重要。即使是一个人的项目,强制规范提交信息也是有必要的,这不仅有益你养成良好的小步提交习惯(大步提交,提交信息必然无法写好),而且也是程序员的自我修养。 在 Udacity 的项目中,官方也有一份 Git 提交信息样式指南,其中的前缀规则非常有用,我已经用到我的项目上。现在,我自己的提交规则是:
比如下面就是一个符合提交规范的提交信息:
但是问题来了:你怎么保证你的每次提交都能遵循完全相同的提交格式呢?这不仅要求你对提交规则烂熟于心,而且有时人为的错误(比如打字打错等)更是无法避免的,有没有自动化的方式来辅助检查提交信息呢?当然有。答案就是 Git 原生提供的 Hooks。 Git Hooks 是比较大的系统,这里不深讲 #!/bin/sh
commit_regex="\[Linesh\]\[#\d*\] (Chore|Feature|Fix|Docs|Style|Refactor|Test): [a-z]"
error_msg="Aborting commit, please double check your commit message."
commit_msg=$(cat $1)
if ! echo "$commit_msg" | grep -E "$commit_regex" ;
then
echo "$error_msg" >&2
exit 1
fi 调试这个脚本可费劲了,说到底还是我的 bash 基本功不扎实,基本是边 stakeoverflow 一边调试的节奏。说是如此,还是遵循小步试错的思想来的,比如一开始我是把 Udacity Styleguide 里有一条,函数声明后面不要有分号 模块化的系统 ES6 Modules: Moduralized Units没有模块化是 JS 一直的痛啊,从语言诞生即如此。我们为什么想要模块化呢?因为这是我们管理一个软件系统复杂性的方法,有了它我们可以分别对每个模块进行单元测试。好在 ES6 之后,标准终于提出了一套实现模块化的规范,只不过最新的 NodeJS 还不支持,因此,我们要使用 Babel 等转译器(transformer)来对使用了模块化的代码进行转义。这里我不多啰嗦了。只需要通过 npm 引入 babel-core 和一些语法 preset 即可,同时测试代码也需要被转译。 .babelrc
{
"presets": [ "es2015", "stage-0" ]
} package.json
{
...
"scripts": {
"test": "mocha test --recursive --compilers js:babel-core/register"
}
...
} 小步前进的测试驱动开发 Mocha/Chai/Sinon: Baby Step Test Driven Development有了模块化,有了测试工具,再加上一纸任务列表,我们终于可以进行 TDD 了!简而言之,TDD 是一种测试先行的方式,也即你先写一个测试来描述你的意图,那么测试必然会挂,然后你再通过最快最小的产品代码来实现需求,让测试通过变绿。最后,在测试的保障下,进行必要的重构,消除代码的坏味道。 TDD 是一种设计工具,是一种编码的方法论。它能带来的好处有:
TDD 如何保证你做完了正确的事情呢?换个问法,你怎么知道你做完了 rubric 上声明的所有需求了呢?有同学可能会说,玩一下游戏不就知道了。也没错,不过缺点是需要手动测,并且往后每动代码就必须回归全测一遍,慢。也有同学会说,依据就是前面的任务列表呀,任务列表做完了,我就很确定所有的需求都做完了,因为我的任务列表完整、穷尽地覆盖了 rubric 上所有的需求。很好,思路是对的。我们 tasking 出来的任务列表最后会变成一个个的测试用例,那么,如果所有的测试用例都实现了,同样也证明我的任务列表完全实现了,也就等价于需求完全实现了。测试用例实现没有,这个就非常可视化了,见下图,1秒证明我实现了所有需求,并且自动化的单元测试可以在以后回归的时候重复多次地运行,成本极低。 关于 TDD 的深入论述和实践,可以参考上篇提到的一些资料。这是额外的话题,有兴趣深入、了解、质疑的同学欢迎加我微信或群里讨论哈~
刻意练习,持续进步 Toggl: Measurable Deliberated PracticeToggl 是我使用的一个计时工具。为什么要对任务实现计时呢?如果有同学戳进去了上面👆的那篇编程的精进之法,就会看到作者对刻意练习的观点:通过预估用时 - 实际用时的对比来定位实际耗费过多时间的瓶颈所在。Toggl 可以对整个项目的完成时间做一个记录。当然,类似的计时需求可以通过 IDE 自带的 time tracking 功能来做到,都是可以的。同学们有什么更好的工具也欢迎来分享。 项目完成概览 Overview of Project Accomplishment
如何使用 TDD 完成代码 TDD in JavaScript突然觉得这部分没什么好说的,TDD 怎么做就是怎么做,说了似乎就变成纯 TDD 贴了。有同学可以给点建议写什么吗?或者,有兴趣的同学可以看一下我的 PR 和提交历史,非常欢迎你的反馈! 刻意练习 Deliberate Practice
下次目标:核心功能总用时进3小时;基础设施代码搭建进1个半小时。 刻意练习计划:
|
EthanLin-TWer/ethanlin-twer.github.io#141
The text was updated successfully, but these errors were encountered: