谈分布式网络程序设计3——调试?测试?
什么叫调试,是个程序员都知道,不知道的可以去撞墙了!本骗取点击率的帖子其实想讲的是测试,测试做的好,完善,调试就可以省很多很多很多...(n个很多)心了。道理大家都懂,关键在于怎么执行了,执行的程度如何。因为有的具体问题,软件工程书上的那些泛泛大论是很难解决的。再说测试之前,应该要说说设计,好的设计会使得测试工作很容易。若设计做的像一砣便便那样,那测试就很痛苦了,而且测试代码的结果也很有可能看起来也像一砣便便。所以强烈推荐基于测试的驱动开发。还有一个技巧,我们设计的时候其实可以参考STL,或C标准库的接口设计技巧,既然这些都是标准了,它的设计应该是很值得模仿的。若接口设计的像STL那样,测试其实很容易的。
1。单元测试。这个是测试的第一步,这个太重要了,除了娶老婆生孩子之外,就是这个最重要了。虽然我们做不到测试case在code之前写,但是编写一段code,再编写这段code的unittest还是可以做到的,这个应该是开发者的任务。单元测试能够发现**%(**是个很大的2位数,具体的我忘了)的bug,每完成一部分代码,接着马上写它的unittest,这时的unittest主要包括failtest, function test,thread-safe的代码还需要multithread的test。最好是每写一个类,就完成对这个类的的test。但是时事难料啊,说是这么说,哪有这么简单啊。要是这个类涉及网络通信之类的,你就麻烦了,单元测试很难很难写了,所以这部分代码的单元测试没有了,只能等到集成测试了(测试高手可以教俺们几招有没有更高深的办法)。还有其他的一些情况会导致单元测试很难写,这就需要设计的时候好好考虑。因为单元测试是测试的第一阶段,在这个阶段调bug最快。若bug等到集成测试调试,尤其是分布式的网络程序,那你就慢慢哭吧(男人哭吧不是罪,女人么就更不是了)。
2。集成测试:跟单元测试差不多,failtest,function test, concurrent test等等。俺们现在一般做法,先做功能验证测试(包括fail test),然后做稳定性测试。因为分布式系统是几个服务器程序的混合体,那就混合起来跑它个三天三夜,看它死不死(千万不要死阿,死了俺们就惨了)。当然这需要一些跟需求相似的模拟程序的帮助。俺们的压力测试是在稳定测试的基础上,增加单位时间的请求产生速度(单位时间内产生的请求数大于系统能处理的峰值),看看系统的行为怎样。常理来说,系统地正常行为应该是响应变慢,且有些请求应该要返回不能处理的异常。此外,高并发的压力测试也能发现一些bug,比如:上次提过的不同策略的锁的问题;还有一个没提过,就是,Log4j这个鸟东西,在多线程高并发下有时候会死锁(bug),兄弟们千万要小心啊,这两个问题俺们是调了好久好久才发现的。还有,以后高压力测试还是不要常做,俺们搞死了2块SCSI的硬盘,这些机子还是刚买的呢。
3。内存测试:C/C++的程序最怕的是内存泄露,这个东西就像噩梦一样让你饭吃不好,觉睡不好,没办法,命苦,埃!!!所以俺们组就整合了一个测试内存泄露的lib。但是也有一些限制,不能检测它所调用的库的内存问题,但是它确保了俺们自己的代码肯定没有内存泄露。对于俺们项目现在使用的某个*库,还好,它有自己的内存测试库,虽然这玩意儿在linux下不能用(可能是俺们对那个automake之类的不熟悉),但是windows下可以。既然windows可以,那就更轻松了,俺以前可是ms的崇拜者,呵呵。还有,补充一点,一般的内存泄露测试都是等程序跑完了,报结果的。但是服务器程序比李铁兄还跑不死,咋办?那就在线打印贝,等到系统的逻辑都跑过的时候,停止产生请求,然后触发事件,在线打印内存泄露报告。这样就好办了。
未完,待续...