分享

随想录(做自己代码的测试工程师)

 心不留意外尘 2016-04-15

from http://blog.csdn.net/feixiaoxing/article/details/40480189

  联系信箱:feixiaoxing @163.com 


    很多工程师都有一个不好的习惯,因为大多数it工程师都喜欢写代码,但是不喜欢测试代码。在他们眼里,把功能做出来是一件很牛逼的事情,而软件测试则是一件低级、价值量不高的事情。事实上是否真的如此呢,恐怕未必。姑且不谈你写的这份代码是否真的会给用户或者消费者带来价值,但是一份极其不稳定甚至时常崩溃的软件,肯定不会带来什么好感,这也就意味着公司投资你作了这个劳动很可能是个无用功。这个问题其实不光小公司有,大公司也是如此。


(1)很多朋友没有代码质量意识。一份软件的价值,一方面体现在是否可以满足客户的需求,另一方面也体现在它是否可以稳定长久地运行。代码运行的时间越长、越稳定和健壮,这样才能最大程度保留代码的价值。


(2)测试工程师远没有开发工程师了解代码的健康程度。很多公司的测试工程师只是按照黑盒的方法对软件进行测试,这些测试的内容包括了功能、易用性、边界测试、兼容性、性能等等,但是这些测试都没有开发者自己写的单元测试重要。大多数单元测试可以在第一时间发现问题、解决问题,而不是等到测试的时候来进行解决。如果开发者觉得代码哪写的好像有问题,那么十有八九有问题。只是个时间问题而已。


(3)好代码是不停修改和重构得来的。之前看了很多的代码,这包括vxworks、gcc、linux、mysql等等,它们中的很多代码从上个世纪八九十年代就已经存在了,到今天还在修改。有的是重新调整流程,有的是为了适配新的cpu,还有的是为了兼容新的设备特性。所以说,一份健康的代码需要反复的测试、反复的重构、反复的运行,没有什么是一层不变的。在服务器上运行的很多系统代码,不知道经过了多少次推倒重来的修改,经过了多少次作者的代码检查,估计只有真正经历的人才知道。


(4)现有的工具可以极大地帮助我们进行代码的各种测试,我有一篇文章谈到了这些工具。比如说,CUnit可以帮助我们进行单元测试;splint可以进行代码的静态检查;valgrind可以进行代码的泄漏测试;gcov可以进行覆盖率的测试;gprof可以进行代码性能的统计测试;gdb的watch功能可以直接帮助我们检查数据是否越界;core dump可以帮助我们保存程序的相关内存信息,为我们逆向调试提供了方便。当然,上面说的都是linux上面的工具,大家可以根据自己的环境,看看有没有什么合适的工具帮到自己提高一下代码的质量。


(5)有些错误是随机的,但是有一定的概率性。这就要求我们对相关数据的输入、输出进行记录和处理。实现这个功能不难,用fprintf和fscanf就可以做到,下面是我自己写的一份简单代码,算是抛砖引玉之用,

  1. #include <stdio.h>  
  2.   
  3. #define NAME "log.txt"  
  4.   
  5. int main(int argc, char* argv[]) {  
  6.   
  7.     FILE* file;  
  8.     char buf[32];  
  9.     int data;  
  10.     unsigned int udata;  
  11.     char str;  
  12.     unsigned int hex;  
  13.   
  14.     // generate log txt file  
  15.   
  16.     file = fopen(NAME, "rt");   
  17.     if(NULL == file){  
  18.   
  19.         file = fopen(NAME, "w");  
  20.         fprintf(file, "%d\n", 10);  
  21.         fprintf(file, "%u\n", -1);  
  22.         fprintf(file, "%s %c 0x%x\n", "china", 'c', 0x12345678);  
  23.         fclose(file);  
  24.   
  25.         return 1;  
  26.     }  
  27.   
  28.     // read file   
  29.   
  30.     fseek(file, 0, SEEK_SET);  
  31.     fscanf(file, "%d\n", &data);  
  32.     fscanf(file, "%u\n", &udata);  
  33.     fscanf(file, "%s %c 0x%x\n", buf, &str, &hex);  
  34.     fclose(file);  
  35.   
  36.     // output content to the screen  
  37.   
  38.     printf("%d\n", data);  
  39.     printf("%u\n", udata);  
  40.     printf("%s %c 0x%x\n", buf, str, hex);  
  41.   
  42.     return 1;  
  43. }  

(6)对于代码中的日志、打印、告警要进行分开处理。有的时候,代码运行很长时间才会发生错误,那么除了core dump和代码入库记录之外,你能看的就是打印日志了,所以写一份自己的print函数也是很有必要的。因为换成自己的print函数后,这些log你可以显示出来,也可以保存到文件里面,同时也可以是一个空函数,真是太方便了。

  1. #include <stdarg.h>  
  2.   
  3. void printk(char* fmt)  
  4. {  
  5.     va_list args;  
  6.     char buffer[256];  
  7.   
  8.     va_start(args, fmt);  
  9.     vsnprintf(buffer, 256, fmt, args);  
  10.     va_end(args);  
  11.   
  12.     printf("%s", buffer);  
  13. }  

    上面的观点是我最近一段时间的感受,欢迎大家来交流。



    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多