《编写可测试的JavaScript代码》——1.2 代码是让人用的

本节书摘来自异步社区《编写可测试的JavaScript代码》一书中的第1章,第1.2节,作者:【美】Mark Ethan Trostler著,更多章节内容可以访问云栖社区“异步社区”公众号查看

1.2 代码是让人用的

最近这一理念已经深入人心,我们不会弱化这一理念。我们编写的代码不是让电脑用的,而是让人用的。编写软件是一种亲身实践的业务。电脑只是接收比特数据、JavaScript、C+、Java、Per、Lisp或任何其他语言,都是将其编译到CPU极其有限的指令集中。CPU不知道它运行的是“编译”的语言还是“解释”的语言。CPU不在乎注释、分号或空格。CPU对人们使用的各种计算机编程语言的结构、语法、语义都是兼容的。JavaScript程序看起来就像是C++程序,而对CPU来说,C++程序又像Perl程序一样。

在最底层,项目的成败与否,与CPU执行的机器语言代码有关。但我们很少看到这一点。我们只看到原始代码。CPU不在乎我们想做什么,那是人要关注的事情。

软件始于意图。你想要做什么?这段代码要完成的是什么?为什么要编写它?这些都是你或你的同事每天都必须要问的重要问题。你将最初的意图(“什么(what)”和“为什么(why)”)转换到实际代码中,即“如何(how)”。本书主要关心的是“how”。首先弄清楚你想做什么,以及为什么要这么做,这是“如何”做工作的第一步,但实际处理“how”工作时,却发现其间关联不断。编程语言书籍可以在最底层的“how”上帮助你;而软件模式书籍可以在更高层次上帮助你。而本书则是希望在顶层能够清楚地解释“how”:如何编写可测试的代码,以及如何测试它。

但我们在了解“how”之前,理解软件开发中的“what”和“why”是非常重要的。

为什么要编写可测试的代码?可测试的代码是什么?

1.2.1 为何要编写可测试的代码
Douglas Crockford说过:“编写软件是人类做的最难的事情”,也就是说,软件要尽可能人性化是极其重要的。可测试的代码更加容易测试,意味着它更加容易维护,易维护则意味着它能让人(包括自己)更加容易理解,更加容易维护,从而又使得测试变得更加容易。

我们绕了一大圈,但这是一个良性循环。没有柏拉图式的完美代码,可测试性、可维护性和可理解性是互相关联的,对于这些内容是什么以及如在软件里应用它们,大家有很多的看法。然而,在可测试的、可维护的、可理解的代码上发现Bug并修复Bug则会简单得多。作为程序员,平时在自己的代码或别人的代码中查找并修复Bug,至少要花一半的时间,所以要善待自己,并让自己在这个过程里尽量轻松。

为什么要可测试的
测试代码,不管使用哪一种类型的测试,都是一件必须要做的事情。测试工作会由你或其他人来完成,即使是使用你的程序的最终用户。没有任何代码在第一次或后来的编写中是完美的,即便是最简单的JavaScript程序。

x=x+1;
这种程序也可能会有问题。如果x是一个字符串?或者x是无穷大?以及x是一个对象?程序会变得越来越复杂,我们只能期望测试最常用的路径。穷举测试是不可能的。编写容易测试的代码,或“可测试的”,至少可以让测试人员有机会完成最基本的且能永远保持先进的测试。

为什么要可维护的
程序员并不总是从零开始编写代码。有时候,我们的任务是调试和维护别人的代码。别人可能已经离开很久了,就像我们离开以前公司编写的代码已经很远了一样。在维护别人的代码时,别人可能也在维护我们的代码。除了让一切变得更美好外,可测试的代码也更易于维护。通常,我们对于代码变更带来的影响没有总体的了解,编写由可测试代码组成的测试可以帮助我们了解看似很小的变更所带来的影响。一旦知道代码如何工作—尤其是做修改以后会发生什么事情—我们就拥有了可维护的代码。这样的代码我们不必担忧。我们可以更容易地与团队成员分享这些代码,我们不需要重写代码也能完全理解它。程序规模越来越大,而完全了解代码知识的人在迅速减少。即便看似无关紧要的变更影响了其他功能,也会让这些人感到惊讶。

为什么要可理解的
高质量软件的第三个特点与其他两个特点交织在一起,就是阅读并理解代码的能力。理解一段代码的用途时,需要花多长时间?显然,能够对代码进行测试(以及为其准备测试)可以在很大程度上帮助理解代码是在做什么。但是,通过看一下方法或函数,能否不仅理解作者的意图,也能理解“如何”吗?如果不能理解自己6个月前编写的代码或者别人写的代码,那么代码就有严重的问题了。阅读一段代码后要了解,它不仅要令人满意,而且还要适当地满足工作需求。相反,如果我们写的代码自己都不再明白了,那么我们就失败了。代码是让人理解、维护和测试的。我们为别人写代码,这意味着我们的同事必须能够相对快速地理解代码。如果不理解代码,就无法进行测试或维护。在这种情况下,代码通常会被全部重写。我们可能扔掉垃圾代码,或者可能扔掉99%没有Bug的代码,但谁又能知道呢?如果没有可测试的、可维护的以及可理解的代码,那它就是垃圾。

