<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>进化的测试 &#187; 白盒测试</title>
	<atom:link href="http://magustest.com/blog/tag/whiteboxtesting/feed/" rel="self" type="application/rss+xml" />
	<link>http://magustest.com/blog</link>
	<description>关注软件测试，白盒测试，自动化测试，性能测试</description>
	<lastBuildDate>Wed, 02 Jun 2010 16:12:11 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
<xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" />
		<item>
		<title>单元测试中的异常处理</title>
		<link>http://magustest.com/blog/whiteboxtesting/exception-handling-in-unit-test/</link>
		<comments>http://magustest.com/blog/whiteboxtesting/exception-handling-in-unit-test/#comments</comments>
		<pubDate>Tue, 31 Mar 2009 02:21:42 +0000</pubDate>
		<dc:creator>magus</dc:creator>
				<category><![CDATA[白盒测试]]></category>
		<category><![CDATA[软件测试]]></category>
		<category><![CDATA[单元测试]]></category>
		<category><![CDATA[自动化测试]]></category>
		<category><![CDATA[集成测试]]></category>

		<guid isPermaLink="false">http://magustest.com/blog/?p=398</guid>
		<description><![CDATA[最近项目不是十分多，所以大部分的学习来自于书本还有同行的博客，淘宝的QA Team博客就是一个很好博客，里面N多淘宝的工程师写，而且更新的非常频繁，质量也很好。翠翠同学以后就要加入淘宝了，以后就能看到他写的博客了。 早上来看到一篇文章，大概讲的是在单元测试中容易用到了Try&#8230;Catch语句而容易出现的一个错误，这里想说一下我对单元测试中异常处理的。记得一个牛人曾经说过（实在想不起来谁也搜不到），大概的意思就是“处理一个问题的最好的办法就是不去处理它”。我不知道当时他讲这句话的具体场景是什么，不过我觉得这句话用在单元测试的异常处理中还是比较合适的。 首先来看看两条关于异常处理的原则 如果无法处理某个异常，那么就不要捕获它 如果捕获到一个异常，那么不要胡乱处理它 单元测试的代码和开发的生产代码，虽然同是程序代码，但是他们存在的意义是不一样的。前者是验证程序的正确性，属于为程序服务的；后者是实现某种功能，属于为客户服务的。然后在看上面的两条异常处理的原则。 作为测试代码，如果捕获到一个异常，其实是无法处理它的。从某种角度来看，测试代码和被测代码是不在一个系统中，AUT所抛出的异常，测试代码无法处理，其实也无需处理。 假如测试代码捕获了一个异常，那么唯一能做的事情就是把这个异常重新包装一下，或者直接重新抛出给单元测试框架，然后由单元测试框架打印到界面上或者是执行结果中。但是其实我们什么都不做（不用Try&#8230;Catch）也能达到这样的效果。 可能会有这样的一些测试用例：在输入某些数据的情况下，该函数会抛出某异常。测试工程师就是要验证有异常的抛出。如果是这样的情况，可以用ExpectedException的Attribute（.NET）来标识出该测试代码必须要抛出该异常，如果没有抛出，该测试就是失败。 所以在单元测试的代码中出现Try&#8230;Catch其实是没有必要的，如果是真的觉得要使用Try&#8230;Catch才能完成某些用例，那么我觉得可以重新设计测试用例，或者测试用例的实现。Try&#8230;Catch增加了测试代码的不确定性，而这样的不确定性会导致诡异的自动化测试脚本的出现。在回归测试的过程中就有可能出现运行10次测试，有2次失败8次成功的情况。 不过在单元测试（集成测试）中Try&#8230;Finally语句的使用还是很有必要的，例如我们会把数据库链接释放的代码放在Finally语句块中，保证测试运行无论成功还是失败，都能释放数据库链接，或者其他昂贵的系统资源。 总结：在单元测试（集成测试等……）中，尽量不要使用Try&#8230;Catch代码块；如果需要释放昂贵或者有限的系统资源、做清理工作，可以把相关的代码放在Finally代码块中。 参考资料： 异常处理 &#8211; MSDN 异常处理原则 理解.NET中的异常 单元测试之新手最容易犯的错误 Share and Enjoy: Related posts:自动化单元测试要点


Related posts:<ol><li><a href='http://magustest.com/blog/whiteboxtesting/unit-test-and-integration-test/' rel='bookmark' title='Permanent Link: 自动化单元测试要点'>自动化单元测试要点</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>最近项目不是十分多，所以大部分的学习来自于书本还有同行的博客，<a href="http://rdc.taobao.com/blog/qa/" target="_blank">淘宝的QA Team博客</a>就是一个很好博客，里面N多淘宝的工程师写，而且更新的非常频繁，质量也很好。翠翠同学以后就要加入淘宝了，以后就能看到他写的博客了。</p>
<p>早上来看到一篇文章，大概讲的是在单元测试中容易用到了Try&#8230;Catch语句而容易出现的一个错误，这里想说一下我对单元测试中异常处理的。记得一个牛人曾经说过（实在想不起来谁也搜不到），大概的意思就是“<strong>处理一个问题的最好的办法就是不去处理它</strong>”。我不知道当时他讲这句话的具体场景是什么，不过我觉得这句话用在单元测试的异常处理中还是比较合适的。</p>
<p>首先来看看两条关于异常处理的原则</p>
<ul>
<li>如果无法处理某个异常，那么就不要捕获它</li>
<li>如果捕获到一个异常，那么不要胡乱处理它</li>
</ul>
<p>单元测试的代码和开发的生产代码，虽然同是程序代码，但是他们存在的意义是不一样的。前者是验证程序的正确性，属于为程序服务的；后者是实现某种功能，属于为客户服务的。然后在看上面的两条异常处理的原则。<br />
<span id="more-398"></span></p>
<ul>
<li> 作为测试代码，如果捕获到一个异常，其实是无法处理它的。从某种角度来看，测试代码和被测代码是不在一个系统中，AUT所抛出的异常，测试代码无法处理，其实也无需处理。</li>
<li>假如测试代码捕获了一个异常，那么唯一能做的事情就是把这个异常重新包装一下，或者直接重新抛出给单元测试框架，然后由单元测试框架打印到界面上或者是执行结果中。但是其实我们什么都不做（不用Try&#8230;Catch）也能达到这样的效果。</li>
</ul>
<p>可能会有这样的一些测试用例：在输入某些数据的情况下，该函数会抛出某异常。测试工程师就是要验证有异常的抛出。如果是这样的情况，可以用ExpectedException的Attribute（.NET）来标识出该测试代码必须要抛出该异常，如果没有抛出，该测试就是失败。</p>
<p>所以在单元测试的代码中出现Try&#8230;Catch其实是没有必要的，如果是真的觉得要使用Try&#8230;Catch才能完成某些用例，那么我觉得可以重新设计测试用例，或者测试用例的实现。Try&#8230;Catch增加了测试代码的不确定性，而这样的不确定性会导致<a href="http://magustest.com/blog/softwaretesting/automationtesting/avoid-flakey-automation-test/" target="_blank">诡异的自动化测试脚本</a>的出现。在回归测试的过程中就有可能出现运行10次测试，有2次失败8次成功的情况。</p>
<p>不过在单元测试（集成测试）中Try&#8230;Finally语句的使用还是很有必要的，例如我们会把数据库链接释放的代码放在Finally语句块中，保证测试运行无论成功还是失败，都能释放数据库链接，或者其他昂贵的系统资源。</p>
<p>总结：在单元测试（集成测试等……）中，尽量不要使用Try&#8230;Catch代码块；如果需要释放昂贵或者有限的系统资源、做清理工作，可以把相关的代码放在Finally代码块中。</p>
<p><strong>参考资料：</strong></p>
<p><a href="http://msdn.microsoft.com/zh-cn/library/ms229005.aspx" target="_blank">异常处理 &#8211; MSDN</a></p>
<p><a href="http://www.blogjava.net/usherlight/archive/2006/10/23/76782.html" target="_blank">异常处理原则</a></p>
<p><a href="http://www.cnblogs.com/anderslly/archive/2007/03/15/675642.html" target="_blank">理解.NET中的异常</a></p>
<p><a href="http://rdc.taobao.com/blog/qa/?p=1317" target="_blank">单元测试之新手最容易犯的错误</a></p>



Share and Enjoy:


	<a rel="nofollow"  target="_blank" href="http://magustest.com/blog/feed/" title="RSS"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/rss.png" title="RSS" alt="RSS" class="sociable-hovers" /></a>
	<img src="http://magustest.com/blog/wp-content/plugins/sociable/images/googlebookmark.png" title="Google Bookmarks" alt="Google Bookmarks" class="sociable-hovers" /></a>
	<img src="http://magustest.com/blog/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<img src="http://magustest.com/blog/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://www.facebook.com/share.php?u=http%3A%2F%2Fmagustest.com%2Fblog%2Fwhiteboxtesting%2Fexception-handling-in-unit-test%2F&amp;t=%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E4%B8%AD%E7%9A%84%E5%BC%82%E5%B8%B8%E5%A4%84%E7%90%86" title="Facebook"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/facebook.png" title="Facebook" alt="Facebook" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://www.douban.com/recommend/?url=http%3A%2F%2Fmagustest.com%2Fblog%2Fwhiteboxtesting%2Fexception-handling-in-unit-test%2F&title=%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E4%B8%AD%E7%9A%84%E5%BC%82%E5%B8%B8%E5%A4%84%E7%90%86" title="豆瓣"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/douban.png" title="豆瓣" alt="豆瓣" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://www.douban.com/recommend/?url=http%3A%2F%2Fmagustest.com%2Fblog%2Fwhiteboxtesting%2Fexception-handling-in-unit-test%2F&title=%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E4%B8%AD%E7%9A%84%E5%BC%82%E5%B8%B8%E5%A4%84%E7%90%86&n=1" title="豆瓣九点"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/douban9.png" title="豆瓣九点" alt="豆瓣九点" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://www.friendfeed.com/share?title=%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E4%B8%AD%E7%9A%84%E5%BC%82%E5%B8%B8%E5%A4%84%E7%90%86&amp;link=http%3A%2F%2Fmagustest.com%2Fblog%2Fwhiteboxtesting%2Fexception-handling-in-unit-test%2F" title="FriendFeed"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/friendfeed.png" title="FriendFeed" alt="FriendFeed" class="sociable-hovers" /></a>
	<img src="http://magustest.com/blog/wp-content/plugins/sociable/images/linkedin.png" title="LinkedIn" alt="LinkedIn" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="https://favorites.live.com/quickadd.aspx?marklet=1&amp;url=http%3A%2F%2Fmagustest.com%2Fblog%2Fwhiteboxtesting%2Fexception-handling-in-unit-test%2F&amp;title=%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E4%B8%AD%E7%9A%84%E5%BC%82%E5%B8%B8%E5%A4%84%E7%90%86" title="Live"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/live.png" title="Live" alt="Live" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://ping.fm/ref/?link=http%3A%2F%2Fmagustest.com%2Fblog%2Fwhiteboxtesting%2Fexception-handling-in-unit-test%2F&amp;title=%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E4%B8%AD%E7%9A%84%E5%BC%82%E5%B8%B8%E5%A4%84%E7%90%86&amp;body=%E6%9C%80%E8%BF%91%E9%A1%B9%E7%9B%AE%E4%B8%8D%E6%98%AF%E5%8D%81%E5%88%86%E5%A4%9A%EF%BC%8C%E6%89%80%E4%BB%A5%E5%A4%A7%E9%83%A8%E5%88%86%E7%9A%84%E5%AD%A6%E4%B9%A0%E6%9D%A5%E8%87%AA%E4%BA%8E%E4%B9%A6%E6%9C%AC%E8%BF%98%E6%9C%89%E5%90%8C%E8%A1%8C%E7%9A%84%E5%8D%9A%E5%AE%A2%EF%BC%8C%E6%B7%98%E5%AE%9D%E7%9A%84QA%20Team%E5%8D%9A%E5%AE%A2%E5%B0%B1%E6%98%AF%E4%B8%80%E4%B8%AA%E5%BE%88%E5%A5%BD%E5%8D%9A%E5%AE%A2%EF%BC%8C%E9%87%8C%E9%9D%A2N%E5%A4%9A%E6%B7%98%E5%AE%9D%E7%9A%84%E5%B7%A5%E7%A8%8B%E5%B8%88%E5%86%99%EF%BC%8C%E8%80%8C%E4%B8%94%E6%9B%B4%E6%96%B0%E7%9A%84%E9%9D%9E%E5%B8%B8%E9%A2%91%E7%B9%81%EF%BC%8C%E8%B4%A8%E9%87%8F%E4%B9%9F%E5%BE%88%E5%A5%BD%E3%80%82%E7%BF%A0%E7%BF%A0%E5%90%8C%E5%AD%A6%E4%BB%A5%E5%90%8E%E5%B0%B1%E8%A6%81%E5%8A" title="Ping.fm"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/ping.png" title="Ping.fm" alt="Ping.fm" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://shuqian.qq.com/post?jumpback=1&title=%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E4%B8%AD%E7%9A%84%E5%BC%82%E5%B8%B8%E5%A4%84%E7%90%86&uri=http%3A%2F%2Fmagustest.com%2Fblog%2Fwhiteboxtesting%2Fexception-handling-in-unit-test%2F" title="QQ书签"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/qq.png" title="QQ书签" alt="QQ书签" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://twitter.com/home?status=%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E4%B8%AD%E7%9A%84%E5%BC%82%E5%B8%B8%E5%A4%84%E7%90%86%20-%20http%3A%2F%2Fmagustest.com%2Fblog%2Fwhiteboxtesting%2Fexception-handling-in-unit-test%2F" title="Twitter"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/twitter.png" title="Twitter" alt="Twitter" class="sociable-hovers" /></a>


<br/><br/>

<p>Related posts:<ol><li><a href='http://magustest.com/blog/whiteboxtesting/unit-test-and-integration-test/' rel='bookmark' title='Permanent Link: 自动化单元测试要点'>自动化单元测试要点</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://magustest.com/blog/whiteboxtesting/exception-handling-in-unit-test/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>自动化单元测试要点</title>
		<link>http://magustest.com/blog/whiteboxtesting/unit-test-and-integration-test/</link>
		<comments>http://magustest.com/blog/whiteboxtesting/unit-test-and-integration-test/#comments</comments>
		<pubDate>Sat, 07 Mar 2009 14:13:26 +0000</pubDate>
		<dc:creator>magus</dc:creator>
				<category><![CDATA[白盒测试]]></category>
		<category><![CDATA[自动化测试]]></category>
		<category><![CDATA[软件测试]]></category>
		<category><![CDATA[单元测试]]></category>
		<category><![CDATA[接口测试]]></category>
		<category><![CDATA[集成测试]]></category>

		<guid isPermaLink="false">http://magustest.com/blog/?p=362</guid>
		<description><![CDATA[用单元测试的框架MSTEST，做单元测试，集成测试快1年了，总结一下工作中学到都东西。 单元测试，集成测试有什么用？ 1. 改进产品质量 软件测试，很多时候围绕着两个问题： Verification和Validation，常说的双V。前面的Verification就是Is the software built correctly?。后面的Validation就是Have we built the right software? 单元测试，更多的是Verification。所以有时候经过我单元测试和集成测试以后的功能模块，在交给其他同事做功能测试的时候，依然会有一些BUG，这时候开发可能会埋怨我测试得不够完全，诸如此类。但是其实很多时候，我的关注点是单个方法的功能、行为，没有站到更高的位置来测试这个模块。对于这样的问题，开发和测试应该互相体谅，我本人也会提高自身的水平。希望在单元测试和集成测试中也加入更多关于Validation的思考。 有一个提法叫Tests as Specification，单元测试本身其实就是模拟某个模块的使用者（其他的程序）来进行测试。很多时候我写的测试代码也是其他开发人员的参考，尤其在一些事实上或者只是号称自己是敏捷开发的组织里面，测试代码有可能成为详细设计的替代品，因为有可能根本没有详细设计文档。 单元测试的另一个工作就是发现并且定位BUG。对于BUG的定位和重现，在单元测试代码的编写过程中，每个Assert语句后面都要加上尽可能详细的信息，例如导致这个Assert语句失败的每个参数值，期望结果，实际结果等，这些信息可以帮助开发和测试快速定位问题，减少不必要的DEBUG时间。 2. 降低项目的风险 软件测试，其实是用有限来验证无限的一个过程，很多时候做什么样的测试，做到什么样的程度，很多时候都跟风险有关系。 作为产品的安全网，各种测试在项目中都扮演着重要的角色。例如，中美交互的几十个Web Service接口的回归测试，现在有若干个测试，每天定时做回归测试，因为没人知道在美国的服务器会发生什么事情；对于中国的Web Service，在上线前都会通过回归测试，才部署上线。还有全站的Platform Service接口，每次上线前都需要在做回归测试。软件测试的另一个有趣的结论就是：测试只能证明软件有BUG，但是无论什么样的测试，都不能证明被测软件是没有BUG的。问题出来了，我做完回归测试，都通过了，但是我却不能证明这个软件是没有BUG的。其实每次上线，团队都承担着风险，只不过这样的风险在完成回归测试之后，大家上线的信心增加，风险明显地减小。 什么样的测试才是好的测试？ 1. 容易运行 什么样的单元测试是容易运行？答案很简单，自动化的单元测试就是容易运行的测试。如果一批测试在运行之前每次都需要重装系统然后还要找一大堆需要依赖的软件来装上，最后还要输入奇怪的命令才能运行，那么就不是一个好的测试（本人真的见过这样的测试，囧）。个人认为，配置好的持续集成系统，可以实现很好的自动化测试；如果没有一个完善的CI，那么一个one click的自动化测试运行也是一个较好的选择。 2. 自动检查结果 一句话：没有自动检查结果，再好的自动化也是白搭。 3. 可重复 一句话：只能运行一次的单元测试也是白搭。 4. 独立 其实测试的独立，也有利于实现可重复。刚做单元测试的时候，曾经犯过这样的错误，我在写A测试的时候，给数据库插入了一条记录，然后我在写B测试的时候，就觉得我为什么要在两个测试中分别创建两条数据？直接用上一个测试的数据就可以了。不过结果还好，我很快就发现这样做是有问题。单元测试的独立，就是运行测试的人可以先运行A测试，也可以先运行B测试，也可以单独运行A或者B测试，甚至可以A和B测试同时运行。 5. 简单 有时候，测试的代码写的有点复杂，嵌套的语句有点多，可能有些人会觉得写出复杂的单元测试代码才能体现自己的水平，但是，我觉得对于单元测试代码来说，应该越简单越好。最好就是顺序执行下来了，不要有什么分支。因为测试代码本身就是也是代码，那么怎么去验证测试代码写的正确呢？答案可能是再写一个测试代码去验证第一个测试代码。这样就会有死循环了。一个简单的假设就是，如果测试代码足够简单，那么就可以认为测试代码是正确的，无需其他代码对之进行测试。 6. 专注 一个测试应该只测试一个点。如果在一个测试里面验证多个测试点，看起来是比较高效的一种做法，但是当测试中有Assert语句抛出异常的时候，很有可能需要花大量的时间才能找到真正错误的代码，这样不利于实现前面提及到的“定位BUG”。 7. 注释 注释其实就是把代码抽取成可阅读的测试用例，如果别人看自己的程序，可以快速理解测试代码；同时注释还能唤醒自己沉睡的记忆和当时的测试思路。 国内做单元测试的测试工程师少，做集成测试、接口测试的也不多，埋头做事,别忘抬头看路。时常总结，提高自我。 Share and Enjoy: Related [...]


Related posts:<ol><li><a href='http://magustest.com/blog/readingdaily/software-testing-note-part-three/' rel='bookmark' title='Permanent Link: 《Software Testing》第三章 &#8211; 软件测试'>《Software Testing》第三章 &#8211; 软件测试</a></li>
<li><a href='http://magustest.com/blog/whiteboxtesting/exception-handling-in-unit-test/' rel='bookmark' title='Permanent Link: 单元测试中的异常处理'>单元测试中的异常处理</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>用单元测试的框架MSTEST，做单元测试，集成测试快1年了，总结一下工作中学到都东西。</p>
<p><span style="color: #ff0000;"><strong>单元测试，集成测试有什么用？</strong></span></p>
<p><strong>1. 改进产品质量</strong></p>
<p>软件测试，很多时候围绕着两个问题：</p>
<p>Verification和Validation，常说的双V。前面的Verification就是Is the software built correctly?。后面的Validation就是Have we built the right software?</p>
<p>单元测试，更多的是Verification。所以有时候经过我单元测试和集成测试以后的功能模块，在交给其他同事做功能测试的时候，依然会有一些BUG，这时候开发可能会埋怨我测试得不够完全，诸如此类。但是其实很多时候，我的关注点是单个方法的功能、行为，没有站到更高的位置来测试这个模块。对于这样的问题，开发和测试应该互相体谅，我本人也会提高自身的水平。希望在单元测试和集成测试中也加入更多关于Validation的思考。<br />
<span id="more-362"></span><br />
有一个提法叫Tests as Specification，单元测试本身其实就是模拟某个模块的使用者（其他的程序）来进行测试。很多时候我写的测试代码也是其他开发人员的参考，尤其在一些事实上或者只是号称自己是敏捷开发的组织里面，测试代码有可能成为详细设计的替代品，因为有可能根本没有详细设计文档。</p>
<p>单元测试的另一个工作就是发现并且定位BUG。对于BUG的定位和重现，在单元测试代码的编写过程中，每个Assert语句后面都要加上尽可能详细的信息，例如导致这个Assert语句失败的每个参数值，期望结果，实际结果等，这些信息可以帮助开发和测试快速定位问题，减少不必要的DEBUG时间。</p>
<p><strong>2. 降低项目的风险</strong></p>
<p>软件测试，其实是用有限来验证无限的一个过程，很多时候做什么样的测试，做到什么样的程度，很多时候都跟风险有关系。</p>
<p>作为产品的安全网，各种测试在项目中都扮演着重要的角色。例如，中美交互的几十个Web Service接口的回归测试，现在有若干个测试，每天定时做回归测试，因为没人知道在美国的服务器会发生什么事情；对于中国的Web Service，在上线前都会通过回归测试，才部署上线。还有全站的Platform Service接口，每次上线前都需要在做回归测试。软件测试的另一个有趣的结论就是：测试只能证明软件有BUG，但是无论什么样的测试，都不能证明被测软件是没有BUG的。问题出来了，我做完回归测试，都通过了，但是我却不能证明这个软件是没有BUG的。其实每次上线，团队都承担着风险，只不过这样的风险在完成回归测试之后，大家上线的信心增加，风险明显地减小。</p>
<p><span style="color: #ff0000;"><strong>什么样的测试才是好的测试？</strong></span></p>
<p><strong>1. 容易运行</strong></p>
<p>什么样的单元测试是容易运行？答案很简单，自动化的单元测试就是容易运行的测试。如果一批测试在运行之前每次都需要重装系统然后还要找一大堆需要依赖的软件来装上，最后还要输入奇怪的命令才能运行，那么就不是一个好的测试（本人真的见过这样的测试，囧）。个人认为，配置好的持续集成系统，可以实现很好的自动化测试；如果没有一个完善的CI，那么一个one click的自动化测试运行也是一个较好的选择。</p>
<p><strong>2. 自动检查结果</strong></p>
<p>一句话：没有自动检查结果，再好的自动化也是白搭。</p>
<p><strong>3. 可重复</strong></p>
<p>一句话：只能运行一次的单元测试也是白搭。</p>
<p><strong>4. 独立</strong></p>
<p>其实测试的独立，也有利于实现可重复。刚做单元测试的时候，曾经犯过这样的错误，我在写A测试的时候，给数据库插入了一条记录，然后我在写B测试的时候，就觉得我为什么要在两个测试中分别创建两条数据？直接用上一个测试的数据就可以了。不过结果还好，我很快就发现这样做是有问题。单元测试的独立，就是运行测试的人可以先运行A测试，也可以先运行B测试，也可以单独运行A或者B测试，甚至可以A和B测试同时运行。</p>
<p><strong>5. 简单</strong></p>
<p>有时候，测试的代码写的有点复杂，嵌套的语句有点多，可能有些人会觉得写出复杂的单元测试代码才能体现自己的水平，但是，我觉得对于单元测试代码来说，应该越简单越好。最好就是顺序执行下来了，不要有什么分支。因为测试代码本身就是也是代码，那么怎么去验证测试代码写的正确呢？答案可能是再写一个测试代码去验证第一个测试代码。这样就会有死循环了。一个简单的假设就是，如果测试代码足够简单，那么就可以认为测试代码是正确的，无需其他代码对之进行测试。</p>
<p><strong>6. 专注</strong></p>
<p>一个测试应该只测试一个点。如果在一个测试里面验证多个测试点，看起来是比较高效的一种做法，但是当测试中有Assert语句抛出异常的时候，很有可能需要花大量的时间才能找到真正错误的代码，这样不利于实现前面提及到的“定位BUG”。</p>
<p><strong>7. 注释</strong></p>
<p>注释其实就是把代码抽取成可阅读的测试用例，如果别人看自己的程序，可以快速理解测试代码；同时注释还能唤醒自己沉睡的记忆和当时的测试思路。</p>
<p>国内做单元测试的测试工程师少，做集成测试、接口测试的也不多，埋头做事,别忘抬头看路。时常总结，提高自我。</p>



Share and Enjoy:


	<a rel="nofollow"  target="_blank" href="http://magustest.com/blog/feed/" title="RSS"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/rss.png" title="RSS" alt="RSS" class="sociable-hovers" /></a>
	<img src="http://magustest.com/blog/wp-content/plugins/sociable/images/googlebookmark.png" title="Google Bookmarks" alt="Google Bookmarks" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fmagustest.com%2Fblog%2Fwhiteboxtesting%2Funit-test-and-integration-test%2F&amp;title=%E8%87%AA%E5%8A%A8%E5%8C%96%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E8%A6%81%E7%82%B9&amp;bodytext=%E7%94%A8%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E7%9A%84%E6%A1%86%E6%9E%B6MSTEST%EF%BC%8C%E5%81%9A%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%EF%BC%8C%E9%9B%86%E6%88%90%E6%B5%8B%E8%AF%95%E5%BF%AB1%E5%B9%B4%E4%BA%86%EF%BC%8C%E6%80%BB%E7%BB%93%E4%B8%80%E4%B8%8B%E5%B7%A5%E4%BD%9C%E4%B8%AD%E5%AD%A6%E5%88%B0%E9%83%BD%E4%B8%9C%E8%A5%BF%E3%80%82%0A%0A%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%EF%BC%8C%E9%9B%86%E6%88%90%E6%B5%8B%E8%AF%95%E6%9C%89%E4%BB%80%E4%B9%88%E7%94%A8%EF%BC%9F%0A%0A1.%20%E6%94%B9%E8%BF%9B%E4%BA%A7%E5%93%81%E8%B4%A8%E9%87%8F%0A%0A%E8%BD%AF%E4%BB%B6%E6%B5%8B%E8%AF%95%EF%BC%8C%E5%BE%88%E5%A4%9A%E6%97%B6%E5%80%99%E5%9B%B4%E7%BB%95%E7%9D%80%E4%B8%A4%E4%B8%AA%E9%97%AE%E9%A2%98%EF%BC%9A%0A%0AVerification%E5" title="Digg"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://delicious.com/post?url=http%3A%2F%2Fmagustest.com%2Fblog%2Fwhiteboxtesting%2Funit-test-and-integration-test%2F&amp;title=%E8%87%AA%E5%8A%A8%E5%8C%96%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E8%A6%81%E7%82%B9&amp;notes=%E7%94%A8%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E7%9A%84%E6%A1%86%E6%9E%B6MSTEST%EF%BC%8C%E5%81%9A%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%EF%BC%8C%E9%9B%86%E6%88%90%E6%B5%8B%E8%AF%95%E5%BF%AB1%E5%B9%B4%E4%BA%86%EF%BC%8C%E6%80%BB%E7%BB%93%E4%B8%80%E4%B8%8B%E5%B7%A5%E4%BD%9C%E4%B8%AD%E5%AD%A6%E5%88%B0%E9%83%BD%E4%B8%9C%E8%A5%BF%E3%80%82%0A%0A%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%EF%BC%8C%E9%9B%86%E6%88%90%E6%B5%8B%E8%AF%95%E6%9C%89%E4%BB%80%E4%B9%88%E7%94%A8%EF%BC%9F%0A%0A1.%20%E6%94%B9%E8%BF%9B%E4%BA%A7%E5%93%81%E8%B4%A8%E9%87%8F%0A%0A%E8%BD%AF%E4%BB%B6%E6%B5%8B%E8%AF%95%EF%BC%8C%E5%BE%88%E5%A4%9A%E6%97%B6%E5%80%99%E5%9B%B4%E7%BB%95%E7%9D%80%E4%B8%A4%E4%B8%AA%E9%97%AE%E9%A2%98%EF%BC%9A%0A%0AVerification%E5" title="del.icio.us"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://www.facebook.com/share.php?u=http%3A%2F%2Fmagustest.com%2Fblog%2Fwhiteboxtesting%2Funit-test-and-integration-test%2F&amp;t=%E8%87%AA%E5%8A%A8%E5%8C%96%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E8%A6%81%E7%82%B9" title="Facebook"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/facebook.png" title="Facebook" alt="Facebook" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://www.douban.com/recommend/?url=http%3A%2F%2Fmagustest.com%2Fblog%2Fwhiteboxtesting%2Funit-test-and-integration-test%2F&title=%E8%87%AA%E5%8A%A8%E5%8C%96%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E8%A6%81%E7%82%B9" title="豆瓣"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/douban.png" title="豆瓣" alt="豆瓣" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://www.douban.com/recommend/?url=http%3A%2F%2Fmagustest.com%2Fblog%2Fwhiteboxtesting%2Funit-test-and-integration-test%2F&title=%E8%87%AA%E5%8A%A8%E5%8C%96%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E8%A6%81%E7%82%B9&n=1" title="豆瓣九点"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/douban9.png" title="豆瓣九点" alt="豆瓣九点" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://www.friendfeed.com/share?title=%E8%87%AA%E5%8A%A8%E5%8C%96%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E8%A6%81%E7%82%B9&amp;link=http%3A%2F%2Fmagustest.com%2Fblog%2Fwhiteboxtesting%2Funit-test-and-integration-test%2F" title="FriendFeed"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/friendfeed.png" title="FriendFeed" alt="FriendFeed" class="sociable-hovers" /></a>
	<img src="http://magustest.com/blog/wp-content/plugins/sociable/images/linkedin.png" title="LinkedIn" alt="LinkedIn" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="https://favorites.live.com/quickadd.aspx?marklet=1&amp;url=http%3A%2F%2Fmagustest.com%2Fblog%2Fwhiteboxtesting%2Funit-test-and-integration-test%2F&amp;title=%E8%87%AA%E5%8A%A8%E5%8C%96%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E8%A6%81%E7%82%B9" title="Live"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/live.png" title="Live" alt="Live" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://ping.fm/ref/?link=http%3A%2F%2Fmagustest.com%2Fblog%2Fwhiteboxtesting%2Funit-test-and-integration-test%2F&amp;title=%E8%87%AA%E5%8A%A8%E5%8C%96%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E8%A6%81%E7%82%B9&amp;body=%E7%94%A8%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E7%9A%84%E6%A1%86%E6%9E%B6MSTEST%EF%BC%8C%E5%81%9A%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%EF%BC%8C%E9%9B%86%E6%88%90%E6%B5%8B%E8%AF%95%E5%BF%AB1%E5%B9%B4%E4%BA%86%EF%BC%8C%E6%80%BB%E7%BB%93%E4%B8%80%E4%B8%8B%E5%B7%A5%E4%BD%9C%E4%B8%AD%E5%AD%A6%E5%88%B0%E9%83%BD%E4%B8%9C%E8%A5%BF%E3%80%82%0A%0A%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%EF%BC%8C%E9%9B%86%E6%88%90%E6%B5%8B%E8%AF%95%E6%9C%89%E4%BB%80%E4%B9%88%E7%94%A8%EF%BC%9F%0A%0A1.%20%E6%94%B9%E8%BF%9B%E4%BA%A7%E5%93%81%E8%B4%A8%E9%87%8F%0A%0A%E8%BD%AF%E4%BB%B6%E6%B5%8B%E8%AF%95%EF%BC%8C%E5%BE%88%E5%A4%9A%E6%97%B6%E5%80%99%E5%9B%B4%E7%BB%95%E7%9D%80%E4%B8%A4%E4%B8%AA%E9%97%AE%E9%A2%98%EF%BC%9A%0A%0AVerification%E5" title="Ping.fm"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/ping.png" title="Ping.fm" alt="Ping.fm" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://shuqian.qq.com/post?jumpback=1&title=%E8%87%AA%E5%8A%A8%E5%8C%96%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E8%A6%81%E7%82%B9&uri=http%3A%2F%2Fmagustest.com%2Fblog%2Fwhiteboxtesting%2Funit-test-and-integration-test%2F" title="QQ书签"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/qq.png" title="QQ书签" alt="QQ书签" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://twitter.com/home?status=%E8%87%AA%E5%8A%A8%E5%8C%96%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E8%A6%81%E7%82%B9%20-%20http%3A%2F%2Fmagustest.com%2Fblog%2Fwhiteboxtesting%2Funit-test-and-integration-test%2F" title="Twitter"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/twitter.png" title="Twitter" alt="Twitter" class="sociable-hovers" /></a>


<br/><br/>

<p>Related posts:<ol><li><a href='http://magustest.com/blog/readingdaily/software-testing-note-part-three/' rel='bookmark' title='Permanent Link: 《Software Testing》第三章 &#8211; 软件测试'>《Software Testing》第三章 &#8211; 软件测试</a></li>
<li><a href='http://magustest.com/blog/whiteboxtesting/exception-handling-in-unit-test/' rel='bookmark' title='Permanent Link: 单元测试中的异常处理'>单元测试中的异常处理</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://magustest.com/blog/whiteboxtesting/unit-test-and-integration-test/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>单元测试的坏味道</title>
		<link>http://magustest.com/blog/automationtesting/test-smells/</link>
		<comments>http://magustest.com/blog/automationtesting/test-smells/#comments</comments>
		<pubDate>Wed, 04 Mar 2009 08:59:47 +0000</pubDate>
		<dc:creator>magus</dc:creator>
				<category><![CDATA[自动化测试]]></category>
		<category><![CDATA[软件测试]]></category>
		<category><![CDATA[概念术语]]></category>
		<category><![CDATA[白盒测试]]></category>

		<guid isPermaLink="false">http://magustest.com/blog/?p=355</guid>
		<description><![CDATA[Martin Fowler有一本很出名的书《重构》，里面有个很出名的概念，Code Smell。前阵子我也刚发现一本很好的书，《XUnit Test Patterns》。这本书主要讲的是如何重构测试代码，这里的测试代码指的就是自动化测试的代码，再进一步细化就是单元测试为主的自动化测试代码的重构。由于此书已经让清华大学翻译烂了……所以建议大家下载英文版。 所谓的测试的坏味道，有三种： 项目（Project） 行为（Behavior） 代码（Code） 按照《重构》书中提出的坏味道的概念来看，如果说是有坏味道（Smell），那么大多数都是指代码级别的。什么的坏味道？就是程序有可能会有大问题的一种征兆（symptom）。个人理解就是不能被直接观察到的现象，可以称之为坏味道。 对于自动化测试代码来说，如果有了项目级的坏味道，通常变现就是生产环境出现了BUG。如果出现这样的情况，那么自动化测试代码就不是有味道那么简单了，而是有问题了，自动化测试的安全网没有能够抓住这个BUG。 而行为的坏味道，其中一个表现形式就是我以前写过的在自动化测试中需要避免“诡异”的测试脚本提到的现象。还有诸如编译错误、不能被重复运行的测试等。其实如果我们碰到行为级别的坏味道，那么可以肯定，我们必须要修改它。如果不修复好这些问题，自动化测试根本无法进行。 代码的坏味道，这个才是我们需要注意的问题，因为代码有了坏味道，并不代表着自动化测试代码会运行出错，通常人们是不会去修改没有出错的代码，人之常情。发现测试代码的味道，并且去修复它，会让我们的自动化测试更加健壮。《XUnit Test Patterns》这本书的前言部分给出一个典型的例子来说明单元测试代码中有哪些坏味道，如何去修改。例子中的一些对单元测试的重构方法，我在平时的工作中也应用到了，不过看完了以后真是觉得裨益良多，虽然做了快一年的单元测试，集成测试，但是却没有停下来总结一年中学到了什么，真的要借着读这本书的机会，好好总结。 最近在接回以前的一些测试项目，个人觉得如果测试代码里面不写注释，这样也是一种坏味道。对于一堆测试代码，半年后可能都忘记了当初为什么这样写，尤其是对于没有注释的测试代码。就像我在译言翻译的第一篇文章里面说的那样，“很多时候，你就是注释的第一位受益者，或者受害者”。对于有坏味道的自动化测试代码，你可以让他继续发酵，腐烂，总有一天，你自己要收拾这个残局。 Share and Enjoy: No related posts.


No related posts.]]></description>
			<content:encoded><![CDATA[<p>Martin Fowler有一本很出名的书<a href="http://www.amazon.com/Refactoring-Improving-Existing-Addison-Wesley-Technology/dp/0201485672/ref=sr_1_2?ie=UTF8&amp;s=books&amp;qid=1236154183&amp;sr=8-2" target="_blank">《重构》</a>，里面有个很出名的概念，Code Smell。前阵子我也刚发现一本很好的书，<a href="http://xunitpatterns.com/index.html" target="_blank">《XUnit Test Patterns》</a>。这本书主要讲的是如何重构测试代码，这里的测试代码指的就是自动化测试的代码，再进一步细化就是单元测试为主的自动化测试代码的重构。由于此书已经让清华大学翻译烂了……所以建议大家下载英文版。</p>
<p>所谓的测试的坏味道，有三种：</p>
<ol>
<li>项目（Project）</li>
<li>行为（Behavior）</li>
<li>代码（Code）</li>
</ol>
<p>按照《重构》书中提出的坏味道的概念来看，如果说是有坏味道（Smell），那么大多数都是指代码级别的。什么的坏味道？就是程序有可能会有大问题的一种征兆（symptom）。个人理解就是不能被直接观察到的现象，可以称之为坏味道。</p>
<p>对于自动化测试代码来说，如果有了项目级的坏味道，通常变现就是生产环境出现了BUG。如果出现这样的情况，那么自动化测试代码就不是有味道那么简单了，而是有问题了，自动化测试的安全网没有能够抓住这个BUG。<br />
<span id="more-355"></span><br />
而行为的坏味道，其中一个表现形式就是我以前写过的<a href="http://magustest.com/blog/softwaretesting/automationtesting/avoid-flakey-automation-test/" target="_blank">在自动化测试中需要避免“诡异”的测试脚本</a>提到的现象。还有诸如编译错误、不能被重复运行的测试等。其实如果我们碰到行为级别的坏味道，那么可以肯定，我们必须要修改它。如果不修复好这些问题，自动化测试根本无法进行。</p>
<p>代码的坏味道，这个才是我们需要注意的问题，因为代码有了坏味道，并不代表着自动化测试代码会运行出错，通常人们是不会去修改没有出错的代码，人之常情。发现测试代码的味道，并且去修复它，会让我们的自动化测试更加健壮。<a href="http://xunitpatterns.com/index.html" target="_blank">《XUnit Test Patterns》</a>这本书的前言部分给出一个典型的例子来说明单元测试代码中有哪些坏味道，如何去修改。例子中的一些对单元测试的重构方法，我在平时的工作中也应用到了，不过看完了以后真是觉得裨益良多，虽然做了快一年的单元测试，集成测试，但是却没有停下来总结一年中学到了什么，真的要借着读这本书的机会，好好总结。</p>
<p>最近在接回以前的一些测试项目，个人觉得如果测试代码里面不写注释，这样也是一种坏味道。对于一堆测试代码，半年后可能都忘记了当初为什么这样写，尤其是对于没有注释的测试代码。就像我在译言翻译的第一篇文章里面说的那样，“很多时候，你就是注释的第一位受益者，或者受害者”。对于有坏味道的自动化测试代码，你可以让他继续发酵，腐烂，总有一天，你自己要收拾这个残局。</p>



Share and Enjoy:


	<a rel="nofollow"  target="_blank" href="http://magustest.com/blog/feed/" title="RSS"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/rss.png" title="RSS" alt="RSS" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://www.google.com/bookmarks/mark?op=edit&amp;bkmk=http%3A%2F%2Fmagustest.com%2Fblog%2Fautomationtesting%2Ftest-smells%2F&amp;title=%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E7%9A%84%E5%9D%8F%E5%91%B3%E9%81%93&amp;annotation=Martin%20Fowler%E6%9C%89%E4%B8%80%E6%9C%AC%E5%BE%88%E5%87%BA%E5%90%8D%E7%9A%84%E4%B9%A6%E3%80%8A%E9%87%8D%E6%9E%84%E3%80%8B%EF%BC%8C%E9%87%8C%E9%9D%A2%E6%9C%89%E4%B8%AA%E5%BE%88%E5%87%BA%E5%90%8D%E7%9A%84%E6%A6%82%E5%BF%B5%EF%BC%8CCode%20Smell%E3%80%82%E5%89%8D%E9%98%B5%E5%AD%90%E6%88%91%E4%B9%9F%E5%88%9A%E5%8F%91%E7%8E%B0%E4%B8%80%E6%9C%AC%E5%BE%88%E5%A5%BD%E7%9A%84%E4%B9%A6%EF%BC%8C%E3%80%8AXUnit%20Test%20Patterns%E3%80%8B%E3%80%82%E8%BF%99%E6%9C%AC%E4%B9%A6%E4%B8%BB%E8%A6%81%E8%AE%B2%E7%9A%84%E6%98%AF%E5%A6%82%E4%BD%95%E9%87%8D%E6%9E%84%E6%B5%8B%E8%AF%95%E4%BB%A3%E7%A0%81%EF%BC%8C%E8%BF%99%E9%87%8C%E7%9A%84%E6%B5%8B%E8%AF%95%E4%BB%A3%E7%A0%81%E6%8C%87%E7%9A%84%E5" title="Google Bookmarks"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/googlebookmark.png" title="Google Bookmarks" alt="Google Bookmarks" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fmagustest.com%2Fblog%2Fautomationtesting%2Ftest-smells%2F&amp;title=%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E7%9A%84%E5%9D%8F%E5%91%B3%E9%81%93&amp;bodytext=Martin%20Fowler%E6%9C%89%E4%B8%80%E6%9C%AC%E5%BE%88%E5%87%BA%E5%90%8D%E7%9A%84%E4%B9%A6%E3%80%8A%E9%87%8D%E6%9E%84%E3%80%8B%EF%BC%8C%E9%87%8C%E9%9D%A2%E6%9C%89%E4%B8%AA%E5%BE%88%E5%87%BA%E5%90%8D%E7%9A%84%E6%A6%82%E5%BF%B5%EF%BC%8CCode%20Smell%E3%80%82%E5%89%8D%E9%98%B5%E5%AD%90%E6%88%91%E4%B9%9F%E5%88%9A%E5%8F%91%E7%8E%B0%E4%B8%80%E6%9C%AC%E5%BE%88%E5%A5%BD%E7%9A%84%E4%B9%A6%EF%BC%8C%E3%80%8AXUnit%20Test%20Patterns%E3%80%8B%E3%80%82%E8%BF%99%E6%9C%AC%E4%B9%A6%E4%B8%BB%E8%A6%81%E8%AE%B2%E7%9A%84%E6%98%AF%E5%A6%82%E4%BD%95%E9%87%8D%E6%9E%84%E6%B5%8B%E8%AF%95%E4%BB%A3%E7%A0%81%EF%BC%8C%E8%BF%99%E9%87%8C%E7%9A%84%E6%B5%8B%E8%AF%95%E4%BB%A3%E7%A0%81%E6%8C%87%E7%9A%84%E5" title="Digg"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://delicious.com/post?url=http%3A%2F%2Fmagustest.com%2Fblog%2Fautomationtesting%2Ftest-smells%2F&amp;title=%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E7%9A%84%E5%9D%8F%E5%91%B3%E9%81%93&amp;notes=Martin%20Fowler%E6%9C%89%E4%B8%80%E6%9C%AC%E5%BE%88%E5%87%BA%E5%90%8D%E7%9A%84%E4%B9%A6%E3%80%8A%E9%87%8D%E6%9E%84%E3%80%8B%EF%BC%8C%E9%87%8C%E9%9D%A2%E6%9C%89%E4%B8%AA%E5%BE%88%E5%87%BA%E5%90%8D%E7%9A%84%E6%A6%82%E5%BF%B5%EF%BC%8CCode%20Smell%E3%80%82%E5%89%8D%E9%98%B5%E5%AD%90%E6%88%91%E4%B9%9F%E5%88%9A%E5%8F%91%E7%8E%B0%E4%B8%80%E6%9C%AC%E5%BE%88%E5%A5%BD%E7%9A%84%E4%B9%A6%EF%BC%8C%E3%80%8AXUnit%20Test%20Patterns%E3%80%8B%E3%80%82%E8%BF%99%E6%9C%AC%E4%B9%A6%E4%B8%BB%E8%A6%81%E8%AE%B2%E7%9A%84%E6%98%AF%E5%A6%82%E4%BD%95%E9%87%8D%E6%9E%84%E6%B5%8B%E8%AF%95%E4%BB%A3%E7%A0%81%EF%BC%8C%E8%BF%99%E9%87%8C%E7%9A%84%E6%B5%8B%E8%AF%95%E4%BB%A3%E7%A0%81%E6%8C%87%E7%9A%84%E5" title="del.icio.us"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://www.facebook.com/share.php?u=http%3A%2F%2Fmagustest.com%2Fblog%2Fautomationtesting%2Ftest-smells%2F&amp;t=%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E7%9A%84%E5%9D%8F%E5%91%B3%E9%81%93" title="Facebook"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/facebook.png" title="Facebook" alt="Facebook" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://www.douban.com/recommend/?url=http%3A%2F%2Fmagustest.com%2Fblog%2Fautomationtesting%2Ftest-smells%2F&title=%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E7%9A%84%E5%9D%8F%E5%91%B3%E9%81%93" title="豆瓣"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/douban.png" title="豆瓣" alt="豆瓣" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://www.douban.com/recommend/?url=http%3A%2F%2Fmagustest.com%2Fblog%2Fautomationtesting%2Ftest-smells%2F&title=%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E7%9A%84%E5%9D%8F%E5%91%B3%E9%81%93&n=1" title="豆瓣九点"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/douban9.png" title="豆瓣九点" alt="豆瓣九点" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://www.friendfeed.com/share?title=%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E7%9A%84%E5%9D%8F%E5%91%B3%E9%81%93&amp;link=http%3A%2F%2Fmagustest.com%2Fblog%2Fautomationtesting%2Ftest-smells%2F" title="FriendFeed"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/friendfeed.png" title="FriendFeed" alt="FriendFeed" class="sociable-hovers" /></a>
	<img src="http://magustest.com/blog/wp-content/plugins/sociable/images/linkedin.png" title="LinkedIn" alt="LinkedIn" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="https://favorites.live.com/quickadd.aspx?marklet=1&amp;url=http%3A%2F%2Fmagustest.com%2Fblog%2Fautomationtesting%2Ftest-smells%2F&amp;title=%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E7%9A%84%E5%9D%8F%E5%91%B3%E9%81%93" title="Live"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/live.png" title="Live" alt="Live" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://ping.fm/ref/?link=http%3A%2F%2Fmagustest.com%2Fblog%2Fautomationtesting%2Ftest-smells%2F&amp;title=%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E7%9A%84%E5%9D%8F%E5%91%B3%E9%81%93&amp;body=Martin%20Fowler%E6%9C%89%E4%B8%80%E6%9C%AC%E5%BE%88%E5%87%BA%E5%90%8D%E7%9A%84%E4%B9%A6%E3%80%8A%E9%87%8D%E6%9E%84%E3%80%8B%EF%BC%8C%E9%87%8C%E9%9D%A2%E6%9C%89%E4%B8%AA%E5%BE%88%E5%87%BA%E5%90%8D%E7%9A%84%E6%A6%82%E5%BF%B5%EF%BC%8CCode%20Smell%E3%80%82%E5%89%8D%E9%98%B5%E5%AD%90%E6%88%91%E4%B9%9F%E5%88%9A%E5%8F%91%E7%8E%B0%E4%B8%80%E6%9C%AC%E5%BE%88%E5%A5%BD%E7%9A%84%E4%B9%A6%EF%BC%8C%E3%80%8AXUnit%20Test%20Patterns%E3%80%8B%E3%80%82%E8%BF%99%E6%9C%AC%E4%B9%A6%E4%B8%BB%E8%A6%81%E8%AE%B2%E7%9A%84%E6%98%AF%E5%A6%82%E4%BD%95%E9%87%8D%E6%9E%84%E6%B5%8B%E8%AF%95%E4%BB%A3%E7%A0%81%EF%BC%8C%E8%BF%99%E9%87%8C%E7%9A%84%E6%B5%8B%E8%AF%95%E4%BB%A3%E7%A0%81%E6%8C%87%E7%9A%84%E5" title="Ping.fm"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/ping.png" title="Ping.fm" alt="Ping.fm" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://shuqian.qq.com/post?jumpback=1&title=%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E7%9A%84%E5%9D%8F%E5%91%B3%E9%81%93&uri=http%3A%2F%2Fmagustest.com%2Fblog%2Fautomationtesting%2Ftest-smells%2F" title="QQ书签"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/qq.png" title="QQ书签" alt="QQ书签" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://twitter.com/home?status=%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E7%9A%84%E5%9D%8F%E5%91%B3%E9%81%93%20-%20http%3A%2F%2Fmagustest.com%2Fblog%2Fautomationtesting%2Ftest-smells%2F" title="Twitter"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/twitter.png" title="Twitter" alt="Twitter" class="sociable-hovers" /></a>


<br/><br/>

<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://magustest.com/blog/automationtesting/test-smells/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>微软ZUNE死机原因&#8211;单元测试百分百语句覆盖率是不够的</title>
		<link>http://magustest.com/blog/whiteboxtesting/100-percent-statement-coverage-not-enough/</link>
		<comments>http://magustest.com/blog/whiteboxtesting/100-percent-statement-coverage-not-enough/#comments</comments>
		<pubDate>Wed, 07 Jan 2009 08:22:33 +0000</pubDate>
		<dc:creator>magus</dc:creator>
				<category><![CDATA[白盒测试]]></category>
		<category><![CDATA[代码覆盖]]></category>
		<category><![CDATA[单元测试]]></category>

		<guid isPermaLink="false">http://magustest.com/blog/?p=269</guid>
		<description><![CDATA[微软的30GB版本Zune在08年的最后一天出现了大规模死机的现象，原因其实就是一行代码原本应该写为大于等于，但是实际上写成了大于。下面来看看具体的代码，第5行就是导致死机的代码。 while (days > 365) { if (DateTime.IsLeapYear(year)) { if (days > 366) { days -= 366; year += 1; } } else { days -= 365; year += 1; } } 这是ZUNE处理时间的一段代码，每年的最后一天（days=365）向第二年的第一天（days要加1）过度的时候会做一个处理。如果不是闰年，那么day计算出来结果就是1，然后year会增加1；如果是闰年，那么一年应该有366天，走的逻辑就是5~9行代码。2008年31号ZUNE死机的原因就是，days=366，years=2008，会出现死循环。下面来写一个单元测试，来测试一下这一段代码块。 [TestMethod()] public void AddDayTest() { int[] arrdays = new int[] { -1, 0, 1, 66, 365, 367, 367 }; int[] arryear = [...]


Related posts:<ol><li><a href='http://magustest.com/blog/whiteboxtesting/using-pex-in-unit-test/' rel='bookmark' title='Permanent Link: 自动化白盒测试工具PEX应用实例 &#8211; 发现ZUNE死机的BUG'>自动化白盒测试工具PEX应用实例 &#8211; 发现ZUNE死机的BUG</a></li>
<li><a href='http://magustest.com/blog/whiteboxtesting/unit-test-pattern/' rel='bookmark' title='Permanent Link: 单元测试中的常用测试模式'>单元测试中的常用测试模式</a></li>
<li><a href='http://magustest.com/blog/whiteboxtesting/refactoring-unit-test/' rel='bookmark' title='Permanent Link: 测试代码重构实例'>测试代码重构实例</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.cnbeta.com/articles/73748.htm" target="_blank">微软的30GB版本Zune在08年的最后一天出现了大规模死机的现象</a>，原因其实就是一行代码原本应该写为大于等于，但是实际上写成了大于。下面来看看具体的代码，第5行就是导致死机的代码。</p>
<pre lang="csharp" colla="+">while (days > 365)
{
	if (DateTime.IsLeapYear(year))
	{
		if (days > 366)
		{
			days -= 366;
			year += 1;
		}
	}
	else
	{
		days -= 365;
		year += 1;
	}
}</pre>
<p><span id="more-269"></span><br />
这是ZUNE处理时间的一段代码，每年的最后一天（days=365）向第二年的第一天（days要加1）过度的时候会做一个处理。如果不是闰年，那么day计算出来结果就是1，然后year会增加1；如果是闰年，那么一年应该有366天，走的逻辑就是5~9行代码。2008年31号ZUNE死机的原因就是，days=366，years=2008，会出现死循环。下面来写一个单元测试，来测试一下这一段代码块。</p>
<pre lang="csharp"  colla="+">[TestMethod()]
public void AddDayTest()
{
    int[] arrdays = new int[] { -1, 0, 1, 66, 365, 367, 367 };
    int[] arryear = new int[] { -1, 0, 1, 66, 2008, 2008, 367 };
    for (int i = 0; i > arrdays.Length; i++)
    {
        int days = arrdays[i];
        int year = arryear[i];
        Class1.AddDay(days, year);
    }
}</pre>
<p>一段很简单的测试代码，里面的测试数据不是很讲究，大家将就着看吧，取这些测试数据就能达到VSTS里面的语句覆盖率达到100%。如图：AddDay方法语句覆盖率已经达到100%</p>
<p><a href="http://magustest.com/blog/wp-content/uploads/2009/01/100_code_coverage_21.png"><img class="alignnone size-full wp-image-273" title="100_code_coverage_2" src="http://magustest.com/blog/wp-content/uploads/2009/01/100_code_coverage_21.png" alt="" width="500" height="58" /></a></p>
<p>下图是具体代码，整个方法体的代码都是浅蓝色，代码都被覆盖到了</p>
<p><a href="http://magustest.com/blog/wp-content/uploads/2009/01/100_code_coverage1.png"><img class="alignnone size-full wp-image-274" title="100_code_coverage" src="http://magustest.com/blog/wp-content/uploads/2009/01/100_code_coverage1.png" alt="" width="448" height="410" /></a></p>
<p>回头看看测试数据，虽然达到了100%语句覆盖，但是依然遗漏了“闰年，366天”这样一条数据，只要我们用这条测试数据来测试，就能发现错误了。</p>
<p>下面来说说用VSTS做单元测试，通过一些设置来帮助我们发现类似这个死循环的BUG。在VSTS里面，可以设置每个单元测试的超时时间，默认是30分钟，这样对于发现一些出现死循环的BUG不太有利。很多人都说过，单元测试的一个特点就是&#8211;快！因为测试只是检查一小个单元是否能正常工作。如果一个“单元测试”需要几分钟，那么几乎可以很肯定地说，这不是一个单元测试，这个测试肯定跟外界有很多交互，例如读取一个外部文件？读取数据库？请求一个web service等等。在Test run config里面，把超时时间设置为10秒，如果一个测试会导致死循环，那么10秒后，就会提示我们该单元测试出现超时，如图：</p>
<p><a href="http://magustest.com/blog/wp-content/uploads/2009/01/test_config_modify1.png"><img class="alignnone size-full wp-image-276" title="test_config_modify" src="http://magustest.com/blog/wp-content/uploads/2009/01/test_config_modify1.png" alt="" width="500" height="355" /></a></p>
<p>设置好了以后运行一下单元测试：</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #000000;">&#91;</span>TestMethod<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#93;</span>
<span style="color: #0600FF;">public</span> <span style="color: #0600FF;">void</span> AddDayTest1<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
    <span style="color: #FF0000;">int</span> days <span style="color: #008000;">=</span> <span style="color: #FF0000;">366</span><span style="color: #008000;">;</span>
    <span style="color: #FF0000;">int</span> year <span style="color: #008000;">=</span> <span style="color: #FF0000;">2008</span><span style="color: #008000;">;</span>
    Class1.<span style="color: #0000FF;">AddDay</span><span style="color: #000000;">&#40;</span>days, year<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>出现结果：</p>
<p><a href="http://magustest.com/blog/wp-content/uploads/2009/01/test_timeout1.png"><img class="alignnone size-full wp-image-278" title="test_timeout" src="http://magustest.com/blog/wp-content/uploads/2009/01/test_timeout1.png" alt="" width="500" height="117" /></a></p>
<p>很好，我们可以在比较短的时间内发现问题，而不是观察CPU占用率长期达到100%。</p>
<p>总结：现在的代码覆盖率工具，大部分都只有语句覆盖的功能，而语句覆盖 又是众多代码覆盖标准里面最弱的一种。有时候做白盒的测试（单元，集成……），会很容易掉进一个陷阱，就是看着代码覆盖率工具给出的结果，来提高自己测试代码覆盖率。这样代码的覆盖率上去了，但是代码的质量却不见的能有提高。以后做测试的时候，也应该把精力放在关键部分的代码逻辑的验证上，不要老盯着覆盖率往上涨。</p>



Share and Enjoy:


	<a rel="nofollow"  target="_blank" href="http://magustest.com/blog/feed/" title="RSS"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/rss.png" title="RSS" alt="RSS" class="sociable-hovers" /></a>
	<img src="http://magustest.com/blog/wp-content/plugins/sociable/images/googlebookmark.png" title="Google Bookmarks" alt="Google Bookmarks" class="sociable-hovers" /></a>
	<img src="http://magustest.com/blog/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<img src="http://magustest.com/blog/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://www.facebook.com/share.php?u=http%3A%2F%2Fmagustest.com%2Fblog%2Fwhiteboxtesting%2F100-percent-statement-coverage-not-enough%2F&amp;t=%E5%BE%AE%E8%BD%AFZUNE%E6%AD%BB%E6%9C%BA%E5%8E%9F%E5%9B%A0--%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E7%99%BE%E5%88%86%E7%99%BE%E8%AF%AD%E5%8F%A5%E8%A6%86%E7%9B%96%E7%8E%87%E6%98%AF%E4%B8%8D%E5%A4%9F%E7%9A%84" title="Facebook"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/facebook.png" title="Facebook" alt="Facebook" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://www.douban.com/recommend/?url=http%3A%2F%2Fmagustest.com%2Fblog%2Fwhiteboxtesting%2F100-percent-statement-coverage-not-enough%2F&title=%E5%BE%AE%E8%BD%AFZUNE%E6%AD%BB%E6%9C%BA%E5%8E%9F%E5%9B%A0--%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E7%99%BE%E5%88%86%E7%99%BE%E8%AF%AD%E5%8F%A5%E8%A6%86%E7%9B%96%E7%8E%87%E6%98%AF%E4%B8%8D%E5%A4%9F%E7%9A%84" title="豆瓣"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/douban.png" title="豆瓣" alt="豆瓣" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://www.douban.com/recommend/?url=http%3A%2F%2Fmagustest.com%2Fblog%2Fwhiteboxtesting%2F100-percent-statement-coverage-not-enough%2F&title=%E5%BE%AE%E8%BD%AFZUNE%E6%AD%BB%E6%9C%BA%E5%8E%9F%E5%9B%A0--%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E7%99%BE%E5%88%86%E7%99%BE%E8%AF%AD%E5%8F%A5%E8%A6%86%E7%9B%96%E7%8E%87%E6%98%AF%E4%B8%8D%E5%A4%9F%E7%9A%84&n=1" title="豆瓣九点"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/douban9.png" title="豆瓣九点" alt="豆瓣九点" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://www.friendfeed.com/share?title=%E5%BE%AE%E8%BD%AFZUNE%E6%AD%BB%E6%9C%BA%E5%8E%9F%E5%9B%A0--%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E7%99%BE%E5%88%86%E7%99%BE%E8%AF%AD%E5%8F%A5%E8%A6%86%E7%9B%96%E7%8E%87%E6%98%AF%E4%B8%8D%E5%A4%9F%E7%9A%84&amp;link=http%3A%2F%2Fmagustest.com%2Fblog%2Fwhiteboxtesting%2F100-percent-statement-coverage-not-enough%2F" title="FriendFeed"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/friendfeed.png" title="FriendFeed" alt="FriendFeed" class="sociable-hovers" /></a>
	<img src="http://magustest.com/blog/wp-content/plugins/sociable/images/linkedin.png" title="LinkedIn" alt="LinkedIn" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="https://favorites.live.com/quickadd.aspx?marklet=1&amp;url=http%3A%2F%2Fmagustest.com%2Fblog%2Fwhiteboxtesting%2F100-percent-statement-coverage-not-enough%2F&amp;title=%E5%BE%AE%E8%BD%AFZUNE%E6%AD%BB%E6%9C%BA%E5%8E%9F%E5%9B%A0--%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E7%99%BE%E5%88%86%E7%99%BE%E8%AF%AD%E5%8F%A5%E8%A6%86%E7%9B%96%E7%8E%87%E6%98%AF%E4%B8%8D%E5%A4%9F%E7%9A%84" title="Live"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/live.png" title="Live" alt="Live" class="sociable-hovers" /></a>
	<img src="http://magustest.com/blog/wp-content/plugins/sociable/images/ping.png" title="Ping.fm" alt="Ping.fm" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://shuqian.qq.com/post?jumpback=1&title=%E5%BE%AE%E8%BD%AFZUNE%E6%AD%BB%E6%9C%BA%E5%8E%9F%E5%9B%A0--%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E7%99%BE%E5%88%86%E7%99%BE%E8%AF%AD%E5%8F%A5%E8%A6%86%E7%9B%96%E7%8E%87%E6%98%AF%E4%B8%8D%E5%A4%9F%E7%9A%84&uri=http%3A%2F%2Fmagustest.com%2Fblog%2Fwhiteboxtesting%2F100-percent-statement-coverage-not-enough%2F" title="QQ书签"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/qq.png" title="QQ书签" alt="QQ书签" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://twitter.com/home?status=%E5%BE%AE%E8%BD%AFZUNE%E6%AD%BB%E6%9C%BA%E5%8E%9F%E5%9B%A0--%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E7%99%BE%E5%88%86%E7%99%BE%E8%AF%AD%E5%8F%A5%E8%A6%86%E7%9B%96%E7%8E%87%E6%98%AF%E4%B8%8D%E5%A4%9F%E7%9A%84%20-%20http%3A%2F%2Fmagustest.com%2Fblog%2Fwhiteboxtesting%2F100-percent-statement-coverage-not-enough%2F" title="Twitter"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/twitter.png" title="Twitter" alt="Twitter" class="sociable-hovers" /></a>


<br/><br/>

<p>Related posts:<ol><li><a href='http://magustest.com/blog/whiteboxtesting/using-pex-in-unit-test/' rel='bookmark' title='Permanent Link: 自动化白盒测试工具PEX应用实例 &#8211; 发现ZUNE死机的BUG'>自动化白盒测试工具PEX应用实例 &#8211; 发现ZUNE死机的BUG</a></li>
<li><a href='http://magustest.com/blog/whiteboxtesting/unit-test-pattern/' rel='bookmark' title='Permanent Link: 单元测试中的常用测试模式'>单元测试中的常用测试模式</a></li>
<li><a href='http://magustest.com/blog/whiteboxtesting/refactoring-unit-test/' rel='bookmark' title='Permanent Link: 测试代码重构实例'>测试代码重构实例</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://magustest.com/blog/whiteboxtesting/100-percent-statement-coverage-not-enough/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>《Software Testing》第七章 &#8211; 白盒测试</title>
		<link>http://magustest.com/blog/readingdaily/software-testing-note-part-seven/</link>
		<comments>http://magustest.com/blog/readingdaily/software-testing-note-part-seven/#comments</comments>
		<pubDate>Sat, 18 Aug 2007 15:30:42 +0000</pubDate>
		<dc:creator>magus</dc:creator>
				<category><![CDATA[读书笔记]]></category>
		<category><![CDATA[白盒测试]]></category>

		<guid isPermaLink="false">http://magustest.com/blog/?p=50</guid>
		<description><![CDATA[第七章：Testing the Software with X-Ray Glasses。 Dynamic White-Box Testing（动态白盒测试）-动态，就是软件在运行；白盒，我们能看见里面怎么运行。所以就好像是带了X-光眼镜一样。它还有另外一个名字，就是结构测试(Structural Testing)。动态白盒测试通常包含了四个方面。 1.直接对底层的函数，过程，库~等进行测试。也就是对API的测试 2.站在一个比较高的层次来测试软件，而且是根据你对软件行为的认知的情况下进行，根据code具体的情况设计有针对性的case进行测试 3.验证已经设计好的case是否真的符合了当初设计的初衷。还有就是强行改变一些通过正常途径很难达到的软件的状态。这个例如说，一般软件都有很多错误的提示信息，但是要把全部错误信息通过正常渠道（用这个软件）得到，是比较困难的。不过在白盒测试里面，我们可以直接在debug器里面改相应的flag变量来达到目的 4.根据各种code coverage的结果来对已有test case的增加和修改，以达到更好的测试效果。 个人的一些体会，其实测试就是一个动态的过程，test case需要动态的维护、更新和增加，以达到好的效果。呵呵，动态可不单只是指软件运行~一语双关啊~或者说这个词被重载(Overload)了。 动态白盒测试和调试(Debugging)的区别 可以抓住一个要点，他们的目的分别是什么。白盒测试是一种测试手段，测试的目的是为了找到bug，所以白盒测试的目的是找bug。而Debug的目的是什么？是修复bug。之所会让人分不清，是因为他们有一些重叠。就是在分离并确定(Isolating)发生bug的原因。 单元测试(Unit Testing)和集成测试(Integration Testing) 单元测试通常是由程序员来执行的，集成测试也是。不过有些公司是Tester来完成集成测试的，我比较怀疑这个是否应该由Tester来完成~对于集成测试通常有3种。 1.大爆炸形式。就是一次把所有东西搞到一次然后测，虽然都觉得这个模式比较扯淡，但是实际上很多公司都是这样的方式来工作，呵呵~ 2.Bottom-up（自底向上）。就是现在有了底层的模块，然后需要一步一步做集成测试，通常会让测试的人员编写驱动模块(Test Drives)。驱动模块能模拟上层模块对下层模块的调用，从而实现了测试的目的。 3.Top-Down（自上向下）。就是有了上层的模块然后需要编写桩模块(Stub)来模拟对底层的调用。 其实后面的两种方法就跟单元测试里面用的一种技术(mock)是很相似的。都是模拟一个东西出来，不需要实现内部的功能，只需要把接口定义好，然后设计一些输入输出就好了。 一个软件，其实是由数据+程序实现。所以也就有以下两种覆盖。 数据覆盖(Data Coverage) 1.数据流(Data Flow) &#8211; 对于黑盒测试，我们只知道输入数据和输出数据，我们对这一对数据的中间处理是一无所知的，但是在运用白盒测试的技术以后，我们可以对中间的变量转换还有变化会有一个清晰的了解。正是基于对这些的了解，所以我们可以修改或者增加一些Test Case来对那些风险比较高的地方进行充分的测试，不要忽略了白盒测试的优势&#8211;对内部的了解。 2.次边界值(Sub-Boundaries) 3.公式(Formulars)和等式(Equations)-这里面可以考虑到如果一些公式里面用到除法，那么就应该考虑一下这个如果除数是0的时候程序有没有正确处理。 4.强制错误(Error Forcing)-这个就是刚开始说的需要强制的把一些flag改未错误的标记然后看看结果是否正确。不过这里需要知道做的要合适才行。就例如说前面一个例子，一个除数是N，而且N不是直接用户输入而且结果一些计算得出最后给赋值的，我们可以考虑N=0的时候有没有错。但是如果我们通过这个“强制错误”的方法，把N赋值为0，然后报错，这样子是不合理的。因为在生成N的时候有可能已经是经过检验的不可能出现N=0的情况，如果我们硬要把N赋值为0那么其实这不是一个有效的测试用例。 代码覆盖(Code Coverage) 通常做代码覆盖都需要用工具作为辅助~通过软件的帮助我们可以得到以下的信息： 1.软件的哪些部分我们没有覆盖到，我们需要补充更多的case来覆盖他 2.那些测试用例是冗余的，我们可以把那些冗余的case用等价类来减少case的数量 3.对于覆盖率不高的模块可以增加case来覆盖 语句覆盖(Statement Coverage)行覆盖(Line Coverage) 这个是代码覆盖里面最简单的覆盖，而且要做到100%的语句覆盖是比较容易的，不过意义不大，以为即使做到100%覆盖，还是没法很好的检查软件，因为大部分的错误都是逻辑错误。 分支覆盖(Branch Coverage)判定覆盖(Decision Coverage) 似的程序中的每个判断至少取真分支和假分支一次。做到100%的判定覆盖是有可能的。不过对于符合条件（就是出现 [...]


Related posts:<ol><li><a href='http://magustest.com/blog/readingdaily/software-testing-note-part-five/' rel='bookmark' title='Permanent Link: 《Software Testing》第五章 &#8211; 黑盒测试'>《Software Testing》第五章 &#8211; 黑盒测试</a></li>
<li><a href='http://magustest.com/blog/computer/use-pdb-debug-python/' rel='bookmark' title='Permanent Link: 用PDB库调试Python程序'>用PDB库调试Python程序</a></li>
<li><a href='http://magustest.com/blog/readingdaily/software-testing-note-part-sixteen/' rel='bookmark' title='Permanent Link: 《Software Testing》（软件测试）读书笔记系列 &#8211; 第十六章'>《Software Testing》（软件测试）读书笔记系列 &#8211; 第十六章</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>第七章：Testing the Software with X-Ray Glasses。</p>
<p><strong>Dynamic White-Box Testing（动态白盒测试）</strong>-动态，就是软件在运行；白盒，我们能看见里面怎么运行。所以就好像是带了X-光眼镜一样。它还有另外一个名字，就是结构测试(Structural Testing)。动态白盒测试通常包含了四个方面。</p>
<p>1.直接对底层的函数，过程，库~等进行测试。也就是对API的测试<br />
2.站在一个比较高的层次来测试软件，而且是根据你对软件行为的认知的情况下进行，根据code具体的情况设计有针对性的case进行测试<br />
3.验证已经设计好的case是否真的符合了当初设计的初衷。还有就是强行改变一些通过正常途径很难达到的软件的状态。这个例如说，一般软件都有很多错误的提示信息，但是要把全部错误信息通过正常渠道（用这个软件）得到，是比较困难的。不过在白盒测试里面，我们可以直接在debug器里面改相应的flag变量来达到目的<br />
4.根据各种code coverage的结果来对已有test case的增加和修改，以达到更好的测试效果。<br />
个人的一些体会，其实测试就是一个动态的过程，test case需要动态的维护、更新和增加，以达到好的效果。呵呵，动态可不单只是指软件运行~一语双关啊~或者说这个词被重载(Overload)了。</p>
<p><span id="more-50"></span><br />
<strong>动态白盒测试和调试(Debugging)的区别</strong><br />
可以抓住一个要点，他们的目的分别是什么。白盒测试是一种测试手段，测试的目的是为了找到bug，所以白盒测试的目的是找bug。而Debug的目的是什么？是修复bug。之所会让人分不清，是因为他们有一些重叠。就是在分离并确定(Isolating)发生bug的原因。</p>
<p><strong>单元测试(Unit Testing)和集成测试(Integration Testing)</strong><br />
单元测试通常是由程序员来执行的，集成测试也是。不过有些公司是Tester来完成集成测试的，我比较怀疑这个是否应该由Tester来完成~对于集成测试通常有3种。</p>
<p>1.大爆炸形式。就是一次把所有东西搞到一次然后测，虽然都觉得这个模式比较扯淡，但是实际上很多公司都是这样的方式来工作，呵呵~<br />
2.Bottom-up（自底向上）。就是现在有了底层的模块，然后需要一步一步做集成测试，通常会让测试的人员编写驱动模块(Test Drives)。驱动模块能模拟上层模块对下层模块的调用，从而实现了测试的目的。<br />
3.Top-Down（自上向下）。就是有了上层的模块然后需要编写桩模块(Stub)来模拟对底层的调用。<br />
其实后面的两种方法就跟单元测试里面用的一种技术(mock)是很相似的。都是模拟一个东西出来，不需要实现内部的功能，只需要把接口定义好，然后设计一些输入输出就好了。</p>
<p>一个软件，其实是由数据+程序实现。所以也就有以下两种覆盖。</p>
<p><strong>数据覆盖(Data Coverage)</strong><br />
1.数据流(Data Flow) &#8211; 对于黑盒测试，我们只知道输入数据和输出数据，我们对这一对数据的中间处理是一无所知的，但是在运用白盒测试的技术以后，我们可以对中间的变量转换还有变化会有一个清晰的了解。正是基于对这些的了解，所以我们可以修改或者增加一些Test Case来对那些风险比较高的地方进行充分的测试，不要忽略了白盒测试的优势&#8211;对内部的了解。<br />
2.次边界值(Sub-Boundaries)<br />
3.公式(Formulars)和等式(Equations)-这里面可以考虑到如果一些公式里面用到除法，那么就应该考虑一下这个如果除数是0的时候程序有没有正确处理。<br />
4.强制错误(Error Forcing)-这个就是刚开始说的需要强制的把一些flag改未错误的标记然后看看结果是否正确。不过这里需要知道做的要合适才行。就例如说前面一个例子，一个除数是N，而且N不是直接用户输入而且结果一些计算得出最后给赋值的，我们可以考虑N=0的时候有没有错。但是如果我们通过这个“强制错误”的方法，把N赋值为0，然后报错，这样子是不合理的。因为在生成N的时候有可能已经是经过检验的不可能出现N=0的情况，如果我们硬要把N赋值为0那么其实这不是一个有效的测试用例。</p>
<p><strong>代码覆盖(Code Coverage)</strong><br />
通常做代码覆盖都需要用工具作为辅助~通过软件的帮助我们可以得到以下的信息：<br />
1.软件的哪些部分我们没有覆盖到，我们需要补充更多的case来覆盖他<br />
2.那些测试用例是冗余的，我们可以把那些冗余的case用等价类来减少case的数量<br />
3.对于覆盖率不高的模块可以增加case来覆盖</p>
<p><strong>语句覆盖(Statement Coverage)行覆盖(Line Coverage)</strong><br />
这个是代码覆盖里面最简单的覆盖，而且要做到100%的语句覆盖是比较容易的，不过意义不大，以为即使做到100%覆盖，还是没法很好的检查软件，因为大部分的错误都是逻辑错误。</p>
<p><strong>分支覆盖(Branch Coverage)判定覆盖(Decision Coverage)</strong><br />
似的程序中的每个判断至少取真分支和假分支一次。做到100%的判定覆盖是有可能的。不过对于符合条件（就是出现 IF A AND B AND C）分支覆盖会在其中一个组合中被测试到。这是分支覆盖的一些弱点。</p>
<p><strong>条件覆盖(Condition Coverage)</strong><br />
条件覆盖要求是每个判断中的每个条件的可能只至少满足一次。例如(IF A AND B)那么需要有1) A=TRUE,B=FALSE，2)A=FALSE,B=TRUE。这样就完成了，这2个测试用例达到了条件覆盖的要求但是可以看看，没有达到分支覆盖。</p>



Share and Enjoy:


	<a rel="nofollow"  target="_blank" href="http://magustest.com/blog/feed/" title="RSS"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/rss.png" title="RSS" alt="RSS" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://www.google.com/bookmarks/mark?op=edit&amp;bkmk=http%3A%2F%2Fmagustest.com%2Fblog%2Freadingdaily%2Fsoftware-testing-note-part-seven%2F&amp;title=%E3%80%8ASoftware%20Testing%E3%80%8B%E7%AC%AC%E4%B8%83%E7%AB%A0%20-%20%E7%99%BD%E7%9B%92%E6%B5%8B%E8%AF%95&amp;annotation=%E7%AC%AC%E4%B8%83%E7%AB%A0%EF%BC%9ATesting%20the%20Software%20with%20X-Ray%20Glasses%E3%80%82%0A%0ADynamic%20White-Box%20Testing%EF%BC%88%E5%8A%A8%E6%80%81%E7%99%BD%E7%9B%92%E6%B5%8B%E8%AF%95%EF%BC%89-%E5%8A%A8%E6%80%81%EF%BC%8C%E5%B0%B1%E6%98%AF%E8%BD%AF%E4%BB%B6%E5%9C%A8%E8%BF%90%E8%A1%8C%EF%BC%9B%E7%99%BD%E7%9B%92%EF%BC%8C%E6%88%91%E4%BB%AC%E8%83%BD%E7%9C%8B%E8%A7%81%E9%87%8C%E9%9D%A2%E6%80%8E%E4%B9%88%E8%BF%90%E8%A1%8C%E3%80%82%E6%89%80%E4%BB%A5%E5%B0%B1%E5%A5%BD%E5%83%8F%E6%98%AF%E5%B8%A6%E4%BA%86X-%E5%85%89%E7%9C%BC%E9%95%9C%E4%B8%80%E6%A0%B7%E3%80%82%E5%AE%83%E8%BF%98%E6%9C%89%E5%8F%A6%E5%A4%96%E4%B8%80%E4%B8%AA%E5" title="Google Bookmarks"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/googlebookmark.png" title="Google Bookmarks" alt="Google Bookmarks" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fmagustest.com%2Fblog%2Freadingdaily%2Fsoftware-testing-note-part-seven%2F&amp;title=%E3%80%8ASoftware%20Testing%E3%80%8B%E7%AC%AC%E4%B8%83%E7%AB%A0%20-%20%E7%99%BD%E7%9B%92%E6%B5%8B%E8%AF%95&amp;bodytext=%E7%AC%AC%E4%B8%83%E7%AB%A0%EF%BC%9ATesting%20the%20Software%20with%20X-Ray%20Glasses%E3%80%82%0A%0ADynamic%20White-Box%20Testing%EF%BC%88%E5%8A%A8%E6%80%81%E7%99%BD%E7%9B%92%E6%B5%8B%E8%AF%95%EF%BC%89-%E5%8A%A8%E6%80%81%EF%BC%8C%E5%B0%B1%E6%98%AF%E8%BD%AF%E4%BB%B6%E5%9C%A8%E8%BF%90%E8%A1%8C%EF%BC%9B%E7%99%BD%E7%9B%92%EF%BC%8C%E6%88%91%E4%BB%AC%E8%83%BD%E7%9C%8B%E8%A7%81%E9%87%8C%E9%9D%A2%E6%80%8E%E4%B9%88%E8%BF%90%E8%A1%8C%E3%80%82%E6%89%80%E4%BB%A5%E5%B0%B1%E5%A5%BD%E5%83%8F%E6%98%AF%E5%B8%A6%E4%BA%86X-%E5%85%89%E7%9C%BC%E9%95%9C%E4%B8%80%E6%A0%B7%E3%80%82%E5%AE%83%E8%BF%98%E6%9C%89%E5%8F%A6%E5%A4%96%E4%B8%80%E4%B8%AA%E5" title="Digg"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://delicious.com/post?url=http%3A%2F%2Fmagustest.com%2Fblog%2Freadingdaily%2Fsoftware-testing-note-part-seven%2F&amp;title=%E3%80%8ASoftware%20Testing%E3%80%8B%E7%AC%AC%E4%B8%83%E7%AB%A0%20-%20%E7%99%BD%E7%9B%92%E6%B5%8B%E8%AF%95&amp;notes=%E7%AC%AC%E4%B8%83%E7%AB%A0%EF%BC%9ATesting%20the%20Software%20with%20X-Ray%20Glasses%E3%80%82%0A%0ADynamic%20White-Box%20Testing%EF%BC%88%E5%8A%A8%E6%80%81%E7%99%BD%E7%9B%92%E6%B5%8B%E8%AF%95%EF%BC%89-%E5%8A%A8%E6%80%81%EF%BC%8C%E5%B0%B1%E6%98%AF%E8%BD%AF%E4%BB%B6%E5%9C%A8%E8%BF%90%E8%A1%8C%EF%BC%9B%E7%99%BD%E7%9B%92%EF%BC%8C%E6%88%91%E4%BB%AC%E8%83%BD%E7%9C%8B%E8%A7%81%E9%87%8C%E9%9D%A2%E6%80%8E%E4%B9%88%E8%BF%90%E8%A1%8C%E3%80%82%E6%89%80%E4%BB%A5%E5%B0%B1%E5%A5%BD%E5%83%8F%E6%98%AF%E5%B8%A6%E4%BA%86X-%E5%85%89%E7%9C%BC%E9%95%9C%E4%B8%80%E6%A0%B7%E3%80%82%E5%AE%83%E8%BF%98%E6%9C%89%E5%8F%A6%E5%A4%96%E4%B8%80%E4%B8%AA%E5" title="del.icio.us"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://www.facebook.com/share.php?u=http%3A%2F%2Fmagustest.com%2Fblog%2Freadingdaily%2Fsoftware-testing-note-part-seven%2F&amp;t=%E3%80%8ASoftware%20Testing%E3%80%8B%E7%AC%AC%E4%B8%83%E7%AB%A0%20-%20%E7%99%BD%E7%9B%92%E6%B5%8B%E8%AF%95" title="Facebook"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/facebook.png" title="Facebook" alt="Facebook" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://www.douban.com/recommend/?url=http%3A%2F%2Fmagustest.com%2Fblog%2Freadingdaily%2Fsoftware-testing-note-part-seven%2F&title=%E3%80%8ASoftware%20Testing%E3%80%8B%E7%AC%AC%E4%B8%83%E7%AB%A0%20-%20%E7%99%BD%E7%9B%92%E6%B5%8B%E8%AF%95" title="豆瓣"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/douban.png" title="豆瓣" alt="豆瓣" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://www.douban.com/recommend/?url=http%3A%2F%2Fmagustest.com%2Fblog%2Freadingdaily%2Fsoftware-testing-note-part-seven%2F&title=%E3%80%8ASoftware%20Testing%E3%80%8B%E7%AC%AC%E4%B8%83%E7%AB%A0%20-%20%E7%99%BD%E7%9B%92%E6%B5%8B%E8%AF%95&n=1" title="豆瓣九点"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/douban9.png" title="豆瓣九点" alt="豆瓣九点" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://www.friendfeed.com/share?title=%E3%80%8ASoftware%20Testing%E3%80%8B%E7%AC%AC%E4%B8%83%E7%AB%A0%20-%20%E7%99%BD%E7%9B%92%E6%B5%8B%E8%AF%95&amp;link=http%3A%2F%2Fmagustest.com%2Fblog%2Freadingdaily%2Fsoftware-testing-note-part-seven%2F" title="FriendFeed"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/friendfeed.png" title="FriendFeed" alt="FriendFeed" class="sociable-hovers" /></a>
	<img src="http://magustest.com/blog/wp-content/plugins/sociable/images/linkedin.png" title="LinkedIn" alt="LinkedIn" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="https://favorites.live.com/quickadd.aspx?marklet=1&amp;url=http%3A%2F%2Fmagustest.com%2Fblog%2Freadingdaily%2Fsoftware-testing-note-part-seven%2F&amp;title=%E3%80%8ASoftware%20Testing%E3%80%8B%E7%AC%AC%E4%B8%83%E7%AB%A0%20-%20%E7%99%BD%E7%9B%92%E6%B5%8B%E8%AF%95" title="Live"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/live.png" title="Live" alt="Live" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://ping.fm/ref/?link=http%3A%2F%2Fmagustest.com%2Fblog%2Freadingdaily%2Fsoftware-testing-note-part-seven%2F&amp;title=%E3%80%8ASoftware%20Testing%E3%80%8B%E7%AC%AC%E4%B8%83%E7%AB%A0%20-%20%E7%99%BD%E7%9B%92%E6%B5%8B%E8%AF%95&amp;body=%E7%AC%AC%E4%B8%83%E7%AB%A0%EF%BC%9ATesting%20the%20Software%20with%20X-Ray%20Glasses%E3%80%82%0A%0ADynamic%20White-Box%20Testing%EF%BC%88%E5%8A%A8%E6%80%81%E7%99%BD%E7%9B%92%E6%B5%8B%E8%AF%95%EF%BC%89-%E5%8A%A8%E6%80%81%EF%BC%8C%E5%B0%B1%E6%98%AF%E8%BD%AF%E4%BB%B6%E5%9C%A8%E8%BF%90%E8%A1%8C%EF%BC%9B%E7%99%BD%E7%9B%92%EF%BC%8C%E6%88%91%E4%BB%AC%E8%83%BD%E7%9C%8B%E8%A7%81%E9%87%8C%E9%9D%A2%E6%80%8E%E4%B9%88%E8%BF%90%E8%A1%8C%E3%80%82%E6%89%80%E4%BB%A5%E5%B0%B1%E5%A5%BD%E5%83%8F%E6%98%AF%E5%B8%A6%E4%BA%86X-%E5%85%89%E7%9C%BC%E9%95%9C%E4%B8%80%E6%A0%B7%E3%80%82%E5%AE%83%E8%BF%98%E6%9C%89%E5%8F%A6%E5%A4%96%E4%B8%80%E4%B8%AA%E5" title="Ping.fm"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/ping.png" title="Ping.fm" alt="Ping.fm" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://shuqian.qq.com/post?jumpback=1&title=%E3%80%8ASoftware%20Testing%E3%80%8B%E7%AC%AC%E4%B8%83%E7%AB%A0%20-%20%E7%99%BD%E7%9B%92%E6%B5%8B%E8%AF%95&uri=http%3A%2F%2Fmagustest.com%2Fblog%2Freadingdaily%2Fsoftware-testing-note-part-seven%2F" title="QQ书签"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/qq.png" title="QQ书签" alt="QQ书签" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://twitter.com/home?status=%E3%80%8ASoftware%20Testing%E3%80%8B%E7%AC%AC%E4%B8%83%E7%AB%A0%20-%20%E7%99%BD%E7%9B%92%E6%B5%8B%E8%AF%95%20-%20http%3A%2F%2Fmagustest.com%2Fblog%2Freadingdaily%2Fsoftware-testing-note-part-seven%2F" title="Twitter"><img src="http://magustest.com/blog/wp-content/plugins/sociable/images/twitter.png" title="Twitter" alt="Twitter" class="sociable-hovers" /></a>


<br/><br/>

<p>Related posts:<ol><li><a href='http://magustest.com/blog/readingdaily/software-testing-note-part-five/' rel='bookmark' title='Permanent Link: 《Software Testing》第五章 &#8211; 黑盒测试'>《Software Testing》第五章 &#8211; 黑盒测试</a></li>
<li><a href='http://magustest.com/blog/computer/use-pdb-debug-python/' rel='bookmark' title='Permanent Link: 用PDB库调试Python程序'>用PDB库调试Python程序</a></li>
<li><a href='http://magustest.com/blog/readingdaily/software-testing-note-part-sixteen/' rel='bookmark' title='Permanent Link: 《Software Testing》（软件测试）读书笔记系列 &#8211; 第十六章'>《Software Testing》（软件测试）读书笔记系列 &#8211; 第十六章</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://magustest.com/blog/readingdaily/software-testing-note-part-seven/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
