Category: Chinese

  • 关于软件测试:持续集成测试

    讲完了单元测试,我来分享下个人感觉另一个开发团队的重要测试步骤:持续集成测试,continuous integration testing。 稍具规模的软件开发,不管是商业或开源,一般是由一个团队来完成。团队写软件,必然会有一系列的分工。比方说,张三可能会写一些处理客户订单方面的library, class,和/或function;李四会写库存管理方面的代码;而王五负责物流和采购;等等。当然也不能排除张三发现李四代码内的问题进而修正的现象。我们在这里假定队里的工程师们已经统一使用一种单元测试机制并且会写单元测试。但最终我们要把这些代码通过代码库整合集中起来,确保作为一个整体,这些代码可以通过所有单元测试,没有冲突和编译错误,并且编译好的binary/executable符合事先订好的规范。这种源代码的整合、总体通过所有单元测试、代码链接和编译以及编译后的一些测试,即为集成测试,integration testing。 在团队开发环境里,各团队成员写的部件会有依赖性。如果我们数天、一周、甚至更长的时间里才做一次代码集成,就很可能会遇到以下情况:来自不同成员的代码部件可能有冲突,界面和生产环境的变化没能及时得到沟通和传达到每个队员,一部分的代码故障修复造成了其它部分的故障,等等等等。这会引进bugs,造成部分或全部的代码回滚,代码的不可编译,甚至拖延产品的发布或升级。为了解决这一常见问题,我们需要尽可能早、多次、自动化地运行集成测试。持续集成测试,即continuous integration testing,就应运而生。 自动化的持续集成测试由软件来完成。现在业界有不少continuous integration testing的工具,开源和商业的都有,像Buildbot(Python写成),Jenkins(Java写成),TeamCity,CruiseControl等。在本文底下我会给两个实战集成测试链接:一个是MariaDB的,用的是Buildbot;一个是Percona的,用的是Jenkins。读完本博后你可以到那两个网站看看,可以分析出他们的集成测试都做什么,有什么报告等,希望对你有所启发。集成测试机制一般有以下特点: 1. 和代码库挂钩。代码提交/check in/commit会自动触发集成测试; 2. 除了代码提交的自动激活测试外,一般可以安排时间定期来做集成测试,比如每天晚上一次; 3. 在编译和构建binary的同时或之后,该机制还可以和其它机制挂钩,如生成文档,给软件打包,做其它测试甚至生产发布,等等; 4. 有网页界面来回报集成测试结果。这结果包括集成测试状态,该集成包括哪些代码变化、bug fixes,新性能等,代码覆盖测试/code coverage报告等等。 一般情况下,如果队伍和产品有一定规模,可以考虑设置专门的build server来完成以上步骤。持续集成测试会给我们带来以下优势: 1. 尽早发现不同队员代码之间的冲突,减少甚至铲除难缠的由于不能尽快整合而对全局有负影响的问题; 2. 促进团队内部沟通; 3. 在紧急情况下,如果需要部署最新软件来解决生产环境中的燃眉之急,你有了可以直接部署的binary。 我个人以为建立持续集成测试机制对一个团队很重要。从我的理解和体会,我觉得以下几点值得注意: 1. 如上文所述,团队用统一的单元测试架构很重要。有了这个架构,工程师要写单元测试; 2. 养成多次从代码库拉下更新自己代码的习惯,每个工作日至少一次。一天可以多次提交代码; 3. 在代码提交之前,完整运行一次所有单元测试,包括组内其他成员的单元测试。测试不通过,不提交自己的代码。更何况,如果你的代码没通过单元测试而被提交,那集成测试机制会发现这个问题并在网页上公布出来,你会觉得很没面子。 好,这次就写到这儿。下次继续,可能会写下接收测试acceptance testing,stress/performan testing之类吧。如上文所述,这里是MariaDB的持续集成测试网站链接(Buildbot);这里是Percona的持续集成测试网站链接(Jenkins)。

  • 关于软件测试:单元测试

    上博我写了测试的重要性。现在我来谈谈软件开发最基本的测试:单元测试,unit testing。 单元测试主要用来检测某class,function,method的正确性。我想绝大多数工程师在编程时都会做各种各样的单元测试。但直到约上世纪末和本世纪初,系统性、自动化的单元测试机制才被真正地建立起来注,见下。说到这里,我们必须提到Kent Beck和Erich Gamma。 Kent Beck在90年代末用Smalltalk编程,在那段时期他写出SUnit,是用Smalltalk写出的给Smalltalk程序做单元测试的架构。在此基础之上,他和Erich Gamma携手创建了JUnit。JUnit是用Java写成的用来做Java单元测试的架构。从JUnit开始,统称为xUnit的测试架构以燎原之势传入到其它语言:Python(unittest),PHP(PHPUnit),NUnit(.Net语言如C#,VB.net)等。 xUnit的架构和基本思路实际上很简单:Arrange-Act-Assert: 1.把输入值和期望值安排好,必要时可以装逼(mock)。mock是当你的单元测试需要大、笨重、或复杂的外部资源支持时(如数据库,其它复杂API等等),你可以用个假模子mock来代替。这一步是Arrange,设定期望值; 2.调动要被测试的function/method/class,得到实际值,这是Act; 3.比较期望值和实际值,报出测试结果,这是Assert. 或许你会说,这有啥大不了的,我编程时所做的随机测试就是这么做的吗。没错,但像xUnit这样的测试机制提供了自动化、可重复性和方便性等特点。 1.自动化 良好的xUnit测试机制有所谓的test harness,即各种脚手架、工具等配套的捆绑机制。在按xUnit规范写出测试案例后,可以很方便地用该捆绑机制轻松调用全部或部分测试案例,不用笨手笨脚地做手动调节; 2.即时性 和上文紧密相关的是xUnit带来的即时性。在写出一个测试案例后,你可以很方便得用copy/paste/adjust来写出更多其它测试案例。因为有自动化机制,运行这些案例会很方便快捷,成功与否,结果立现。这样你就可以在思路、信息还停留在脑海之时,趁热打铁,迅速、有效地解决这个问题。顺便说一句,英语中也有这一俚语:strike while the iron is hot。不知该成语是否是翻译、借用来(中英或英中),我感觉自发生成的可能性大些。 单元测试是你的安全网。随着你单元测试的增多,你的安全网就变得越来越密集,漏网之鱼就会越来越少。测试给你的软件质量提供了足够的保障。 如果说我们对单元测试的重要性和自动化有了共识,我有以下想法和你共勉,让我们一起来学习和提高。弄好测试,如俗谚所说,磨刀不费砍柴工,会大大提高你的功力! 1.搜索出并安装适合你编程语言的xUnit测试框架。比方说你写PHP,那你可以用PHPUnit。如你用Python,如果是2.7以后的话,你可以用标准的unittest模块来做测试:注意要安装nose来做这个测试的harness,来方便地调用你的测试案例。像其它语言,大多数都会有xUnit,搜搜就可以找到; 2.花时间学习如何写单元测试案例和如何有效地调用单元测试。相关的tutorial,how to等应当不少; 3.在做新开发时,要给新function/method/class写单元测试。当有时间或需要修改已存在代码时,如那段代码没单元测试,逐步引进单元测试; 4.单元测试也是代码的一部分,当然要进入代码管理库; 5.用copy和paste,写出各种满足边缘参数、一般参数等各种情况下的测试案例。硬盘便宜,多存几个案例占不了多大空,注意好的文档和命名方式对案例的管理很有帮助; 6.如果在整合测试/integration test或质量检测/quality assurance甚至是生产环境中发现你的function/method/class出现问题时,请首先写出个单元测试案例来捕捉这条漏网之鱼,然后修改代码来让测试通过。这样你的安全网就会被织得更紧一些。 在完成这个修改之后,你要反思一下为什么一开始你没想到要写这个测试?为什么没有想到鱼会有这种形状和技巧来挣脱你已经编织的网?通过这种反思,你会慢慢增加你的编程洞察力、嗅觉、和敏锐。 好,先写到这里。下一篇继续。我可能会写integration testing和continuous integration testing。或者专门写一下单元测试的应用实例如Python。如有问题或评论,欢迎提出,我们一起切磋,共同前进。 注:Perl的TAP(Test Anything Protocol)值得专门提一下。早在1987年,即随Perl第一版发布,就有了自己的单元测试机制。这比SUnit(xUnit之前身)要早10年左右。之后大部分在CPAN上公布的模块都经过了Test::More的符合TAP规格的单元测试。我个人以为这是Perl作为元老级脚本语言,至今仍威风八面、历久弥新的主要原因之一。所以如果你用Perl编程,我强烈建议你掌握Test::More和相关的Test::Harness模块。

  • 关于软件测试:测试的重要性

    题记:去年12月在淘宝和奥莱利公司举办的Velocity会议上,结交了很多好朋友。当时有好多想分享的主意,回来后写了个“开源软件的参与及社区互动的一些体会和建议”系列。之后就酝酿着要写一个测试系列,因为我坚信好的测试是生产高质量软件的必要条件。后来因为有家人从各地来,再加上时间安排不当(主要是懒和自律性差)和其它方面的原因,现在才动手写这个系列。这是开头篇。 通过自己的实战经验和阅读别人经验体会,我感觉我们可以总结出在生产高质量和高可靠的软硬件产品过程中,大都会走如下流程: 尽快制出原型产品(prototype); 尽快把原型产品拿到生产环境中做检测和获得反馈; 尽快把在生产中得到的反馈数据和教训融入到下一步的故障修复和性能提升; 把改进后的产品再次尽快拿到生产环境中做检测和反馈; 循环以上步骤。 在这样的流程里,有以下几个方面特别值得注意: 1. 尽快做出原型产品并拿到实战中(或近可能类似于生产环境中)检验。 和用户互动,了解实战应用场景,检索、阅读、和了解业界同仁的文章和经验积累,搜索、阅读、分析网上网下的关于各种语言、解决方案的文档等都是很重要的过程。但把想法和了解到的信息付之与实践之前,那些理论、分析、和研究到头来只是纸上谈兵。把东西付诸与实践后,你会加深和巩固自己对已有知识的理解,碰到和解决自己和别人没有想象或碰到的问题,把学到的理论和步骤加以调整后运用到自己的环境中去。这是Kent Beck在极限编程/eXtreme Programming/XP中的一大重要、也是在实战中极端有效的一个原则。这一点和陆游在1199年写的《冬夜读书示子聿》里说得是同一个道理: 古人学问无遗力,少壮工夫老始成。 纸上得来终觉浅,绝知此事要躬行。 2. 快速的检测和反馈需要可靠、方便、和尽可能自动化的测试机制。 原型产品出来后肯定会有这样或那样的问题:有的地方需要改进和提高,有的地方需要添加新功能等等。我们在做改进和提高的同时还要做到已有功能不退化(regression bugs)。要能够实现这一目标,唯一有效的办法是建立起有效、系统、和自动化的测试脚手架。有了这种测试机制,并配有有效的源代码管理系统,我们就敢于去做代码改进和重构,就有足够的信心来保证代码的质量和可靠性。 前一段时间读Kent Beck的TDD(Test-Driven Development)书,他举了这样一个例子,我觉得挺贴切的。我们都知道用轱辘打水比从井里直接往上提省力,是打水的有效方法。假设水提到一半后你累啦或有别的情况而hold不住,你的努力就会前功尽弃。但如果你在轱辘上安装个齿轮机制来咬住你的进程而不至于让提上来的绳子后退,那你就会轻松、自信地打很多水。有效、自动化的测试机制就是你用轱辘打水的那个齿轮,它给你信心和回旋余地,让你大胆、放心地去修复、改进、重构、和添加新功能,让你有信心和实效来生产和提高产品,在保留既有功效的前提下扩大战果,打一场干脆利索、无后顾之忧(或担忧最小化)、不拖泥带水的漂亮仗! 在编程中,如果我们把每一个类/class、每一个函数/function都当作一个产品的话,根据上述“尽快做出原型产品并拿到实战中检验”的法则,我们就可以很容易地理解TDD的原理: a.我们对某类或某函数的界面有初步打算,即脑中已经设计出原型; b.在实施该类或函数之前,我们写出一个单元测试案例来在实战中应用该函数/类的原型; c.我们运行该单元测试,那么这第一个测试应当失败; d.好,接下来我们用代码来实施该函数或类的原型,直到该单元测试通过; e.我们接着写更多的测试来强化该函数/类的代码,直至新的单元测试通过; f.循环以上步骤,来搭建其它函数/类。 按照这种方式来写代码,这些单元测试就构建成咬定既有成果的齿轮和脚手架。它们给我们提供质量保证和信心,给整个产品的稳定、可靠、和高质量打下了坚实的基础。 先写到这儿,该系列的下一篇,我写一下单元测试。 后记:这些生产原型产品、实战测试和反馈、之后提高的良性循环经验过程,不仅仅可以应用到软件开发方面,个人以为在硬件、工业制造、能源和环保产品的设计和研发等很多方面也能派上用场。比方说关于节能型汽车的研发、改进和提高,关于高铁、大飞机各部件的研发和应用,关于能源产品如藻类/海藻产生能源和风能、地热能、太阳能方面的可行性研究和应用,关于很多产业向创新、高附加值型转型等等,这些对于中国和很多后发国家都有很现实的指导意义。有的东西你可以在网上、书里、和各种会议上学,有的东西别人会藏着、掖着不想让你学到,但你若不自己去应用和尝试,那永远都不会成为你自己的东西。不要自高自大,也不要妄自菲薄,一步步建立起完善的研发、测试、反馈、和提高机制,有勇气和实际行动去大胆尝试,踏踏实实地走稳每一步,那么最后领先的会是你。

  • 剃头

    头发长了。吃完晚饭,遛完狗,我骑了洋车子(家乡土话。学名自行车)到镇中心的Hair Cuttery连锁店去理发。 常给我理发的来自越南的华裔女士今天不在。我不在乎发型,我的妆,从来都是清汤挂面,素面朝天,所以就告诉工作人员哪个理发师有空都可以。坐在那儿没几分钟,莎伦剃完了一个后,就给我理发。顺便说一句,进商店、到饭店预约等需要挂个名时,我都摇身一变,自称亚历克斯,能省点麻烦。 莎伦来这个店不到一星期,三四十岁的样子。她之前在Hair Cuttery的另一个连锁店。她说那个店里的发型师有矛盾,玩办公室政治,所以选择离开。其实我感觉这个店也不见得就能好到哪里去,我以前就注意到这儿的发型师们在该谁接电话、扫地等方面逗斗心眼儿、说风凉话。但话说回来,这东西和人的脾性有关,希望这地儿能和她的意。 就随便聊聊天,开开玩笑。莎伦住的远一点,买不起车,所以上班都是坐公共汽车,要转好几次。现在好一点,但冷天、雪天就不好受。但车也有车的麻烦,她说一想到上班高峰期那么多的车在路上而自己要和他们抢道开时就觉得公交也很不错。她没自己的房子,住公寓,我说那你考虑就近找个公寓住呀,最好一班汽车直达。她说正考虑,偏西北方的公寓可能便宜些。就聊起了网上找公寓的问题,说起有的Craig’s list上好像有变态在上面活跃,挺逗的。理了个平头后,我让她洗了下。理发和洗头共15块美元,我给了3块小费,总共18。 实际上我以为人进化到现在,毛发应当是下一个被淘汰的部件。这玩意儿没大用,碍事不说,还得花钱伺候它。小时候在季庄农村,都是邻居或遛乡的理发师用推子剃头,俺大也借别人的推子自己给我们剃过。遛乡的和镇上的理发室在剃头的同时也提供刮胡子业务。那时刮胡子就用泡沫,我不知那泡沫从哪里来。一般还有皮带子用来磨刮胡刀。 在厦大上学时,记得隔壁宿舍的林凯哥们激我剃光头,我的要求好像是要他请客买单。那是我的第一次光头。来美国后我好像也剃过一次光头,现在记不太清啦。 对于初到美国的中国人,剃头也可以算是个有趣的话题吧。我那会儿,90年代中后期,不少男留学生买个推子,互相帮助解决理发的难题,不知现在怎样。这里有好几个方面的因素吧。语言方面,一些词儿和描述方式会有困难。经济上,当时一换成人民币就是一大笔钱,能省则省。还有就是文化习俗方面也会有影响吧:剃头是一个肢体的接触,里面蕴含着文化习俗上的潜规则,在一个人生地不熟的环境里,让一个和自己种族、语言、文化、风俗等不同的人来摆弄自己的脑袋,心里稍有犯毛是完全可以理解的。我想国际人士初到中国可能也有这方面的挑战吧。慢慢了解熟悉后,就好了。我记不太清我留学时第一次去美国私人理发店花了多少钱,说了什么话,但尴尬和误解肯定有。后来常去那个店,还从店主也是理发员那儿买了辆自行车。 后来谈恋爱成家后,我曾不止一次要求老婆给我剃头,她绝不答应。瑞典理发比较贵,好几十上百美刀,所以她在瑞典时,都是让她姐姐给她做头发。在美国,她没办法,也得去理发厅。她姐姐几年前来过一次美国,还在这儿给她做头发。我爸第一次来美国时,我哥那儿有理发的家什儿,他又给我们哥俩在美国剃了回头,挺好。我想这对于双方,都会有一种亲近和满足吧。 儿子出生后,我们专门买了套剃头的家什儿,就给他用过一次。现在他是上初中的少年,留起长头发来啦!我现在想让他剪剪,但我说不大管用,得让孩娘来做这方面的工作。

  • 开源软件的参与及社区互动的一些体会和建议:沟通和交流

    开源上的项目有时需要和国外的人员沟通。怎样沟通,怎样建立互信,这是个非常大的题目。我把观察到的和蹦到脑子里的想法写出来。如果读者有问题,可以提出来。 我在美国待了很久了,也到过一些其他国家和地区。依我看,不管白红黄黑棕哪个国家哪个种族的人,不管你是女皇还是屌丝,本质上讲大家都是人,没大差别。大家都有七情六欲,都有那么点小可爱和小肮脏,都要屙屎放屁。和你我一样,女皇伊丽莎白的屁和屎照样臭,当然还不能排除更臭的可能。大家脱了衣服后都是那几样东西,毛或多或少,高矮大小尺寸有点不同,连披金戴银穿着红皮鞋的德裔种族主义者现任教皇也不例外,不管你外表如何的冠冕堂皇。有的还可能像奥巴马总统一样有点口臭,特别是清晨刚睡醒后那段时间(这是根据第一夫人未当选前的表述,后来她不说这个了。期待方舟子科普口臭的原因和防治)。当然这不是教你去不修边幅,形象还是很重要的,因为形象在一定程度上反映一个人有无自尊。每个国家每个地区每个宗教和无宗教的人都有人的闪光和可憎之处,部分因为经济、习惯和教育的原因,大家的表现(不少人喜欢称之为“素质”的那个东西)会有不同,这都没啥。 乱七八糟地说这些,意思就是说国外的人和你我一样,都是人。抱着以人为本的信念来互相尊重和学习,体谅和理解,知道自己的尊严、自信和底线来结交朋友。有了这个出发点和任何人沟通和交流,给你打包票,错不了。 下面来谈谈一些小建议。我以为这些建议,相关部分在本国同事之间的交流上同样管用。当提到国际友人时,我指的是所有国际友人,不管国籍、肤色、宗教信仰、性取向等。不管你是美国白人、黑人、外籍华裔,不管你来自非洲、中东、日韩、南美,一视同仁地以尊重、友好的方式来维护双方的利益。如果你不希望别人以刻板的方式来对待你,那你就不要以刻板的方式来对待别人。己所不欲,勿施于人,你要有这个风范! 1. 目前国际上交流的载体大部分是英文,所以不少人在这方面会有障碍。但不要因为有了这个障碍就不敢交流,不要因为害怕病句、拼写的错误而放弃交流。你当然要努力尽量用正确的词和句法,但如果词和语法不完美和正确但意思到了,那么这个交流就很有意义。这样一来二去,你的外语水平会提高。在本文的最后我有提高英语的小建议。另外,其他参与到开源软件的人可能来自非英语国家,他们的英语不见得比你强到哪里去; 2. 要注意名字的拼写。一般来讲,别人怎样自称,你就要用那种拼写方式,包括字母的大小写。我看到一些从国内来的电邮,其中有的不知何故的改变别人名字的大小写,请不要这样做; 3. 无论是书面还是口头交流,千万不要不懂装懂!如果你没搞明白,如果这个事情不是鸡毛蒜皮之类的小事,特别是牵扯到计划、行动、和时间安排等对他人有直接和间接影响的信息,不要敷衍了事!你没搞明白,你可以说,对不起,你可以换一种方式来解释吗?或者你可以以你的理解方式复述重要的交流信息,以此来确认和验证彼此观点和计划的一致性。千万不要在双方还没真正达成一致的情况下拍胸脯、打包票,结果损人损己; 4. 口语交流上,不要太在乎口音。能表述清楚是第一要务,所以说的时候不要着急。一般来讲说慢些会有利于理解; 5. 哈哈一笑是比较常见的沟通方式,也是化解矛盾、将就着过去的方法。另外,我们中的不少人和国际友人交流的机会不多,有好奇心甚至觉得国际友人的举止比较可爱的情况很正常。再加上语言的不便,这种有点紧张的笑声就更容易听到。但我感觉在大多数情况下,国际友人,特别是不太了解东方文化的,可能会以为这种笑对他们来讲有点奇怪甚至难以理解。这不是说面对面沟通或打电话交流时不能笑,大家都板着脸。重要的是能察言观色,观看肢体语言和表情,这方面我感觉东西方的差别不大,并根据这些观察来调整和理清模糊的观点。有些东西,一次解释不清不要紧,以后时机成熟时再提也不迟; 6. 对外交流增多,有很多人来中国,我们要逐渐适应、学习、尊重、和欣赏他们所带来的多样性和多元化。举个小例子,面对面交流时,我们尊重别人的饮食习惯,有人吃素,有人不习惯吃整的带刺儿的鱼等等。尊重别人的时间和空间,有计划并及时沟通; 7. 既然我们都是人,那么国际人士和国内同胞一样,也不乏混蛋、瘪三、种族主义者、圣人蛋、猥琐的小人混蛋之流。再加上事情的偶然性、沟通障碍、不合宜的时机等,有的项目即使我们做得很好,也可能因为各种各样的因素,我们的patch,feature set等不被接纳。在这种情况下,在合作的努力没有结果后,我们可以发布自己的分支和大家共享和进步。 拉拉杂杂,就先写这儿吧。另外,最近在微博上总结了些学英语的小建议,也在这儿先放着吧,如下。 不论哪个语言,想把东西表达清楚和准确,都要认真努力花时间下功夫,母语也是如此,何况外文。多读多写,慢慢积累。读的话,读好的原版的关于自己本身就感兴趣的主题的作品,这样读时就不会觉得枯燥,读得下去的同时可以提高词汇量,学到好的句法和表达方式。举个例子,如你喜欢伍迪艾伦的电影或乔治卡林的单口相声,就可以先在亚马逊上找关于他们的书,要读者评论口碑高的那些,然后弄来读。注意到的新词和好的表达方式,要试着用。个人体会,一些新的词和句法,如果能在合适的场合自己用过一次,就算掌握了大半。多用几次,就是自己的啦。 一开始读外文书时可以囫囵吞枣,但有的词老出现老不懂就要用字典啦。要有好的英汉字典。个人以为如果到了可以用纯英文字典来学新词并且到完全可以理解的地步,那英文水平就很不错啦。 我认为过了六级英语的同学没必要通过读报纸和杂志英语新闻来提高,因那都是肤浅空泛的八股句式,搞得人很浮躁和浮漂,蜻蜓点水一样,内功提不上去,个别的长的深度报导除外。我不是开玩笑,我觉得读《洋葱》(The Onion)学英语要比读NYT,The Wall Street Journal,Time Magazine,Newsweek等更有效和有趣。National Geographic还行,但质量也在下滑。最好是读书,安静一下,每周找个时间,沉下心来,给自己放个假,读本好书,陶冶性情,平稳而满足。在《洋葱》那里你可以逐渐理解部分美式的幽默和讽刺!祝学得愉快!