一个偶然的机会,调试一段多年前的程序,那段程序有一套自动化的测试,但是经过多人易手,变化已经比较大了,测试已经无法通过,那么我的切入点就放在了这些测试里面.
这是一段带界面操作的程序,目标是测试一个矢量图形控件,这个例子里我关心的大致功能接口如下:
1, PlaceTestingSystem(...)
放置一个图形节点
2,PeripheralSystemNode PlacePeripheralSystem(...)
放置一个图形节点
3,ChannelNode PlaceChannel(...)
放置一个火柴棍
4, ProtocolLink PlaceProtocolLink(...)
放置一根连线
这根连线可以附加一些信息,在双击连线时可以激发下面的事件
通过事件,可以获取到附加的信息
测试的名称[TestMethod()]public void EditProtocol_Test(),这个测试所表示的不变式为: 输入:双击连线 预期:激发ProtocolEdit事件
OK,先看一段测试代码
var f = new System.Windows.Forms.Form(); DesignControl target = new DesignControl(); var sysNode = target.PlacePeripheralSystem(...); target.PlaceTestingSystem(..); var ch = target.PlaceChannel(..); target.PlaceProtocolLink(..);
当我运行到这段测试的时候,发现"空引用的错误"
private PointF FindEdgePoint(...) { ...... TestingSystemNode node = addFlow1.Items[0] as TestingSystemNode; var rect_d = node.Rect; ==>node 是一个null ...... }
原来是后期的维护者加入了这么一个假设:矢量图里的第一个节点是TestingSystemNode类型的节点,但是从测试用例来看
var sysNode = target.PlacePeripheralSystem(...);
target.PlaceTestingSystem(..);
明显第一个节点不是,这时候我可以推断:这名维护者在修改完代码以后根本没有运行测试,而只是在其他环境里进行了测试,偶然正确,就完事大吉了.我没有批评这位作者的意向,但是从中告诉作者一个简单的关于测试的道理:
从这个例子可以很明显地学习到测试的一个用途:保证开发完成后的修改不会破坏以前的逻辑,如果破坏了,则马上就要知道,
如果没有这些测试,或者不经常运行这些测试,就会导致偏差越来越大,最后无法维护
尽管涉及到界面的测试,不是那么稳定,我也觉得在集成服务里每次嵌入都运行一遍不现实,但是我认为每1天或者2天手工运行一遍还是必须的,你运行的间隔周期越短,就越有信心,反之就会慢慢失去信心,这也是持续集成的优势