CI: Continuous Integration,持续集成
如果说CI是共产主义(我们先假设共产主义是可以实现的),那么“自动化测试”、“自动化部署”们则是社会主义阶段。在通往CI的路上,似乎后面这两者所需要的时间、努力更长(当然,前提是我们已经有了像Jenkins、Buildbot解决了“持续”问题的利器。
打另外一个比喻,CI就像大脑,自动化测试、自动化部署分别是两条腿。大脑要支配身体走路,“绝对的”依赖于这两条腿。这两条腿的健壮程度,决定了CI的期望——快速走路,能否实现。
那么,自动化测试、自动化部署难在哪里呢?
自动化测试
“自动构建”是前提,不过这个步骤需要的工作较少,所需的工作也是基本固定的,一次完成了后期基本不需要再大动。
自动化测试,测试代码跟工作代码联系非常之紧密,随着工作代码的增长也需要增长(否则就没有啥意义了)。并且,写单元测试的话,对工作代码及工程会提出更高的要求:分层、分模块、各种模式、封装,等等。这就是对程序员最本质、最大的挑战。大多数程序员(尤其是经验不足的,不过这也怪不得他,没经验嘛),写代码的唯一诉求是:实现功能。不管代码的封装性是多差、可复用性是多低……完全置之度外。用我最初参见工作时前辈的说法就是“一锅粥编程”。别人拿到他的代码,看不出明晰的概念、界限,“没地方下脚”。可想而知,他对代码是没有清晰的层次之分的,自己维护自己的代码恐怕也得踮着脚走路,战战兢兢,一个不小心就踩在shit上了。
抽象,是一种能力,而且是程序员的核心能力要求。这句话永远都不会过时,只要地球上还存在编程这个职业。
事实上,写单元测试对程序员的要求,比实现功能还要高——要求你对工程持续不断地划分、抽象,以保持整体的统一、脉络清晰等。也正是以为这个要求层次更高,所以那些“小富即安”的程序员们没有勇气、没有毅力去将自己的能力提高的这个层次。所以,在国内的大多数公司中单元测试都难实施起来。“千程序员易得,一架构师难求”。只有那些有架构师潜质、志向的程序员,才会不断提升自己吧,也许。
这里顺便谈一下对“没那么多时间进行单元测试”这个说法的质疑。程序员们往往认为,进行单元测试需要多花很多时间,在项目时间紧急的情况下就不应该进行。事实上,国内的公司哪个项目不是在“时间紧急”下呢?所以,做不起来的责任就推给了时间紧急,推给了市场,推给了老板。真的是需要多花很多时间吗?就个人的体验来看,无论从开发一个功能当前的时间看,还是从长远维护所花的时间看,单元测试都不会多花时间。长远的情况,就不用说了,都会承认是划算的。当前的情况,来说说。
其实单元测试代码没多少,比起你调试、改bug花的时间来,写那几行代码的时间根本不足虑。有一个词叫“即时反馈”,即你有一个动作,马上可以看到其产生的效果。你即刻根据这个结果是否符合你的预期来进行调整或进行下一步操作。心理学认为,这样的“紧密互动”的过程容易让人产生愉悦的情绪,从而提高你对类似这样过程的兴趣,进而提高你的能力,进而提高生产力。单元测试,能尽可能地缩短你“写一段代码,检查其效果”这个过程的周期,从而让你在编程时很兴奋,很有效率。而只知道让偌大一个产品运行起来,改一句代码也得启动、一系列操作、看效果(这是bug描述的步骤),这样的做法会让你做很多重复的工作,还会让你的大脑多数时间处于等待、闲置状态。这样的过程恰恰比较难出现兴奋、高效的情况,相反还会让人腻烦、排斥,更降低了生产率。
要说“多花时间”,其实也不假,不过多花的时间是用在提高程序员本身的能力上,而不是工作量上。所以,与其说是不愿多花时间,不如说是不愿提高自己能力,为自己不思进取找的理由。
自动化部署
【本人是客户端开发,对服务端仅知皮毛,如有不妥请指正。】
服务端程序员也需要单元测试、接口测试等,本质上跟上面所述没有区别。
自动化部署,应该包括:
- 服务器环境搭建
- 程序代码同步
- 数据库更新
这一系列工作一般是由运维工程师来完成,他们似乎是没有编程的经验。就自己公司的实际情况,部署这件事还是手工完成的。不知道这块工作的难点在哪里,没有实际经验,不便多说。