overlay了

都是程序,程序,程序。

好长,不知道你有没有耐心看完

既然要走了,就免不了要回顾一下在这里6年所作的一切。

其实真的回顾一下,真正觉得有意义的事情不是很多。但是其中有一件事是我一定要说的,甚至是我觉得在这里工作6年最有意义的事情,也是能够对后来人有帮助的事情。

其实这个事情就是我写了一个测试工具和框架,来帮助我以及其他人快速的验证设计。

一 缘起

我每天的工作就是实现客户希望卡片能具有的功能,这么干了两三年之后我就觉得没啥意思了。 本身需求变化很小,只不过是从一个便宜的芯片换到另一个更便宜的芯片。既然开发没啥意思,我琢磨了一下测试有啥可做的。当时可用的测试工具五花八门,但是基本上只有两个类型。一类是依靠visual basic的可编程的测试工具,基本上就是写vb脚本,另一类是各种个样,用于不同目的的静态数据发送和接受比较工具。这两类当然是可编程的高级一些,有些测试需求必然只能用vb来实现。但是当时vb那套工具是核心研发部分设计用来测试核心系统的,不是专门设计用来测试业务逻辑的,他们的测试思路是检查产品发出的数据的每一个字节,这必然导致测试的工作量是很大的,但是我所在的业务部门绝大多数项目的周期在1个星期内,不可能在测试上花费太多时间。 所以常规项目不可能用这个工具。只有当修改到核心业务代码的时候才会运行一下这个东西。

静态测试工具这一类的起源就不清楚了,给我的感觉是最初只是用来测试简单业务逻辑,所以他们用excel里面的vba来生成测试数据,然后用另一个工具来读取测试数据,然后转换成直接给产品的底层数据。 其实这里暗藏一个问题,测试脚本本身也是程序,也需要调试,但是从源代码,到最终测试数据竟然需要两次转换,那么调试测试程序就变的很麻烦。举个例子,运行测试数据的时候,如果发现错误,虽然知道期望什么,得到什么,但是并不立刻知道那一行测试脚本源代码遇到问题,需要追本溯源才能找到什么。而且是在两个工具之间,两个专有术语之间追本溯源。这个东西让所有的人都觉得不是很方便,但是大家又懒得去弄一个新的,慢慢的也就习惯了,这种习惯的力量导致后来任何一种新测试工具在推广的时候都遇到了强大的阻力,即使新工具又很多优点,只要新工具和老工具不一样,就会被已经熟悉老工具的人拒绝。 我认真的考察过这个工具,发现他最擅长的东西就是静态数据和静态业务逻辑的测试,这恰恰是他最初被发明出来的直接动力。但是随着对于测试的各种需求的出现,不断的给这个工具添加了很多功能来试图满足那些需求,结果是需求都满足了,但是这个工具本身变的几乎无法维护,越来越多的bad smile代码,而且由于采用了excel vba 这种无法用scm工具管理的东西,导致后期想做一些共用的库也没有任何意义,因为所有原本可以自动化完成的库升级也要依靠手工完成。 对于像我这样的懒蛋程序员来说还不如就先把测试搞过了再说,升级?不管他。

我如此的讨厌现有的东西,所以我想自己搞一套。既然是自己搞一套,就首先满足我的几个需求。

首先是要可编程,其次是智能化,可以忽略部分测试数据,只关心部分数据,最后是使用简单,容易修改。

这几个需求很简单,也直接将技术思路固定了。

可编程,意味着最好直接使用编程语言,而不是自己发明一套术语,然后再发明一套术语解释器。同时也意味着当测试逻辑发现错误的时候,异常信息就给出了哪里出错。

智能化,意味着当从产品获取数据时,不是全盘比较,而是摘取自己感兴趣的数据来比较,

简单,意味着给测试人员提供的接口要能直接反映测试逻辑,尽量避免在测试代码里面出现0x3031323334,这是1234的意思。

这几个需求看似简单,现有的工具都做不到。

二 玩具时代

非常巧合的是正好我们公司的老外写了一个python底层库,可以用来在windows上用python语言发送数据。我基于这个东西写了一些简单的功能,开始了玩具时代的探索。这期间主要是尝试看看这个东西能做什么,顺便照着规范实现了一些低级别业务层的测试业务功能。在不断的添加功能的时候,我不断的发现重复的代码会不断的被写出来,好在我是利用工作的空余时间给我自己写这个东西,所以我一看到重复的代码就会尝试重构一下,然后继续添加功能。因此经常出现写了一坨代码,重构一下变的短了很多。这种反复重构的行为最初只是发自内心的认为多余的代码就要删除,过了一段时间我就发现重构的意义不仅仅是多余的代码应该被删除,更多的好处在于后来添加更多功能的时候,或者修改某个底层的细节的时候,往往仅仅修改一个地方就可以了,不会影响其他模块,这种令人愉悦的结果让我始终坚持重构,即使没有什么新的功能可以添加,我也会随便的浏览一些代码,看看有没有可以重构的地方。

