HTML5技术

使用测试用例来约束自己的代码 - 陈宏鸿

字号+ 作者:H5之家 来源:H5之家 2017-05-09 14:00 我要评论( )

写测试代码这种事情 ,以前只在网上和书上看到过, 自己从来没有写过。 每当看到那些世界顶级程序员编写的技术书籍中出现测试用例测试代码的字样或者一些行业的鼎鼎大名的技术大牛们提及写测试的重要性的时候,我的心里就会产生一种自己编的一定是假程的错觉

写测试代码这种事情 ,以前只在网上和书上看到过, 自己从来没有写过。 每当看到那些世界顶级程序员编写的技术书籍中出现“测试用例”“测试代码”的字样或者一些行业的鼎鼎大名的技术大牛们提及写测试的重要性的时候,我的心里就会产生一种自己编的一定是假程的错觉, 为什么我写代码就从来不用那玩意?

 

就拿开发一个MVC框架的Web应用程序设来说, 通常的做法就是新建一个控制器和一个模型, 把代码要实现功能的业务逻辑写在模型里面,控制器调用模型, 假如有外部参数则接收参数传递给模型, 假如业务逻辑过于复杂导致模型过于臃肿或逻辑不顺畅, 则再进行梳理或提取,构建成一个新类,再由模型进行调用。 这一过程反复循环迭代, 直到功能开发完毕。 调试或者测试写的代码是否能得出想要的结果, 自然也是使用最简单粗暴的方法, 在浏览器中运行程序, 定位到控制器, 控制器调用模型, 模型再调用其它所涉及到的类,拿到结果后再一步步返回, 浏览器是否显示预期结果就意味着我们写的程序是否正确。不管是我们要测试的功能模块离控制器只有一个调用还是有十个调用,都遵循着这样一个步骤, 因为这是最符合我们直觉和习惯的方式。 我也一直以这种方式在开发程序。

 

原本这也没有什么问题,我们所写的代码逻辑是通过我们的大脑深思熟虑组织后产生的,通常情况下我们有这个把握可以确定代码逻辑运行的正确性,就算出现意料之外的情况, 多点几下浏览器的刷新按扭也能把问题找出来解决,因为我们对代码的运行逻辑了然于胸,自信不会出什么叉子,一旦出现了叉子那就产生了所谓的程序BUG。

 

然而, 万事总有例外, 导致我们以往的经验失效。 就拿我最近碰到的一件事情来说,公司有一个项目因性能优化需要,对部分功能进行技术方案调整, 重写了代码。代码量不大, 功能本身的代码和其依赖的通用函数代码加起来一共也就二三百行,但是隐含在背后的逻辑却异常复杂,涉及到的数据表也有五张。我将这部分需要重写的代码重头至尾仔仔细细读了一遍, 勉强能理解每一个语句块都干了些什么。 可能是我逻辑思维能力不过关, 也有可能是代码太过于复杂 , 我没有办法将所有这些代码的来龙去脉全盘了然于胸,也就没有办法从全局的角度去梳理代码逻辑确定优化方案,我只能从局部的角度出发, 依样画葫芦的按照旧方案重新实现一遍代码的逻辑, 在实现的过程中如发现有优化的余地则进行局部优化,等到足够熟悉全局逻辑后,再从宏观的角度对代码结构进行调整优化,这么做效率是低了点,却是最保险的做法。

 

我照着旧代码写出一个个一模一样的函数,却没有办法确定这些函数的运行结果是否能得出预期的结果,鬼知道换一种语言实现以后, 函数吐出来的结果还是不是和之前的一样,我可没有jeff dean那样牛逼,预判代码的结果比编译器还精准。本来这也不是什么大问题,把代码跑一遍,当执行到这些函数的调用时自然就知道结果了。问题出在这之中某些函数和代码的入口隔着七八个调用,而且其中某些调用因为依赖于某些if条件判断结果而不是必然被调用到的,要构造出能使这些函数被调用到的if条件判断分支走向的参数环境是一件异常繁琐的事情,光想想就让人觉得烦躁和气馁。另一种方法就是把函数的调用代码复制一份放到执行入口的开始位置,这样代码一运行就直接能调用的到了。 然而, 这种方法也会带来问题,如

 

函数处于不同的类和包内,调用函数需要导入包和实例化类,而做这些事情对项目的本身没有实际的意义

 

某几个函数只在所在的类内被调用, 访问修饰是private, 通过这种方法测试它的准确性还需要放开权限把访问修饰声明为public, 调试完毕后还得改回去, 操蛋

 

有多个分布在不同类之中的不同函数需要以类似的方式测试, 反复进行这些无意义且繁琐的操作, 极度浪费时间,影响心情

 

代码的执行入口总放着那么一坨被注释掉的代码,想拿掉又怕拿掉以后下次还要用, 内心挣扎的难受

 

因此, 想要解决这个问题, 上面的两种方案都不可取, 柔肠百转也想不出像样的解决方案。 长辈们都说编程都是脑力劳力, 我之前不以为然, 但当碰到这些想破脑袋也找不到办法的问题时就不得不承认, 编程的确是脑力劳力。我才20岁,外表却有30岁可以看,我想也跟长期被这些问题困扰有一定的关系(我说的是10年前的自己)

 

我思前想后,检索所有脑子中关于程序设计的资源, 才找出一个之前从来没有尝试过的方案, 引入单元测试。我这个人有一个优点, 在工作上碰到陌生的东西从来不会望而却步,只要有用处, 都会去积极尝试。对于单元测试,我虽然没有掌握使用的方法, 但是网上查查资料, 看看教程, 我相信花不了多少功夫就能搞出来。 事实也的确如此, 只看了一篇资料,照着教程的步骤操作就把测试程序跑起来了。 我使用的是go语言, 按照go test的规则 ,被测试的代码所在的文件名加上test后缀即可作为测试代码所在的文件的命名,如下图

测试函数的命名方式必须要以Test作为前缀, 如下图

测试代码编写完成后, 在代码所在的文件目录下使用cmd运行go test命令,测试代码就可被运行了

需要测试的函数在测试代码中被直接调用, 省去了跟踪庞杂代码执行走向的麻烦,从复杂的业务逻辑中解放出来, 非常的清晰方便。

 

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • 【Vue 入门】使用 Vue2 开发一个展示项目列表的应用 - zhangjk

    【Vue 入门】使用 Vue2 开发一个展示项目列表的应用 - zhangjk

    2017-04-30 16:00

  • 对于Bootstrap的介绍以及如何使用 - novai-L

    对于Bootstrap的介绍以及如何使用 - novai-L

    2017-04-29 09:00

  • 在Delphi下使用迅雷APlayer组件进行免注册开发 - Delphi力量

    在Delphi下使用迅雷APlayer组件进行免注册开发 - Delphi力量

    2017-04-28 15:00

  • 探索 vuex 2.0 以及使用 vuejs 2.0 + vuex 2.0 构建记事本应用 - nzbin

    探索 vuex 2.0 以及使用 vuejs 2.0 + vuex 2.0 构建记事本应用 - nzb

    2017-04-25 09:02

网友点评
!