gongmingqm10

Life is a journey, not a destination

Work in Dallas

| Comments

时光匆匆,算上实习期来ThoughtWorks工作已近一年。如果技术方面来看,我提升的主要是广度。但是从敏捷实践角度来看,我正在也将继续朝深度上提升。

敏捷这个词,大学期间或多或少听过,大体的印象是软件工程学的一些术语,之后在项目中才开始慢慢实践。我前后经历过三四个项目,虽然每个项目待的时间不长,但是却又想能够和不同的团队,面对不同的客户,也有幸能够在不同的国家体会不同文化下的敏捷实践的标准。

由于敏捷包含的方面很多,作为Developer的我,也会主要从Developer的角度,结合自己的想法来谈自己在这一年对敏捷的认识。此文不是软文,只是自己闲时的一点纪录。不喜求轻喷。

开发驱动测试(DDT)

加入TW,很长一段时间我一直都抱有这个想法。当时虽然已经在项目上工作,在Code Review的压力下也会偶尔用开发驱动测试(DDT)。因为别人告诉我不写测试的程序员不是好程序员,这个句式怎么听起来和不想当将军的士兵不是好士兵一个道理。听起来是很多道理,但是真正实施的时候呢,我开始犯难了。

测试的痛点在哪里?我常这样问自己,其实我有时也不知道痛点再哪里,只是不太会写。为什么不会写?因为我连怎么实现都不知道,怎么会写?通过这样反推过来也就是只有知道怎么实现,才知道怎么写测试。这个观点对吗?

只有知道怎么实现,才会知道怎么写测试。写测试有点作秀的嫌疑

这是我曾经的观点,先别批评我逻辑性或者对测试的理解有多差,因为这是我过去的想法。如果我现在来看这句话的话,我会套用那句很通用的 It depends。肯定有人会反驳,那到底取决于什么呢。

以我现在的认知来看,我之所以不知道在实现之前怎么写测试,往往是由于要测试的对象本身很大,很杂,一个方法要管的事情太多了,所以我不知道怎么测试。其实回过头来想想,当一个东西连测试都很难写的时候,是不是意味着我所要测试的函数做了太多的事情了呢。

  • 重构里的术语来讲,自己对类或者方法的设计不太合理,导致要测试的内容过多而不知从何下手。
  • 另外一种角度来看,如果一个测试很难描述出测试对象的时候,为什么不可以多增加几个测试,循序渐进的去添加测试。
  • 如果以上两种情况你都不属于,很不幸有可能你在动手之前应该查一下,确保自己清楚这个被测对象的职责,代码上基本的实现思路。

当然对于某些情况,我确实可以先写测试再写实现。例如一个简单的计算器的加法,测试中我知道给函数两个输入值,我期望能够输出某种结果。在这种情形下我知道怎么写测试因为要测试的对象足够简单,负责的事情足够清楚。这种有结果输出的测试也是相对简单的。这时候我甚至完全不用操心别人究竟怎么实现的,我只需要用强有力的测试来验证结果即可。

知已知彼,百战不怠。你之所以知道怎么用测试驱动开发,因为你在测试之前已经在心中将这个函数设计和实现了一遍。如果你和我一样达不到这种境界,那可能就是对这块知识了解确实太少,意味着你该自己补补了。

测试的价值

测试到底有没有价值,得看你是怎么理解价值的。从科学的角度来看,肯定会有人用实验来证明写测试能够减少Bug发生率,虽然前期写测试花费时间,但在后期却能够节约时间。这种最常见的来证明敏捷实践标准的理论数见不鲜,但是有时却很难是刚入门的人信服。

从我经历过的项目来看,有测试或者没测试的项目都有接触过。对测试的价值也有自己的认识。先不管别人的研究结果如果,单从开发人员开发时间来考虑,测试的确会花费更多时间,相当于你要写两份代码,一份实现,一份保证已实现的功能不被后期修改破坏掉。当然测试的确可以提高产品质量。

什么时候我不会写测试,虽然我信奉测试是产品质量的保障,但是有时我不一定会写测试:

  1. 交付周期过短的项目,并且是在没有引入测试的项目基础上开发。这种项目在国内客户中比较常见,多半是对原来的项目增加一个模块,并且之前的代码没有测试。这类项目的特点是周期短,功能相对较少。敏捷实践是敏捷实践,但是没必要固执的和自己死磕。因为也许客户并不在乎你有没有测试,只在乎产品能不能按期上线。
  2. 功能变化过快的互联网产品。一些初创型公司在做产品时往往信奉天下武功,唯快不破,特别是公司人手不够,功能较多,并且在每两周一次的迭代中功能变化过大的时候,维护测试变显得有点复杂。当然并不意味着任何的测试都是多余的。这里有个测试力度的问题,具体得靠自己的把握。

