思归呓语

衣带渐宽终不悔,为伊消得人憔悴
随笔 - 413, 评论 - 2972, 引用 - 245

导航

关于

标签

每月存档

最新留言

广告

Pex

在PDC上的一个讲座中,微软研究所展示了一个工具,叫Pex (Program EXploration - 程序探索):

Research: Contract Checking and Automated Test Generation with Pex
http://channel9.msdn.com/pdc2008/TL51/

 

Pex项目地址:
http://msdn.microsoft.com/en-us/devlabs/cc950525.aspx

(上面链接里的下载好像是针对VS 2010的,其他的版本可在这个地址http://research.microsoft.com/Pex/downloads.aspx下载)

 

Pex是个白盒测试生成工具,可以用于帮助理解.NET代码的行为,调试问题,以及,完全自动地,创建涵盖所有边界案例的全套测试。它提供了与VS的集成。

在安装之后,如果在自己的代码中点击右鼠标,然后在上下文菜单中选择运行Pex探索(“Run Pex Explorations”)的话,它会用不同的输入运行你的代码很多次。这些输入不是任意的,也不是所有可能输入的全部组合,而是根据你的代码,分析出其中的边界条件,选出有代表性的输入。简单地说,Pex会分析每一句代码,会琢磨出达到该语句的测试输入。如果代码中有条件性分支,Pex会做案例分析,即Pex会根据代码中条件分支的数目和可能组合生成对应的测试输入。

Pex是在一个反馈循环中运作的: Pex运行代码多次,通过监测控制和数据分流,了解程序的行为。每次运行之后,Pex会挑一个早先没有覆盖的分支,建造一个描述如何达到那个分支的约束系统,然后使用约束解算器(constraint solver,这个版本用了一个叫Z3的约束解算器)决定满足对应约束的新测试输入。然后用新的输入再次运行测试。。。这个过程会重复多次。每次运行,Pex也许会发现新的代码,深入代码实现之中。通过这个方式,Pex可以探索代码的行为。

在VS中,在运行Pex探索之后,在探索结果中选择某个输入,然后选择保存测试案例的话,Pex会为你的代码生成一个测试项目,在其中生成测试类以及相关测试方法。当然你也可以选择所有的输入场景,然后保存所有的测试案例,供你做regression测试之用。

Pex在探索代码、生成测试输入时也会跟踪代码覆盖率。但Pex只有局部的覆盖率知识(Pex称之为动态覆盖率),只有VS代码覆盖率收集器才能给你提供全局的覆盖率信息。

在Pex的新手起步网页上有个简短的代码挖掘教程http://research.microsoft.com/pex/articles/pexcodediggertutorial.pdf 

 

新手起步网页上,还有更深入的教程,原理概述,参考手册和例程等等。

posted on 2008-11-06 14:39:47 by saucer  评论(0) 阅读(6366)

想成为出色的程序员,你必须承认你是个糟糕的程序员

Ted Neward在最近的博客里引用了这个博客里的有点“禅”味的句子,

To be a Great Programmer, you must admit that you are a Terrible Programmer
(想成为出色的程序员,你必须承认你是个糟糕的程序员)

然后他说,

"I am human, therefore I make mistakes. If I make mistakes, then I cannot assume that I will write code that has no mistakes. If I cannot write code that has no mistakes, then I must assume that mistakes are rampant within the code. If mistakes are rampant within the code, then I must find them. But because I make mistakes, then I must also assume that I make mistakes trying to identify the mistakes in the code. Therefore, I will seek the best support I can find in helping me find the mistakes in my code."
(我是人,因此我犯错。如果我犯错,那么我不能假定我写的代码不会有错。如果我不能写出没有错的代码,那么我必须假定代码内错误横行。如果代码内错误横行,那么我必须找到它们。但因为我犯错,那么我还必须假定在代码内试着找错时也会犯错。因此,我必须寻求我所能找到的最好的支持,来帮我在我的代码内找到错误。)

这样的支持包括,
1. 使用一门静态类型的语言 (编译时和运行时的类型检查等),使用静态分析工具(Static Analysis Tool)
2. 大量使用断言(assertion)
3. 疯狂的测试(Testing Masochism--Masochism,根据在线字典,是受虐狂(“sexual pleasure obtained from receiving punishment (physical or psychological)”)的意思,即到了“以测试为乐,以break one’s own code为乐”的境地),追求测试涵盖范围至百分之百
4. 冷酷但诚实的代码评审
5. 对可见系统当机(Visible Crash)的追求(即不隐藏错误/异常,让错误/异常以导致当机的形式暴露出来)

鉴于多线程/并发代码中的缺陷很难找,Ted Neward认为业界里流行的说法“dynamic-language-authored code can be proven correct by simple use of unit tests(用动态语言编写的代码使用单元测试即可证明其之正确性)”是有问题的,认为我们需要各种形式的支持,我们需要更好的静态分析工具,而不是完全抛弃它们。

posted on 2007-11-06 02:48:00 by saucer  评论(12) 阅读(5021)

编程道场

近年在法国,芬兰等地流行一种程序员活动的形式,叫“Coding Dojo(编程道场)”,围绕着小规模的编程主题挑战进行研究(有点模仿Dave Thomas的Coding Kata的意思),各种不同水平的程序员在一起探讨某个问题的解决方案。芬兰的活动有这样一些规矩


1.参与人数不超过15人
2.编程挑战的主题会预先告知
3.活动之前会预先公布即将进行的活动将采用的编程语言
4.实际的编程以迭代的形式进行,在每个编程迭代前,可以有一段简短的计划时间
5.主持人起项目所有者的作用
6.活动房间内有一台计算机连到大屏幕上
7.开始时,主持人解释编程挑战内容,然后从与会人中挑选二人开始“乱战(Randori,散打?)"
8.上场的二人必须使用测试驱动开发(TDD)
9.每5分钟换掉其中一人
10.上场的二人要不停地解释他们在做什么
11.观众中有人提问或不理解的话,他们必须中止,直到理解为止
12.编程测试出现绿灯时,观众才能对设计进行评论(在红灯期间观众只可以问问题)
13.观众对当前的设计不满意的话,上场的二人不可以编写新代码(在编写新代码之前,必须对当前代码进行重构)
14.所有的生成的代码在Apache License(2.0版)许可下公开

芬兰以往的活动有这样一些主题
1.计算网球得分
2.对一手扑克牌进行分类
3.用ruby on rails建造一个基于web的blackjack游戏
4.建造Connect Four(四子棋?)的领域模型
5.建造数独(Sudoku)游戏的领域模型
6.建造一个可交互的Commodore 64 Basic解释器,采用了一个Java的行为驱动开发框架(BDD)

在编程道场的网站上,列出了一些可以做练习的主题(Kata-日文“型”-大概是招式,套路的意思):
1.计算随购买数量而变的折扣书的金额(我对该题目做了大概翻译,点击这里阅读
2.从ASCII图形中读出数字并做验证,然后输出,对出错的图形进行校正
3.对扑克牌的手数进行分类,并辨别赢家
4.保龄球记分(好像跟Robert Martin的模式书里的类似)
5.输出1到100的数字,但如果是3的倍数,就不输出这个数字,而是输出“Fizz”,5的倍数就用“Buzz”代替,如果同时是3和5的倍数就输出“FizzBuzz”
6.扫雷游戏
7.Reversi(翻转棋)游戏,根据当前布置,返回合法的着法

posted on 2007-11-01 02:11:00 by saucer  评论(4) 阅读(4789)

【小题大做】测试该如何驱动设计 - 我大概会这么做

就象我在前面一个贴子的答复里说的,TDD反转了传统的设计-编码-测试的过程,变成测试-编码-设计(重构)的过程,这会带来什么样的效果,你大概可以从无穷多的地方读到,我就不重复了。在这里我只想对上个贴子里那个简单的例子做个示范,写些小测试,认定需求里的假设,按部就班地推出满足需求的行为。有点小题大做的感觉,而且由于该例子的procedure的本质,并没有显示出TDD的威力来。因为比较长,我把它放在文章里了,点击这里阅读。

posted on 2007-10-22 12:08:00 by saucer  评论(2) 阅读(5203)

【问题】测试该如何驱动开发?

在JavaEye上看到gigix的一篇贴子,《测试如何驱动开发

“需求:反转一个句子
我可能会写出以下的测试——写一个测试,然后写代码让测试通过,然后再写下一个测试。
自己看吧。

代码

  1. public class StringReverseTest {    
  2.   # Test 1
  3. public void testShouldSplitSentenceIntoWords(){    
  4.     StringReverser sr=new StringReverser();    
  5.     String str = "This is a sentence";    
  6.     Assert.assertEquals(4, sr.split(str).size());  
  7.     Assert.assertEquals("sentence", sr.split(str).get(0));    
  8.     Assert.assertEquals("a", sr.split(str).get(1));    
  9.     Assert.assertEquals("is", sr.split(str).get(2));    
  10.     Assert.assertEquals("This", sr.split(str).get(3));    
  11.   }    
  12.   # Test 2
  13. public void testShouldReverseSentence(){    
  14.     StringReverser sr=new StringReverser();    
  15.     String str = "Tdd is a software devolopment technology";    
  16.     Assert.assertEquals("technology devolopment software a is Tdd",sr.reverse(str));    
  17.   }    
  18.   # Test 3
  19. public void testShouldAlwaysReverseSentences(){    
  20.     StringReverser sr=new StringReverser();    
  21.     String str = "This is Yet Another sentence";    
  22.     Assert.assertEquals("sentence Another Yet is This",sr.reverse(str));    
  23.   }    
  24. }    

他写的第一个测试方法名叫“testShouldSplitSentenceIntoWords”, 是验证StringReverser这个类会用split方法将一个句子分成4个词,这4个词的顺序与原来句子里的顺序相反。

第二个方法名叫“testShouldReverseSentence”,测试这个类的reverse方法把一个句子里的词反向。

第三个测试方法叫“testShouldAlwaysReverseSentences”,做同样的事情。

读完测试代码后,虽说测试代码有颗粒大小之说,但还是感觉这里好像跳跃比较快。当然,TDD中测试代码的步子是因人而已的。

如果是你做,你会怎么做?怎么写测试代码?然后为让测试通过,该怎么编写应用代码? 记住,“Test-Driven Development Is Not About Testing”。

当然,原来的需求不是很清晰,“反转一个句子”的确切定义是什么?譬如,这个句子允许象句号这样的标点符号么?如果允许的话,反转后,这句号是出现在前面还是后面?这句子里允许有嵌套的句子么?譬如这样的句子,

He said, "This is confusing..."

"This is confusing..."本身需要反转么还是可以当作一个单元而不需要反转?

等等,但根据上面的测试方法的实现,我们先来把需求整理一下,我们会传给这个类一个字符串,字符串中内含N个词,词之间有空格隔开,你的任务是把这个字符串里的词反向排列后再用空格隔开将其输出来。(虽然象我这样爱吹毛求疵的人大概还会问,如果两个词之间有多个空格,输出时,也需要输出多个空格么?)至于怎么排除其他类型的字符,譬如,含有标点的,嵌套句子的情形,假设在前面已经有个类把用户原先输入的字符做过整理了。

再考虑一下,如果需要保留空格的多少又怎么从测试驱动设计?如果遇上“test-driven”这样的组合词呢?把这些认为是需求的改变好了,在面临需求的改变时,你又该怎么做?你的代码是否容易修改?

同时参考一下第二页上“抛出异常的爱”的答复

posted on 2007-10-17 02:46:00 by saucer  评论(3) 阅读(5978)

Powered by: Joycode.MVC引擎 0.5.2.0