三 初露锋芒

尽管这个东西能做一些事情了,但是距离能给大家用还有很长的距离,毕竟基于python,毕竟别人都很懒。不过大概是应了机会是给有准备的人这句话,非常巧合的在我负责管理的一个项目上出现了一个需求,产品发出的数据是随机的,这使得现有的测试工具无法应对,虽然开发人员通过手动测试可以验证,不过如果有人要重用代码的话就很麻烦了,所以我在这个项目完成之后就写了一个测试脚本,等着以后的产品。果然,后续的类似的项目多了起来,我的脚本开始发挥作用,这是第一次发挥作用。我非常受鼓舞,所以继续的写啊写啊。慢慢的,随着通用模块的逐渐丰富,已经可以实现一些以前很难实现的自动测试了。这期间我也听到了大家对于缺少用户手册的抱怨,所以我抽时间写了一个。 后来有个很出色的小伙子,宋,他给这个工具添加了一个很重要的模块,他还大大称赞了我写的用户手册。 这个小伙子现在去做通用数据库了,打算今年读完mysql的代码。

四 大展身手

随着我添加了越来越多的模块,这个工具已经基本上可以做所有现在项目需要的自动测试了,但是,仍然没有太多的人主动用他,大家还是依赖于旧的东西。 不过很快的,一个由我们开发的产品项目需要一个完整自动测试,而且这次没有核心部门的帮助,pm在征求了多个人的意见之后,放弃了使用核心部门发明的测试工具,决定启用我发明的这个东西。 好在这个东西用python,好在我之前的工作做的多,所以别人用于熟悉环境的时间很短,很快的就可以开始写测试代码了。他们不仅仅是很快能写出来能用的测试代码,甚至写出了很多变态的测试代码,各种循环,总之以前旧工具无法实现的各种想法现在都轻易实现。这个项目启动于一年多以前,最近这个产品换了硬件,由核心部门重新实现了一遍,那么重新跑一遍测试脚本会有什么问题么?不知道。最终结果是,重写了初始化的部分,其他修改的非常非常少,从git log可以看出来这种效果。这套测试脚本可以非常好的完成测试。至少从这个结果看来,我最初对这个产品的需求的定义是正确的,甚至可以认为是高瞻远瞩。

五 脱胎换骨

尽管很成功,但是这套东西其实依然是一个工具箱一样的东西,需要什么功能,就拿什么工具。一个功能对应一个函数,使用者依然要看使用手册,依然要学习。所以爱使用的人依然不多。后来我在偶然的机会用核心部门的工具写了几个测试逻辑,发现微软的ide真是强大,只要知道一个东西,然后点一下就知道能做什么了。我开始想是不是可以把这个东西实现在我的这套东西里面。不过这需要面向对象的知识了,而我作为一个顽固不化的c语言程序员,在学习c++的时候感到异常的困难,从此开始远离面向对象。好在2011年看了一本书,《松本行弘的程序世界》,这位大哥在这本书里面讲了很多面向对象的来源和用途,让我有恍然大悟的感觉。 读了这本书之后,我开始了尝试,首先用微软的工具尝试了一段时间, 因为微软的工具自动提示方面很强大。 在这段尝试期间,我反复写了很多抽象方案,在和同事讨论了很长时间之后,并且自己也用了一段时间之后,我最终才把业务逻辑中应该有的几个关键概念搞定了,更明白的说法,就是测试人员在按下点之前要敲的那个单词搞定了。再次感谢我之前的不间断的重构,我添加这样一个新的概念到现有东西里面不会对任何已有的测试代码发生影响,而且甚至允许新旧两种风格同时存在。业务逻辑的关键概念搞定之后,剩下就是按步就班的把点之后该出现的那些函数慢慢实现了。

这个东西的效果怎么样呢?我自己很高兴,因为我也不用记住实现那些功能要用什么函数了,点一下eclipse就做了剩下的事情。 别人对此的感受不一样,因为他们不想用eclipse,虽然没了自动提示功能,可是他们依然很喜欢这个新的东西,因为新的东西更简单,更容易理解。寻找某个函数只需要去所在的类就行了。


六 结语

我自己的经验值在做这个项目期间增长了很多。从一开始的用c语言编程思路来写python代码,到后来可以用面向对象。从一开始给自己用,到后来给别人用。


最后

未来可能2年的时间都会专注在cocoa objective c上,如果有机会会尝试ruby rails lisp

评论