1.2.2 什么是可测试的代码
所以究竟“什么”才是“可测试的”代码?“可维护的”代码看起来是什么样子?什么样的代码又是“可理解的”的代码?让我们深入挖掘一下这些问题。通过本书,我们会看到很多例子,展示这些内容是什么样子。

什么是可测试
可测试的代码就是容易被测试的代码。我猜大家会很惊讶!但是怎样让代码更易于测试呢?一般来说,使代码易于测试的特性,同样使代码易于维护,以及更容易理解:短小但也不太复杂的代码、完整的注释,以及松耦合。这些特性更让代码具有“可测试性”。利用可测试性特性和测试工具,可以让代码更具有可测试性。

什么是可维护
可维护的代码是一种可以移交给其他团队成员和同事,并便于接手和过渡的代码。具有良好测试并容易理解的可测试代码,比复杂的、不加注释的且没有测试的代码更容易维护。可维护的代码可以存在于一个完整的产品生命周期:产品从一个人转到另外一个人手里时,不需要部分或全部重写。可以修复和更改代码,而不必完全理解所有的代码,要有信心自己所做的修改不会影响别的功能,这样的代码就是可维护的代码。

什么是可理解的
看一段代码—不管是一个函数还是一段更小的代码,要花多长时间去理解?需要原作者一步一步解释一下吗?或者能在合理的时间内“理解”它吗?简单的、小型的且有注释的代码往往更加容易理解。通过单独运行来测试关于代码的假设,也能大大有助于理解。最重要的是代码可理解;否则,它将会被丢弃并重写。

1.2.3 如何编写可测试的代码
理解“为什么”和“什么”才能得知“如何”。这本书主要是关于如何编写、测试并维护可测试的、可维护的以及可理解的代码。显然,对已经具有可测试性、可维护性以及可理解性的代码进行测试和维护,可以让工作变得更简单。有了这个坚实的基础,可以让我们更富有成效,富有成效的人是快乐的,快乐的人也是富有成效的!这是一个良性循环,我喜欢良性循环。

如何编写可测试的代码
从头开始编写可测试的代码更容易一些(所有事情从头开始做都更加简单,不是吗?)。一些开发方法,比如TDD和BDD,可以产生可测试的代码,但也不是必然的。这是因为给代码编写测试不会自动让代码变得可测试。然而,从一开始的时候就关注测试,写出的代码比从头到尾都没有测试的代码更具可测试性。我不会要求大家在编写代码的时候使用TDD和BDD;但是,我认为从头就开始测试是一个很好的想法,我相信编写可测试的代码,有必要不断地进行测试。先编写测试或编写UI并非编写可测试代码的必要条件,但先编写单元测试(TDD)或集成测试(BDD)是编写可测试代码的一个基本概念:代码执行和测试,越早越好。在TDD和BDD之间,我要提出第三种方法:测试循环开发(test-while-driven,TWDD)。测试和代码是鸡生蛋和蛋生鸡的问题:有第一个,另外一个接着才会有—也就是说,不要一点代码都不写就编写大量的测试,也不要编写了大量的代码而一点测试都不编写。而是要编写一段代码后,就开始编写一段测试;或者编写一段测试后,就开始编写一段代码。

再说一下,这些方法并不一定能够编写出可测试的代码,我们仍然可以编写大量没用的测试。在一点一点编写代码和测试的时候,记住要考虑到大局:编写短小、最小依赖和最低复杂度的可隔离的代码块,这种思想是本书的精髓。

如何编写可维护的代码
可以以实现可测试代码的相同方式,来实现编写可维护的代码:编写短小简单的、可隔离的代码—短小,是因为代码行数越少,错误就越少;简单,是因为简单的代码更容易维护;可隔离的,这样在代码修改时,对其他代码的影响才会最小。在本书中,我们将探讨几种能让代码短小且可隔离的方法。

如何编写可理解的代码
不足为奇,要编写可理解的代码需要遵循相同的原则。代码越简单越容易理解。有测试的代码使我们能够进一步了解代码的意图和内部运作机理,注释可以提高可理解性。

编写代码类似于创作小说章节:多个小章节比几个大章节更容易理解。冗长的注释(方法前插入的注释块)和代码(选择有意义的变量名、遵循最佳实践、遵循一致的编码风格,等等)可以提高可理解性。负责维护代码的同事也不是白痴,给他们一些标示帮助他们理解代码,这样我们的代码才不会被丢弃和重写。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值