什么时候我会在项目中引入测试呢?

  1. 项目周期相对较长,客户经济上有能力承担多几个开发者带来的成本;
  2. 如果是在客户原有系统上开发,之前的系统就有一套测试体系,无疑我们在增加代码的时候应该增加测试。而且尽量沿用之前已经构建好的一整套测试体系。
  3. 一个从零开始的项目,并且有可能建立长期合作的客户。这是TW的核心竞争力,卓越软件质量的前提。客户不提,我们自己也应该做到。

写测试是一种好习惯,至少作为一个合格的程序员,应该写测试。如果你是一个Github上代码贡献的活跃者,在为自己写代码的时候,请尽量为自己的代码加上测试。Travis就是这样一个免费的提供CI服务的平台,如果你想为自己的代码加上测试但是又不想自己去搭建CI,可以试试Travis。

回归正题,测试的价值在于你多看重软件质量。测试有时会消耗一定的时间,但是有测试保障的软件在质量上的确可以提高好几个层次。是否写测试则需要结合你自己的项目实际情况以及客户本身而定。

如果你经历过国内客户和国外客户,那么你应该能够体会到他们对于软件质量的不同态度。当然所有人肯定都希望软件交付质量最高,时间最短。但是当两者需要权衡的时候,国内客户比较在乎的会是进度,国外客户比较在乎的是质量。所以质量和进度之间需要找到一个平衡点。

从国内外客户的差异,其实也可以联想到国内外软件开发者的差异。到美国这边与美国这边的同事办公之后发现,这边的同事对于测试的重视程度要远远高于国内的同事(不是黑ThoughtWorks China的同事们)。You can not do anything when you write test. Test first,这是美国这边一位senior的同事和我pair的时候说的。自己曾经那些不好的编程习惯到了这边是应该好好改改了。

在美国这边工作曾经有几天我对项目上的测试有点质疑了,因为有些地方实在测的太细,几乎是想用测试覆盖掉每一行代码,并且有些代码还被多个测试覆盖。后来偶然的聊天中,同事告诉我 I think I don't write so much meaningful tests in our code, some tests seems to be useless. And Jered is more expereienced, he pointed out.,虽然这是一种谦虚的说法。但是这却告诉我,写好测试才能真正体现测试的价值。

我姑且称那些永远不会fail,或者基本没有测任何有意义的东西的测试为僵尸测试,这种测试太多了直接影响整个测试的可阅读性。好的测试应该可以通过函数命名,测试输出结果的判断来提供文档的功能。所以不要用数量来堆砌测试,努力写好测试是关键。

敏捷团队角色

敏捷开发中很重要的一部分是团队角色。一个敏捷团队主要有应用开发工程师(Dev),业务分析师(BA),质量保障工程师(QA)等。在项目的Story估点之时,除了有BA和QA的参与,Dev的参与也是很重要的部分。BA和QA主要从业务上评估,Dev主要从技术上评估,这种多人参与过的估点才是有意义的。

同样一个Story制定的时候产品设计效果图和可验证的Scenario是很重要的。Scenario的制定其实考察的是BA/QA对业务以及实际使用场景的考验。这一点我在Mobile端体会尤其明显。因为Mobile端更重交互,对于用户可能有的行为,制定验收标准是就应该考虑清楚。所以这时候BA不仅仅承担一个业务分析的角色,还承担着用户的角色。

Dev和BA沟通Story的时候最简单的情形是以用户为媒介。无论业务分析还是开发实现,最终都是为了给终端用户一个具有某种功能的产品。

有时我会想如果让Dev转型当BA,那这个BA一定很能了解功能的实现者。后来发现这种想法本身存在一定的问题,因为不管这个BA懂不懂具体的实现,BA/QA应该懂的是用户,应该懂得是平台特性以及用户特性。无论是Mobile和Web,抑或是Android和IOS,无论是敏捷团队的何种角色,你都得尝试去了解这个平台的特性,了解终端用户,才能够做出更好的决策。

结语

作为ThoughtWorks咨询师,我们应该知道公司的核心竞争力是什么,我们也更应该尝试去影响客户,给客户带来价值。也希望新的一年里自己能够在敏捷实践上做得更好,能够帮助客户,影响客户。

We think disruptively to deliver technology to address our clients’ toughest challenges, all while seeking to revolutionize the IT industry and create positive social change.

Comments