zoukankan      html  css  js  c++  java
  • 打造第二代测试框架TestDriven 2.0(三)—— 测试还是调试?玩玩BreakPoint!

    ------------------ 

    前言 Preface

    ------------------ 

    本文是第二代测试框架系列文章,同时也是软件工程革命三部曲中的技术文献。

    本文展示了Visual Studio中独特的断点调试技术,是目前尚未有人尝试过的断点方式,而且也是您google也找不到的技术。

     

    ------------------ 

    测试还是调试?

    ------------------ 

    测试驱动TDD的提出,有其理论的优势,也有明显的不足,本人的理解是:当我们对项目有六成以上的把握,采用测试先行可以节省代码开发量,否则绝对不建议测试先行(测试先行 不等于 单元测试 等等)。

    原因也很简单,如果我们对未来估计不足,不仅系统代码变化很大,而且测试代码变化也很大,盲目采用了测试先行导致增加了工作量。

    如果上面的论点是正确的,那么我可以获得下面的论点:项目开发中,测试先行以外,必然存在了测试后行,或者我们非常熟悉的名词——调试。我不知道为啥测试和调试有必要分开,这个就是玩文字游戏,硬把相同的事情用不同的LABEL区分。

    那么既然测试后行就是调试,我就应该把调试技术纳入测试框架,于是引入了Breakpoint技术。

     

    ------------------ 

    Breakpoint

    ------------------ 

    传统的调试技术,无非就是在Visual studio里面设几个断点,然后运行中查看。

    这让我想起我初中的时候,用qbasic写的人生第一个游戏:Dream of Navigation(当时玩大航海时代玩疯了,于是自己写了一个)。扯远了,提这个只是想说,那时已经有了break point技术了。所以,几乎写程序的人就知道breakpoint。

    今天,老弟我就令走不寻常路,介绍一个新的断点技术。

    首先看看在c#里面如何使用代码设置断点:

    System.Diagnostics.Debugger.Break();

    恩,就这么简单!当代码出现了这句话后,在debugger模式下,IDE会自动停在这里了。如果问原因,就是在IL里面插入了一个断点。换句话说,我可以用纯IL的方法实现这个技术,不过既然微软封装了,我就省了。

    不知道大伙会不会立刻打开VS,然后写一段测试一下? 有了这个技术,就可以实现VS的任何断点技术,包括:断点条件、断点命中次数、甚至断点宏等。如果不知道这些功能,可以打开IDE,设一个断点,然后鼠标右键点击一下,得到:

     

    平时,我几乎很少用上面的功能,因为实在太麻烦也不直观。如果这些设置能在代码里面完成,调试结束后删除调试代码,那么就更加实用了。于是我就扩展了断点技术。 

    当然,遇到比较大的问题就是断点位置问题,比如计算命中次数,不同地方的断点对命中次数计算是不一样的,不过有了之前的经验,解决这个问题就很简单了,我只要获得当前断点代码在总代码中的偏移量,就可以获得唯一的位置标识符,然后隔离不同的算法。例如一下就是断点技术中另外一个核心算法:

    代码
            public string GetBreakingLocation()
            {
                StackTrace stack 
    = new StackTrace();

                StackFrame testcaseframe 
    = stack.GetFrame(default_stack_index);

                System.Reflection.MethodBase method 
    = testcaseframe.GetMethod();

                StringBuilder builder 
    = new StringBuilder();
                builder.Append(method.DeclaringType.FullName);
                builder.Append(method.Name);
                builder.Append(method.IsGenericMethod);
                
    if (method.IsGenericMethod)
                    builder.Append(method.GetGenericArguments().Length);
                
    foreach (System.Reflection.ParameterInfo parameter in method.GetParameters())
                {
                    builder.Append(parameter.ParameterType.FullName);
                    builder.Append(parameter.Name);
                }
                builder.Append(method.ReflectedType.FullName);
                builder.Append(testcaseframe.GetILOffset());

                
    return Pixysoft.Security.MD5.GetMD5(builder.ToString());
            }

    我使用 StackTrace 技术,获取了断点代码的偏移量(GetILOffset()),然后再MD5一下,就得到了当前断点的唯一标识符。

    最后,展示一下断点技术的实际应用:

     代码


            
    public void test012()
            {
                
    string name = "hello";

                
    //设置 立刻中断

                BreakPoint.BreakAtOnce 
    = true;

                
    // 当 name = "hello" 的时候,中断

                BreakPoint.BreakAt(name 
    == "hello");


                
    for (int i = 0; i < 100; i++)
                {
                    
    //当循环到98次开始 中断

                    BreakPoint.BreakAt(
    98);

                    
    if (BreakPoint.True)
                    {
                        Console.WriteLine(i);
                    }
                }


                
    int value = 1;

                
    for (int i = 0; i < 3; i++)
                {
                    value 
    = i % 2;

                    
    //当 value 值变化后中断

                    BreakPoint.BreakWhen(value);

                    
    if (BreakPoint.True)
                    {
                        Console.WriteLine(value);
                    }
                }
            }

    源代码下载:

    http://www.boxcn.net/shared/8vpet6yf0d

    ------------------ 

    后记 Conclusion

    ------------------ 

     本文和”框架“ 两字相比,简直是雕虫小技,不过Big Game在后头。各位别急着copy paste,也别急着让我出个完美版的XXX,这都仅仅是冰山一角。

    希望各位能够继续关注我的TestDriven 2.0 框架,也请继续关注软件工程革命三部曲。我会好好玩一场游戏。

    同时,我也希望各位ITer们(当然更多的是IT精英们),在忙着学hibernate / spring、找.net 十大工具、研究一大堆scrum之类名词等时候,试试在人挤人人推人的人流中,停下脚步,回头看看,当别人往左转的时候,试试往右转,之后就会发现原来你能做的比他们更好。期待各位的留言和想法。

    鞠躬敬礼! 

  • 相关阅读:
    Python学习笔记-常用内置函数
    Python练习-高阶函数-2018.12.03
    Python练习-生成器、迭代器-2018.12.01
    Python练习-列表生成式-2018.11.30
    Python练习-迭代-2018.11.28
    Python练习-循环及切片-2018.11.27
    FortiGate端口聚合配置
    FortiGate路由模式--静态地址线路上网配置
    方位电话批量配置教程
    Python学习笔记(七)
  • 原文地址:https://www.cnblogs.com/zc22/p/1676139.html
Copyright © 2011-2022 走看看