您的位置:首页 > 其它

打造第二代测试框架TestDriven 2.0(三)—— 测试还是调试?玩玩BreakPoint!

2010-03-02 03:36 375 查看
------------------

前言 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之类名词等时候,试试在人挤人人推人的人流中,停下脚步,回头看看,当别人往左转的时候,试试往右转,之后就会发现原来你能做的比他们更好。期待各位的留言和想法。

鞠躬敬礼!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: