<?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/category/whiteboxtesting/feed/" rel="self" type="application/rss+xml" />
	<link>http://magustest.com/blog</link>
	<description>关注软件测试，白盒测试，自动化测试，性能测试</description>
	<lastBuildDate>Tue, 31 Aug 2010 16:19:36 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
<xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" />
		<item>
		<title>Linq to Object在测试中的应用</title>
		<link>http://magustest.com/blog/whiteboxtesting/using-linq-to-object-in-testing/</link>
		<comments>http://magustest.com/blog/whiteboxtesting/using-linq-to-object-in-testing/#comments</comments>
		<pubDate>Fri, 10 Jul 2009 03:34:50 +0000</pubDate>
		<dc:creator>magus</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[白盒测试]]></category>
		<category><![CDATA[LINQ]]></category>
		<category><![CDATA[集成测试]]></category>

		<guid isPermaLink="false">http://magustest.com/blog/?p=563</guid>
		<description><![CDATA[.NET Framework 3.5中引入了一个新特性LINQ（集成语言查询），据说.NET Framework 3.5中很多特性都是为LINQ而服务的，例如Lambda表达式的支持，匿名类型，等等……这篇文章会讲述一个把Linq to Object应用于测试的例子。 前一阵子需要测试一个搜索在线会员的功能，如果一个用户是在线的，那么他所能够被搜索到的信息都会作为一条记录，保存在一个表中，主要的字段有5个，也就是根据这5个字段的信息可以查询出用户想要的在线会员。一个简单的方案就是写一个比较复杂的存储过程，然后根据5个输入来查询出不同的结果，不过DBA说在SQL SERVER中进行逻辑运算的性能不是很好，所以开发人员写了12条存储过程，分别对应不同的组合，那么对于我做集成测试来说，我起码要有12个测试方法对应这12条存储过程。同时我还要设计一定数量的测试数据，供我查询测试，而比较要命的是，这些测试数据随着我对这个功能的理解的深入，在不断地增加，结果就是如果我写第一个测试的时候，我准备的数据是30条，OK，测试通过；等我写到第五个测试的时候，测试数据可能有40条了，当我用这40条测试数据重新指向第一个测试的时候，FAILED!!!这让人非常郁闷。所以我想到了能不能用round trip的方法来进行测试。做一个比喻，假如说我想证明WIN7的计算器程序是正确的，那么可以把相同的计算在WIN XP的计算器中跑一遍，如果两者结果一样，那么我可以认为WIN7的计算器程序也是正确的（如果XP的计算器有错怎么办？先别较真，有风险，但很小）。 我的做法就是，准备一些数据，首先用SUT进行查询，然后用LINQ进行查询，如果两者查询结果一致，那么可以认为程序是正确的，否则就是两者之一存在问题。 首先准备一些测试数据，保存为XML文件，第一方便对测试数据进行CRUD，第二可以用XmlSerializer把这些数据转换为对象，方便用LINQ查询。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 &#60; ?xml version=&#34;1.0&#34; encoding=&#34;utf-8&#34; ?&#62; &#60;onlinefriends&#62; &#60;friends&#62; &#60;onlinefrienddata&#62; &#60;friendid&#62;1300010000&#60;/friendid&#62; &#60;province&#62;北京市&#60;/province&#62; &#60;city&#62;北京市&#60;/city&#62; &#60;age&#62;18&#60;/age&#62; &#60;gender&#62;2&#60;/gender&#62; [...]


Related posts:<ol><li><a href='http://magustest.com/blog/net/automatic-generate-xml-instance-by-using-xsd/' rel='bookmark' title='Permanent Link: 用XSD自动生成XML对应的.NET实体类'>用XSD自动生成XML对应的.NET实体类</a></li>
<li><a href='http://magustest.com/blog/whiteboxtesting/data-driven-test-in-unit-test/' rel='bookmark' title='Permanent Link: 在单元测试中应用数据驱动'>在单元测试中应用数据驱动</a></li>
<li><a href='http://magustest.com/blog/softwaretesting/using-httpcontext-in-unittest/' rel='bookmark' title='Permanent Link: 在C#单元测试中使用HttpContext的简单解决办法'>在C#单元测试中使用HttpContext的简单解决办法</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>.NET Framework 3.5中引入了一个新特性<a href="http://msdn.microsoft.com/en-us/netframework/aa904594.aspx" target="_blank">LINQ</a>（集成语言查询），据说.NET Framework 3.5中很多特性都是为LINQ而服务的，例如<a href="http://en.wikipedia.org/wiki/Lambda" target="_blank">Lambda表达式</a>的支持，<a href="http://msdn.microsoft.com/zh-cn/library/bb397696.aspx" target="_blank">匿名类型</a>，等等……这篇文章会讲述一个把Linq to Object应用于测试的例子。</p>
<p>前一阵子需要测试一个搜索在线会员的功能，如果一个用户是在线的，那么他所能够被搜索到的信息都会作为一条记录，保存在一个表中，主要的字段有5个，也就是根据这5个字段的信息可以查询出用户想要的在线会员。一个简单的方案就是写一个比较复杂的存储过程，然后根据5个输入来查询出不同的结果，不过DBA说在SQL SERVER中进行逻辑运算的性能不是很好，所以开发人员写了12条存储过程，分别对应不同的组合，那么对于我做集成测试来说，我起码要有12个测试方法对应这12条存储过程。同时我还要设计一定数量的测试数据，供我查询测试，而比较要命的是，这些测试数据随着我对这个功能的理解的深入，在不断地增加，结果就是如果我写第一个测试的时候，我准备的数据是30条，OK，测试通过；等我写到第五个测试的时候，测试数据可能有40条了，当我用这40条测试数据重新指向第一个测试的时候，FAILED!!!这让人非常郁闷。所以我想到了能不能用round trip的方法来进行测试。做一个比喻，假如说我想证明WIN7的计算器程序是正确的，那么可以把相同的计算在WIN XP的计算器中跑一遍，如果两者结果一样，那么我可以认为WIN7的计算器程序也是正确的（如果XP的计算器有错怎么办？先别较真，有风险，但很小）。</p>
<p>我的做法就是，准备一些数据，首先用SUT进行查询，然后用LINQ进行查询，如果两者查询结果一致，那么可以认为程序是正确的，否则就是两者之一存在问题。</p>
<p>首先准备一些测试数据，保存为XML文件，第一方便对测试数据进行CRUD，第二可以用XmlSerializer把这些数据转换为对象，方便用LINQ查询。<br />
<span id="more-563"></span></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
</pre></td><td class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;">&lt; ?xml <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;utf-8&quot;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;onlinefriends<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;friends<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;onlinefrienddata<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;friendid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>1300010000<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/friendid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;province<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>北京市<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/province<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;city<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>北京市<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/city<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;age<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>18<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/age<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;gender<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>2<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/gender<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;hasphoto<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>true<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/hasphoto<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/onlinefrienddata<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;onlinefrienddata<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;friendid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>1300010002<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/friendid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;province<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>北京市<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/province<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;city<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>北京市<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/city<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;age<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>27<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/age<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;gender<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>2<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/gender<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;hasphoto<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>false<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/hasphoto<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/onlinefrienddata<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;onlinefrienddata<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;friendid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>1300010004<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/friendid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;province<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>广东省<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/province<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;city<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>广州市<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/city<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;age<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>45<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/age<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;gender<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/gender<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;hasphoto<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>true<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/hasphoto<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/onlinefrienddata<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/friends<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/onlinefriends<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></td></tr></table></div>

<p>然后需要有一个类，利用XmlSerializer来反序列化这些测试数据</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #000000;">&#91;</span>XmlRoot<span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;OnlineFriends&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#93;</span>
<span style="color: #0600FF;">public</span> <span style="color: #FF0000;">class</span> OnlineFriends
<span style="color: #000000;">&#123;</span>
	<span style="color: #0600FF;">private</span> <span style="color: #FF0000;">bool</span> IsEmpty <span style="color: #008000;">=</span> true<span style="color: #008000;">;</span>
&nbsp;
	<span style="color: #0600FF;">private</span> <span style="color: #0600FF;">static</span> OnlineFriends fs <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> OnlineFriends<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
	<span style="color: #0600FF;">private</span> OnlineFriends<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
	<span style="color: #000000;">&#123;</span> <span style="color: #000000;">&#125;</span>
&nbsp;
	<span style="color: #0600FF;">public</span> <span style="color: #0600FF;">static</span> OnlineFriends Instance
	<span style="color: #000000;">&#123;</span>
		get
		<span style="color: #000000;">&#123;</span>
			<span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>fs.<span style="color: #0000FF;">IsEmpty</span><span style="color: #000000;">&#41;</span>
			<span style="color: #000000;">&#123;</span>
				fs.<span style="color: #0000FF;">Deserialize</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
			<span style="color: #000000;">&#125;</span>
			<span style="color: #0600FF;">return</span> fs<span style="color: #008000;">;</span>
		<span style="color: #000000;">&#125;</span>
	<span style="color: #000000;">&#125;</span>
&nbsp;
	<span style="color: #0600FF;">private</span> <span style="color: #0600FF;">void</span> Deserialize<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
	<span style="color: #000000;">&#123;</span>
		var serialzer <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> XmlSerializer<span style="color: #000000;">&#40;</span><span style="color: #008000;">typeof</span><span style="color: #000000;">&#40;</span>OnlineFriends<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
		<span style="color: #0600FF;">using</span> <span style="color: #000000;">&#40;</span>XmlReader xmlreader <span style="color: #008000;">=</span> XmlReader.<span style="color: #0000FF;">Create</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;OnlineFriends.xml&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>
		<span style="color: #000000;">&#123;</span>
			fs <span style="color: #008000;">=</span> serialzer.<span style="color: #0000FF;">Deserialize</span><span style="color: #000000;">&#40;</span>xmlreader<span style="color: #000000;">&#41;</span> <span style="color: #0600FF;">as</span> OnlineFriends<span style="color: #008000;">;</span>
			fs.<span style="color: #0000FF;">IsEmpty</span> <span style="color: #008000;">=</span> false<span style="color: #008000;">;</span>
		<span style="color: #000000;">&#125;</span>
	<span style="color: #000000;">&#125;</span>
&nbsp;
	<span style="color: #0600FF;">public</span> <span style="color: #FF0000;">class</span> OnlineFriendData
	<span style="color: #000000;">&#123;</span>
		<span style="color: #000000;">&#91;</span>XmlElement<span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;FriendId&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#93;</span>
		<span style="color: #0600FF;">public</span> <span style="color: #FF0000;">int</span> FriendId <span style="color: #000000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #000000;">&#125;</span>
&nbsp;
		<span style="color: #000000;">&#91;</span>XmlElement<span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;Province&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#93;</span>
		<span style="color: #0600FF;">public</span> <span style="color: #FF0000;">string</span> Province <span style="color: #000000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #000000;">&#125;</span>
&nbsp;
		<span style="color: #000000;">&#91;</span>XmlElement<span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;City&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#93;</span>
		<span style="color: #0600FF;">public</span> <span style="color: #FF0000;">string</span> City <span style="color: #000000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #000000;">&#125;</span>
&nbsp;
		<span style="color: #000000;">&#91;</span>XmlElement<span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;Age&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#93;</span>
		<span style="color: #0600FF;">public</span> <span style="color: #FF0000;">int</span> Age <span style="color: #000000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #000000;">&#125;</span>
&nbsp;
		<span style="color: #000000;">&#91;</span>XmlElement<span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;Gender&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#93;</span>
		<span style="color: #0600FF;">public</span> <span style="color: #FF0000;">byte</span> Gender <span style="color: #000000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #000000;">&#125;</span>
&nbsp;
		<span style="color: #000000;">&#91;</span>XmlElement<span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;HasPhoto&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#93;</span>
		<span style="color: #0600FF;">public</span> <span style="color: #FF0000;">bool</span> HasPhoto <span style="color: #000000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #000000;">&#125;</span>
	<span style="color: #000000;">&#125;</span>
&nbsp;
	<span style="color: #000000;">&#91;</span>XmlArray<span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;Friends&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#93;</span>
	<span style="color: #000000;">&#91;</span>XmlArrayItem<span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;OnlineFriendData&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#93;</span>
	<span style="color: #0600FF;">public</span> OnlineFriendData<span style="color: #000000;">&#91;</span><span style="color: #000000;">&#93;</span> Friends <span style="color: #000000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span></pre></td></tr></table></div>

<p>数据的准备工作就差不多了，看一个简单的测试。首先这个测试方法会重新初始化测试数据，然后查询27岁的在线会员，查询出来的结果保存在ids的INT列表中。OnlineFriends.Instance.Friends对象中保存了所有在线好友的数据，它是一个实现了IEnumerable<t>接口的类，所以可以使用LINQ相关的<a href="http://msdn.microsoft.com/en-us/library/bb383977.aspx" target="_blank">扩展方法</a>。</p>
<p>在OnlineFriends.Instance.Friends.Where(x => x.Age == age)语句中，“x => x.Age == age”是一个应用了Lambda表达式的匿名委托，整个语句的意思就是在OnlineFriends.Instance.Friends这个集合中，找到年龄==age的元素。</p>
<p>不过找到了以后还不行啊，SUT返回的是INT列表，而刚才查到的是OnlineFriendData对象的集合，接下来可以用Select(y => y.FriendId).ToList<int>()对集合做一个投影，只取出FriendId属性，并且转换为INT列表。</p>
<p>最后用CollectionAssert.AreEquivalent()方法对两个INT列表进行比较，看列表是否相等。</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #000000;">&#91;</span>TestMethod<span style="color: #000000;">&#93;</span>
<span style="color: #0600FF;">public</span> <span style="color: #0600FF;">void</span> GetOnlineFriendsIdList_Query_Age_LowerUpperDiffOne<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
	<span style="color: #008080; font-style: italic;">//重新初始化测试数据</span>
	TestHelp.<span style="color: #0000FF;">InitForSearch</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
	<span style="color: #FF0000;">int</span> age <span style="color: #008000;">=</span> <span style="color: #FF0000;">27</span><span style="color: #008000;">;</span>
	OnlineFriendQuery query <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> OnlineFriendQuery<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
	query.<span style="color: #0000FF;">AgeLowerBound</span> <span style="color: #008000;">=</span> age<span style="color: #008000;">;</span>
	query.<span style="color: #0000FF;">AgeUpperBound</span> <span style="color: #008000;">=</span> age<span style="color: #008000;">;</span>
             <span style="color: #008080; font-style: italic;">//根据条件查询在线会员，在这里就是要查询27岁的会员</span>
	List<span style="color: #008000;">&lt;</span><span style="color: #FF0000;">int</span><span style="color: #008000;">&gt;</span> ids <span style="color: #008000;">=</span> FriendListGateway.<span style="color: #0000FF;">FriendListProvider</span>.<span style="color: #0000FF;">GetOnlineFriendsIdList</span><span style="color: #000000;">&#40;</span>query, MyAllPc<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
	<span style="color: #008080; font-style: italic;">//Two collects are equivalent</span>
	CollectionAssert.<span style="color: #0000FF;">AreEquivalent</span><span style="color: #000000;">&#40;</span>OnlineFriends.<span style="color: #0000FF;">Instance</span>.<span style="color: #0000FF;">Friends</span>.<span style="color: #0000FF;">Where</span><span style="color: #000000;">&#40;</span>x <span style="color: #008000;">=&gt;</span> x.<span style="color: #0000FF;">Age</span> <span style="color: #008000;">==</span> age<span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">Select</span><span style="color: #000000;">&#40;</span>y <span style="color: #008000;">=&gt;</span> y.<span style="color: #0000FF;">FriendId</span><span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">ToList</span><span style="color: #008000;">&lt;/</span><span style="color: #FF0000;">int</span><span style="color: #008000;">&gt;&lt;</span><span style="color: #FF0000;">int</span><span style="color: #008000;">&gt;</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>, ids<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span>
<span style="color: #008000;">&lt;/</span><span style="color: #FF0000;">int</span><span style="color: #008000;">&gt;</span></pre></td></tr></table></div>

<p>假如使用我最开始的测试方法（就是先准备测试数据，然后人工统计一下里面有多少个27岁的数据，最后进行比较），我在完成了这一条测试以后，接下来还要小心翼翼地添加测试数据，不能再添加年龄是27岁的数据，要不然就会影响到测试结果。但是应用了LINQ以后，我在后续的测试数据设计中就无需要担心新设计的测试数据会对老的测试造成影响。甚至我还可以用程序生成各种不同的数据，填入数据库，供我测试用。</int></t></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%2Fwhiteboxtesting%2Fusing-linq-to-object-in-testing%2F&amp;title=Linq%20to%20Object%E5%9C%A8%E6%B5%8B%E8%AF%95%E4%B8%AD%E7%9A%84%E5%BA%94%E7%94%A8&amp;annotation=.NET%20Framework%203.5%E4%B8%AD%E5%BC%95%E5%85%A5%E4%BA%86%E4%B8%80%E4%B8%AA%E6%96%B0%E7%89%B9%E6%80%A7LINQ%EF%BC%88%E9%9B%86%E6%88%90%E8%AF%AD%E8%A8%80%E6%9F%A5%E8%AF%A2%EF%BC%89%EF%BC%8C%E6%8D%AE%E8%AF%B4.NET%20Framework%203.5%E4%B8%AD%E5%BE%88%E5%A4%9A%E7%89%B9%E6%80%A7%E9%83%BD%E6%98%AF%E4%B8%BALINQ%E8%80%8C%E6%9C%8D%E5%8A%A1%E7%9A%84%EF%BC%8C%E4%BE%8B%E5%A6%82Lambda%E8%A1%A8%E8%BE%BE%E5%BC%8F%E7%9A%84%E6%94%AF%E6%8C%81%EF%BC%8C%E5%8C%BF%E5%90%8D%E7%B1%BB%E5%9E%8B%EF%BC%8C%E7%AD%89%E7%AD%89%E2%80%A6%E2%80%A6%E8%BF%99%E7%AF%87%E6%96%87%E7%AB%A0%E4%BC%9A%E8%AE%B2%E8%BF%B0%E4%B8%80%E4%B8%AA%E6%8A%8ALinq%20to%20Object%E5%BA%94" 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%2Fwhiteboxtesting%2Fusing-linq-to-object-in-testing%2F&amp;title=Linq%20to%20Object%E5%9C%A8%E6%B5%8B%E8%AF%95%E4%B8%AD%E7%9A%84%E5%BA%94%E7%94%A8&amp;bodytext=.NET%20Framework%203.5%E4%B8%AD%E5%BC%95%E5%85%A5%E4%BA%86%E4%B8%80%E4%B8%AA%E6%96%B0%E7%89%B9%E6%80%A7LINQ%EF%BC%88%E9%9B%86%E6%88%90%E8%AF%AD%E8%A8%80%E6%9F%A5%E8%AF%A2%EF%BC%89%EF%BC%8C%E6%8D%AE%E8%AF%B4.NET%20Framework%203.5%E4%B8%AD%E5%BE%88%E5%A4%9A%E7%89%B9%E6%80%A7%E9%83%BD%E6%98%AF%E4%B8%BALINQ%E8%80%8C%E6%9C%8D%E5%8A%A1%E7%9A%84%EF%BC%8C%E4%BE%8B%E5%A6%82Lambda%E8%A1%A8%E8%BE%BE%E5%BC%8F%E7%9A%84%E6%94%AF%E6%8C%81%EF%BC%8C%E5%8C%BF%E5%90%8D%E7%B1%BB%E5%9E%8B%EF%BC%8C%E7%AD%89%E7%AD%89%E2%80%A6%E2%80%A6%E8%BF%99%E7%AF%87%E6%96%87%E7%AB%A0%E4%BC%9A%E8%AE%B2%E8%BF%B0%E4%B8%80%E4%B8%AA%E6%8A%8ALinq%20to%20Object%E5%BA%94" 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%2Fusing-linq-to-object-in-testing%2F&amp;title=Linq%20to%20Object%E5%9C%A8%E6%B5%8B%E8%AF%95%E4%B8%AD%E7%9A%84%E5%BA%94%E7%94%A8&amp;notes=.NET%20Framework%203.5%E4%B8%AD%E5%BC%95%E5%85%A5%E4%BA%86%E4%B8%80%E4%B8%AA%E6%96%B0%E7%89%B9%E6%80%A7LINQ%EF%BC%88%E9%9B%86%E6%88%90%E8%AF%AD%E8%A8%80%E6%9F%A5%E8%AF%A2%EF%BC%89%EF%BC%8C%E6%8D%AE%E8%AF%B4.NET%20Framework%203.5%E4%B8%AD%E5%BE%88%E5%A4%9A%E7%89%B9%E6%80%A7%E9%83%BD%E6%98%AF%E4%B8%BALINQ%E8%80%8C%E6%9C%8D%E5%8A%A1%E7%9A%84%EF%BC%8C%E4%BE%8B%E5%A6%82Lambda%E8%A1%A8%E8%BE%BE%E5%BC%8F%E7%9A%84%E6%94%AF%E6%8C%81%EF%BC%8C%E5%8C%BF%E5%90%8D%E7%B1%BB%E5%9E%8B%EF%BC%8C%E7%AD%89%E7%AD%89%E2%80%A6%E2%80%A6%E8%BF%99%E7%AF%87%E6%96%87%E7%AB%A0%E4%BC%9A%E8%AE%B2%E8%BF%B0%E4%B8%80%E4%B8%AA%E6%8A%8ALinq%20to%20Object%E5%BA%94" 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%2Fusing-linq-to-object-in-testing%2F&amp;t=Linq%20to%20Object%E5%9C%A8%E6%B5%8B%E8%AF%95%E4%B8%AD%E7%9A%84%E5%BA%94%E7%94%A8" 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%2Fusing-linq-to-object-in-testing%2F&title=Linq%20to%20Object%E5%9C%A8%E6%B5%8B%E8%AF%95%E4%B8%AD%E7%9A%84%E5%BA%94%E7%94%A8" 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%2Fusing-linq-to-object-in-testing%2F&title=Linq%20to%20Object%E5%9C%A8%E6%B5%8B%E8%AF%95%E4%B8%AD%E7%9A%84%E5%BA%94%E7%94%A8&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=Linq%20to%20Object%E5%9C%A8%E6%B5%8B%E8%AF%95%E4%B8%AD%E7%9A%84%E5%BA%94%E7%94%A8&amp;link=http%3A%2F%2Fmagustest.com%2Fblog%2Fwhiteboxtesting%2Fusing-linq-to-object-in-testing%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%2Fusing-linq-to-object-in-testing%2F&amp;title=Linq%20to%20Object%E5%9C%A8%E6%B5%8B%E8%AF%95%E4%B8%AD%E7%9A%84%E5%BA%94%E7%94%A8" 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%2Fusing-linq-to-object-in-testing%2F&amp;title=Linq%20to%20Object%E5%9C%A8%E6%B5%8B%E8%AF%95%E4%B8%AD%E7%9A%84%E5%BA%94%E7%94%A8&amp;body=.NET%20Framework%203.5%E4%B8%AD%E5%BC%95%E5%85%A5%E4%BA%86%E4%B8%80%E4%B8%AA%E6%96%B0%E7%89%B9%E6%80%A7LINQ%EF%BC%88%E9%9B%86%E6%88%90%E8%AF%AD%E8%A8%80%E6%9F%A5%E8%AF%A2%EF%BC%89%EF%BC%8C%E6%8D%AE%E8%AF%B4.NET%20Framework%203.5%E4%B8%AD%E5%BE%88%E5%A4%9A%E7%89%B9%E6%80%A7%E9%83%BD%E6%98%AF%E4%B8%BALINQ%E8%80%8C%E6%9C%8D%E5%8A%A1%E7%9A%84%EF%BC%8C%E4%BE%8B%E5%A6%82Lambda%E8%A1%A8%E8%BE%BE%E5%BC%8F%E7%9A%84%E6%94%AF%E6%8C%81%EF%BC%8C%E5%8C%BF%E5%90%8D%E7%B1%BB%E5%9E%8B%EF%BC%8C%E7%AD%89%E7%AD%89%E2%80%A6%E2%80%A6%E8%BF%99%E7%AF%87%E6%96%87%E7%AB%A0%E4%BC%9A%E8%AE%B2%E8%BF%B0%E4%B8%80%E4%B8%AA%E6%8A%8ALinq%20to%20Object%E5%BA%94" 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=Linq%20to%20Object%E5%9C%A8%E6%B5%8B%E8%AF%95%E4%B8%AD%E7%9A%84%E5%BA%94%E7%94%A8&uri=http%3A%2F%2Fmagustest.com%2Fblog%2Fwhiteboxtesting%2Fusing-linq-to-object-in-testing%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=Linq%20to%20Object%E5%9C%A8%E6%B5%8B%E8%AF%95%E4%B8%AD%E7%9A%84%E5%BA%94%E7%94%A8%20-%20http%3A%2F%2Fmagustest.com%2Fblog%2Fwhiteboxtesting%2Fusing-linq-to-object-in-testing%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/net/automatic-generate-xml-instance-by-using-xsd/' rel='bookmark' title='Permanent Link: 用XSD自动生成XML对应的.NET实体类'>用XSD自动生成XML对应的.NET实体类</a></li>
<li><a href='http://magustest.com/blog/whiteboxtesting/data-driven-test-in-unit-test/' rel='bookmark' title='Permanent Link: 在单元测试中应用数据驱动'>在单元测试中应用数据驱动</a></li>
<li><a href='http://magustest.com/blog/softwaretesting/using-httpcontext-in-unittest/' rel='bookmark' title='Permanent Link: 在C#单元测试中使用HttpContext的简单解决办法'>在C#单元测试中使用HttpContext的简单解决办法</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://magustest.com/blog/whiteboxtesting/using-linq-to-object-in-testing/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>在测试项目中应用Pex的经验分享</title>
		<link>http://magustest.com/blog/whiteboxtesting/using-pex/</link>
		<comments>http://magustest.com/blog/whiteboxtesting/using-pex/#comments</comments>
		<pubDate>Mon, 15 Jun 2009 02:28:40 +0000</pubDate>
		<dc:creator>magus</dc:creator>
				<category><![CDATA[白盒测试]]></category>
		<category><![CDATA[PEX]]></category>

		<guid isPermaLink="false">http://magustest.com/blog/?p=547</guid>
		<description><![CDATA[Pex是微软研究院开发的一个自动化白盒测试工具，前面我也写过一些博客来对Pex进行介绍，上周决定正式把Pex应用到真正的项目中，不过效果没有想象中的好，不过还是决定记录下一些心得。 1. 关于测试类名称和测试方法名称 为了把Pex和其他的单元测试方法区分开来，本人选择了把所有Pex的测试都以PexTest作为方法名和类名的前缀。因为Pex会根据已经写好的PUT(Parameterized Unit Test)生成一般的单元测试代码，规则可以自定义，一般都是PUT的名字然后跟上01，02，03……如果我们以PexTest作为前缀，那么就比较容易区分PexTest和普通的单元测试。 2. 每个PexTest都会生成一些普通的单元测试代码，这些代码都是存放在一个叫{TestMethodName}.g.cs的文件中，对于这个文件里面代码，不建议手动修改。 3. 在组织测试代码的时候，应该吧PexTest和一般的单元测试分开，如图： 4. 如果需要测试Singleton实例中的方法，需要给这个实例创建一个带有[PexFactoryMethod]属性的方法，来告诉Pex如何获得Singleton实例。例如： 1 2 3 4 5 6 7 8 public static partial class CommentProviderFactory &#123; &#91;PexFactoryMethod&#40;typeof&#40;CommentProvider&#41;&#41;&#93; public static object Create&#40;&#41; &#123; return CommentProvider.Instance; &#125; &#125; 5. Pex有时候会尝试着对.NET自带的代码也进行测试，如果遇到这种情况，可以在Pex Exploration Results窗口中把相关的方法标记为不检测。 6. 如果修改了PUT，那么原来在{TestMethodName}.g.cs自动生成的测试方法有可能没法运行，可以把这个文件删掉，然后让Pex重新生成测试。 Share and Enjoy: Related posts:Linq to Object在测试中的应用 用XSD自动生成XML对应的.NET实体类 PEX-.NET自动化白盒测试工具的介绍(1)


Related posts:<ol><li><a href='http://magustest.com/blog/whiteboxtesting/using-linq-to-object-in-testing/' rel='bookmark' title='Permanent Link: Linq to Object在测试中的应用'>Linq to Object在测试中的应用</a></li>
<li><a href='http://magustest.com/blog/net/automatic-generate-xml-instance-by-using-xsd/' rel='bookmark' title='Permanent Link: 用XSD自动生成XML对应的.NET实体类'>用XSD自动生成XML对应的.NET实体类</a></li>
<li><a href='http://magustest.com/blog/whiteboxtesting/introduction-to-pex-automated-white-box-testing-for-dotnet/' rel='bookmark' title='Permanent Link: PEX-.NET自动化白盒测试工具的介绍(1)'>PEX-.NET自动化白盒测试工具的介绍(1)</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><a href="http://research.microsoft.com/en-us/projects/Pex/" target="_blank">Pex</a>是微软研究院开发的一个自动化白盒测试工具，前面我也写过一些博客来对Pex进行介绍，上周决定正式把Pex应用到真正的项目中，不过效果没有想象中的好，不过还是决定记录下一些心得。</p>
<p>1. 关于测试类名称和测试方法名称</p>
<p>为了把Pex和其他的单元测试方法区分开来，本人选择了把所有Pex的测试都以PexTest作为方法名和类名的前缀。因为Pex会根据已经写好的PUT(Parameterized Unit Test)生成一般的单元测试代码，规则可以自定义，一般都是PUT的名字然后跟上01，02，03……如果我们以PexTest作为前缀，那么就比较容易区分PexTest和普通的单元测试。</p>
<p>2. 每个PexTest都会生成一些普通的单元测试代码，这些代码都是存放在一个叫{TestMethodName}.g.cs的文件中，对于这个文件里面代码，不建议手动修改。</p>
<p>3. 在组织测试代码的时候，应该吧PexTest和一般的单元测试分开，如图：</p>
<p><img class="alignnone size-full wp-image-548" title="test" src="http://magustest.com/blog/wp-content/uploads/2009/06/test1.png" alt="test" width="270" height="192" /></p>
<p>4. 如果需要测试Singleton实例中的方法，需要给这个实例创建一个带有[PexFactoryMethod]属性的方法，来告诉Pex如何获得Singleton实例。例如：<br />
<span id="more-547"></span></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF;">public</span> <span style="color: #0600FF;">static</span> <span style="color: #0600FF;">partial</span> <span style="color: #FF0000;">class</span> CommentProviderFactory
<span style="color: #000000;">&#123;</span>
	<span style="color: #000000;">&#91;</span>PexFactoryMethod<span style="color: #000000;">&#40;</span><span style="color: #008000;">typeof</span><span style="color: #000000;">&#40;</span>CommentProvider<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#93;</span>
	<span style="color: #0600FF;">public</span> <span style="color: #0600FF;">static</span> <span style="color: #FF0000;">object</span> Create<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
	<span style="color: #000000;">&#123;</span>
		<span style="color: #0600FF;">return</span> CommentProvider.<span style="color: #0000FF;">Instance</span><span style="color: #008000;">;</span>
	<span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span></pre></td></tr></table></div>

<p>5. Pex有时候会尝试着对.NET自带的代码也进行测试，如果遇到这种情况，可以在Pex Exploration Results窗口中把相关的方法标记为不检测。</p>
<p>6. 如果修改了PUT，那么原来在{TestMethodName}.g.cs自动生成的测试方法有可能没法运行，可以把这个文件删掉，然后让Pex重新生成测试。</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%2Fusing-pex%2F&amp;t=%E5%9C%A8%E6%B5%8B%E8%AF%95%E9%A1%B9%E7%9B%AE%E4%B8%AD%E5%BA%94%E7%94%A8Pex%E7%9A%84%E7%BB%8F%E9%AA%8C%E5%88%86%E4%BA%AB" 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%2Fusing-pex%2F&title=%E5%9C%A8%E6%B5%8B%E8%AF%95%E9%A1%B9%E7%9B%AE%E4%B8%AD%E5%BA%94%E7%94%A8Pex%E7%9A%84%E7%BB%8F%E9%AA%8C%E5%88%86%E4%BA%AB" 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%2Fusing-pex%2F&title=%E5%9C%A8%E6%B5%8B%E8%AF%95%E9%A1%B9%E7%9B%AE%E4%B8%AD%E5%BA%94%E7%94%A8Pex%E7%9A%84%E7%BB%8F%E9%AA%8C%E5%88%86%E4%BA%AB&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%9C%A8%E6%B5%8B%E8%AF%95%E9%A1%B9%E7%9B%AE%E4%B8%AD%E5%BA%94%E7%94%A8Pex%E7%9A%84%E7%BB%8F%E9%AA%8C%E5%88%86%E4%BA%AB&amp;link=http%3A%2F%2Fmagustest.com%2Fblog%2Fwhiteboxtesting%2Fusing-pex%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%2Fusing-pex%2F&amp;title=%E5%9C%A8%E6%B5%8B%E8%AF%95%E9%A1%B9%E7%9B%AE%E4%B8%AD%E5%BA%94%E7%94%A8Pex%E7%9A%84%E7%BB%8F%E9%AA%8C%E5%88%86%E4%BA%AB" 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%2Fusing-pex%2F&amp;title=%E5%9C%A8%E6%B5%8B%E8%AF%95%E9%A1%B9%E7%9B%AE%E4%B8%AD%E5%BA%94%E7%94%A8Pex%E7%9A%84%E7%BB%8F%E9%AA%8C%E5%88%86%E4%BA%AB&amp;body=Pex%E6%98%AF%E5%BE%AE%E8%BD%AF%E7%A0%94%E7%A9%B6%E9%99%A2%E5%BC%80%E5%8F%91%E7%9A%84%E4%B8%80%E4%B8%AA%E8%87%AA%E5%8A%A8%E5%8C%96%E7%99%BD%E7%9B%92%E6%B5%8B%E8%AF%95%E5%B7%A5%E5%85%B7%EF%BC%8C%E5%89%8D%E9%9D%A2%E6%88%91%E4%B9%9F%E5%86%99%E8%BF%87%E4%B8%80%E4%BA%9B%E5%8D%9A%E5%AE%A2%E6%9D%A5%E5%AF%B9Pex%E8%BF%9B%E8%A1%8C%E4%BB%8B%E7%BB%8D%EF%BC%8C%E4%B8%8A%E5%91%A8%E5%86%B3%E5%AE%9A%E6%AD%A3%E5%BC%8F%E6%8A%8APex%E5%BA%94%E7%94%A8%E5%88%B0%E7%9C%9F%E6%AD%A3%E7%9A%84%E9%A1%B9%E7%9B%AE%E4%B8%AD%EF%BC%8C%E4%B8%8D%E8%BF%87%E6%95%88%E6%9E%9C%E6%B2%A1%E6%9C%89%E6%83%B3%E8%B1%A1%E4%B8%AD%E7%9A%84%E5%A5%BD%EF%BC%8C%E4%B8%8D%E8%BF%87%E8%BF%98%E6%98%AF%E5%86%B3%E5%AE%9A%E8%AE%B0%E5%BD%95%E4%B8%8B%E4%B8%80%E4%BA%9B%E5%BF%83%E5%BE%97%E3" 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%9C%A8%E6%B5%8B%E8%AF%95%E9%A1%B9%E7%9B%AE%E4%B8%AD%E5%BA%94%E7%94%A8Pex%E7%9A%84%E7%BB%8F%E9%AA%8C%E5%88%86%E4%BA%AB&uri=http%3A%2F%2Fmagustest.com%2Fblog%2Fwhiteboxtesting%2Fusing-pex%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%9C%A8%E6%B5%8B%E8%AF%95%E9%A1%B9%E7%9B%AE%E4%B8%AD%E5%BA%94%E7%94%A8Pex%E7%9A%84%E7%BB%8F%E9%AA%8C%E5%88%86%E4%BA%AB%20-%20http%3A%2F%2Fmagustest.com%2Fblog%2Fwhiteboxtesting%2Fusing-pex%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-linq-to-object-in-testing/' rel='bookmark' title='Permanent Link: Linq to Object在测试中的应用'>Linq to Object在测试中的应用</a></li>
<li><a href='http://magustest.com/blog/net/automatic-generate-xml-instance-by-using-xsd/' rel='bookmark' title='Permanent Link: 用XSD自动生成XML对应的.NET实体类'>用XSD自动生成XML对应的.NET实体类</a></li>
<li><a href='http://magustest.com/blog/whiteboxtesting/introduction-to-pex-automated-white-box-testing-for-dotnet/' rel='bookmark' title='Permanent Link: PEX-.NET自动化白盒测试工具的介绍(1)'>PEX-.NET自动化白盒测试工具的介绍(1)</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://magustest.com/blog/whiteboxtesting/using-pex/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<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/refactoring-unit-test/</link>
		<comments>http://magustest.com/blog/whiteboxtesting/refactoring-unit-test/#comments</comments>
		<pubDate>Sat, 21 Mar 2009 11:17:35 +0000</pubDate>
		<dc:creator>magus</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[白盒测试]]></category>
		<category><![CDATA[单元测试]]></category>

		<guid isPermaLink="false">http://magustest.com/blog/?p=383</guid>
		<description><![CDATA[Martin Fowler的《重构》这本书基本上每个程序员都会看，对于做单元测试的测试工程师来说，测试的代码本身也是程序，也需要重构。最近在看《XUnit Test Patterns》，把以前的做的东西重新梳理了一下，并且落实到新的项目中。 首先来看看一个最原始的单元测试代码： 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 &#91;TestMethod&#93; public void GetPaymentAccountByOwnerID&#40;&#41; &#123; int ownerId = 1300100000; //Delete the account TestHelper.DeletePaymentAccountByOwnerId&#40;ownerId&#41;; &#160; //Here should be create an account PaymentAccount paymentAccount = PaymentGateway.PaymentProvider.GetPaymentAccountByOwnerID&#40;ownerId, AccountOwnerType.NormalUser&#41;; &#160; //Verify the payment account instance Assert.IsTrue&#40;paymentAccount.AccountID [...]


Related posts:<ol><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/beginning-nmock/' rel='bookmark' title='Permanent Link: NMock2入门经验'>NMock2入门经验</a></li>
<li><a href='http://magustest.com/blog/automationtesting/data-driven-codedui-test/' rel='bookmark' title='Permanent Link: 实现数据驱动的CodedUI Test'>实现数据驱动的CodedUI Test</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Martin Fowler的<a href="http://www.china-pub.com/12901">《重构》</a>这本书基本上每个程序员都会看，对于做单元测试的测试工程师来说，测试的代码本身也是程序，也需要重构。最近在看<a href="http://xunitpatterns.com/">《XUnit Test Patterns》</a>，把以前的做的东西重新梳理了一下，并且落实到新的项目中。</p>
<p>首先来看看一个最原始的单元测试代码：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #000000;">&#91;</span>TestMethod<span style="color: #000000;">&#93;</span>
<span style="color: #0600FF;">public</span> <span style="color: #0600FF;">void</span> GetPaymentAccountByOwnerID<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
	<span style="color: #FF0000;">int</span> ownerId <span style="color: #008000;">=</span> <span style="color: #FF0000;">1300100000</span><span style="color: #008000;">;</span>
	<span style="color: #008080; font-style: italic;">//Delete the account</span>
	TestHelper.<span style="color: #0000FF;">DeletePaymentAccountByOwnerId</span><span style="color: #000000;">&#40;</span>ownerId<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
	<span style="color: #008080; font-style: italic;">//Here should be create an account</span>
	PaymentAccount paymentAccount <span style="color: #008000;">=</span> PaymentGateway.<span style="color: #0000FF;">PaymentProvider</span>.<span style="color: #0000FF;">GetPaymentAccountByOwnerID</span><span style="color: #000000;">&#40;</span>ownerId, AccountOwnerType.<span style="color: #0000FF;">NormalUser</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
	<span style="color: #008080; font-style: italic;">//Verify the payment account instance</span>
	Assert.<span style="color: #0000FF;">IsTrue</span><span style="color: #000000;">&#40;</span>paymentAccount.<span style="color: #0000FF;">AccountID</span> <span style="color: #008000;">&gt;</span> <span style="color: #FF0000;">0</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
	Assert.<span style="color: #0000FF;">AreEqual</span><span style="color: #000000;">&#40;</span>DateTime.<span style="color: #0000FF;">Now</span>.<span style="color: #0000FF;">DayOfYear</span>, paymentAccount.<span style="color: #0000FF;">CreateTime</span>.<span style="color: #0000FF;">DayOfYear</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
	Assert.<span style="color: #0000FF;">AreEqual</span><span style="color: #000000;">&#40;</span>DateTime.<span style="color: #0000FF;">Now</span>.<span style="color: #0000FF;">DayOfYear</span>, paymentAccount.<span style="color: #0000FF;">UpdateTime</span>.<span style="color: #0000FF;">DayOfYear</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
	Assert.<span style="color: #0000FF;">AreEqual</span><span style="color: #000000;">&#40;</span><span style="color: #FF0000;">0</span>, paymentAccount.<span style="color: #0000FF;">Balance</span>, <span style="color: #FF0000;">0.0001</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
	Assert.<span style="color: #0000FF;">AreEqual</span><span style="color: #000000;">&#40;</span><span style="color: #FF0000;">0</span>, paymentAccount.<span style="color: #0000FF;">AvailableBalance</span>, <span style="color: #FF0000;">0.0001</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
	Assert.<span style="color: #0000FF;">AreEqual</span><span style="color: #000000;">&#40;</span><span style="color: #FF0000;">0</span>, paymentAccount.<span style="color: #0000FF;">FreezeAccount</span>, <span style="color: #FF0000;">0.0001</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span></pre></td></tr></table></div>

<p>以上是个很简单的单元测试代码，应用了AAA原则，首先做好准备（删掉原有的数据），然后执行测试，最后再验证返回结果。看起来很好也很清晰。首先发现一个问题，就是那一堆Assert让人觉得迷惑，究竟想干啥？其实那6句Assert都是验证程序返回的PaymentAccount对象是是否符合设计。我把这些Assert语句提取出来，作为一个方法，让测试代码更加容易让人明白。也就有了版本2。<br />
<span id="more-383"></span></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #000000;">&#91;</span>TestMethod<span style="color: #000000;">&#93;</span>
<span style="color: #0600FF;">public</span> <span style="color: #0600FF;">void</span> GetPaymentAccountByOwnerID<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
	<span style="color: #FF0000;">int</span> ownerId <span style="color: #008000;">=</span> <span style="color: #FF0000;">1300100000</span><span style="color: #008000;">;</span>
	<span style="color: #008080; font-style: italic;">//Delete the account</span>
	TestHelper.<span style="color: #0000FF;">DeletePaymentAccountByOwnerId</span><span style="color: #000000;">&#40;</span>ownerId<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
	<span style="color: #008080; font-style: italic;">//Here should be create an account</span>
	PaymentAccount paymentAccount <span style="color: #008000;">=</span> PaymentGateway.<span style="color: #0000FF;">PaymentProvider</span>.<span style="color: #0000FF;">GetPaymentAccountByOwnerID</span><span style="color: #000000;">&#40;</span>ownerId, AccountOwnerType.<span style="color: #0000FF;">NormalUser</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
	<span style="color: #008080; font-style: italic;">//Verify the payment account instance</span>
	PaymentAccountAssertion<span style="color: #000000;">&#40;</span>paymentAccount<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span>
&nbsp;
<span style="color: #0600FF;">private</span> <span style="color: #0600FF;">void</span> PaymentAccountAssertion<span style="color: #000000;">&#40;</span>PaymentAccount paymentAccount<span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
	Assert.<span style="color: #0000FF;">IsTrue</span><span style="color: #000000;">&#40;</span>paymentAccount.<span style="color: #0000FF;">AccountID</span> <span style="color: #008000;">&gt;</span> <span style="color: #FF0000;">0</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
	Assert.<span style="color: #0000FF;">AreEqual</span><span style="color: #000000;">&#40;</span>DateTime.<span style="color: #0000FF;">Now</span>.<span style="color: #0000FF;">DayOfYear</span>, paymentAccount.<span style="color: #0000FF;">CreateTime</span>.<span style="color: #0000FF;">DayOfYear</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
	Assert.<span style="color: #0000FF;">AreEqual</span><span style="color: #000000;">&#40;</span>DateTime.<span style="color: #0000FF;">Now</span>.<span style="color: #0000FF;">DayOfYear</span>, paymentAccount.<span style="color: #0000FF;">UpdateTime</span>.<span style="color: #0000FF;">DayOfYear</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
	Assert.<span style="color: #0000FF;">AreEqual</span><span style="color: #000000;">&#40;</span><span style="color: #FF0000;">0</span>, paymentAccount.<span style="color: #0000FF;">Balance</span>, <span style="color: #FF0000;">0.0001</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
	Assert.<span style="color: #0000FF;">AreEqual</span><span style="color: #000000;">&#40;</span><span style="color: #FF0000;">0</span>, paymentAccount.<span style="color: #0000FF;">AvailableBalance</span>, <span style="color: #FF0000;">0.0001</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
	Assert.<span style="color: #0000FF;">AreEqual</span><span style="color: #000000;">&#40;</span><span style="color: #FF0000;">0</span>, paymentAccount.<span style="color: #0000FF;">FreezeAccount</span>, <span style="color: #FF0000;">0.0001</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span></pre></td></tr></table></div>

<p>以上代码看起来就舒服多了，比较清晰、简短。但是有一个问题，就是后面的3条Assert语句的期望结果是Hard code的，这样很不利于这个自定义的Assert方法的重用。改！我会把那3个〇抽取成这个方法的一个参数，这个自定义的Assert方法变得更加灵活了。代码不贴上来了，因为有一个问题，就是如果我们还需要对PaymentAccount增加一些属性，而这些属性的值都需要被验证，那么这个PaymentAccountAssertion方法的参数就会越来越长。超长的方法参数也是一个不好的味道，我改！改为传递一个期望的PaymentAccount对象进来，这样就是两个参数了，很好。</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #000000;">&#91;</span>TestMethod<span style="color: #000000;">&#93;</span>
<span style="color: #0600FF;">public</span> <span style="color: #0600FF;">void</span> GetPaymentAccountByOwnerID<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
	<span style="color: #FF0000;">int</span> ownerId <span style="color: #008000;">=</span> <span style="color: #FF0000;">1300100000</span><span style="color: #008000;">;</span>
	<span style="color: #008080; font-style: italic;">//Delete the account</span>
	TestHelper.<span style="color: #0000FF;">DeletePaymentAccountByOwnerId</span><span style="color: #000000;">&#40;</span>ownerId<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
	<span style="color: #008080; font-style: italic;">//Here should be create an account</span>
	PaymentAccount paymentAccount <span style="color: #008000;">=</span> PaymentGateway.<span style="color: #0000FF;">PaymentProvider</span>.<span style="color: #0000FF;">GetPaymentAccountByOwnerID</span><span style="color: #000000;">&#40;</span>ownerId, AccountOwnerType.<span style="color: #0000FF;">NormalUser</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
	<span style="color: #008080; font-style: italic;">//Verify the payment account instance</span>
	PaymentAccount expected <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> PaymentAccount<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
	PaymentAccountAssertion<span style="color: #000000;">&#40;</span>expected, paymentAccount<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span>
&nbsp;
<span style="color: #0600FF;">private</span> <span style="color: #0600FF;">void</span> PaymentAccountAssertion<span style="color: #000000;">&#40;</span>PaymentAccount expectedObject, PaymentAccount paymentAccount<span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
	Assert.<span style="color: #0000FF;">IsTrue</span><span style="color: #000000;">&#40;</span>paymentAccount.<span style="color: #0000FF;">AccountID</span> <span style="color: #008000;">&gt;</span> <span style="color: #FF0000;">0</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
	Assert.<span style="color: #0000FF;">AreEqual</span><span style="color: #000000;">&#40;</span>DateTime.<span style="color: #0000FF;">Now</span>.<span style="color: #0000FF;">DayOfYear</span>, paymentAccount.<span style="color: #0000FF;">CreateTime</span>.<span style="color: #0000FF;">DayOfYear</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
	Assert.<span style="color: #0000FF;">AreEqual</span><span style="color: #000000;">&#40;</span>DateTime.<span style="color: #0000FF;">Now</span>.<span style="color: #0000FF;">DayOfYear</span>, paymentAccount.<span style="color: #0000FF;">UpdateTime</span>.<span style="color: #0000FF;">DayOfYear</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
	Assert.<span style="color: #0000FF;">AreEqual</span><span style="color: #000000;">&#40;</span>expectedObject.<span style="color: #0000FF;">Balance</span>, paymentAccount.<span style="color: #0000FF;">Balance</span>, <span style="color: #FF0000;">0.0001</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
	Assert.<span style="color: #0000FF;">AreEqual</span><span style="color: #000000;">&#40;</span>expectedObject.<span style="color: #0000FF;">AvailableBalance</span>, paymentAccount.<span style="color: #0000FF;">AvailableBalance</span>, <span style="color: #FF0000;">0.0001</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
	Assert.<span style="color: #0000FF;">AreEqual</span><span style="color: #000000;">&#40;</span>expectedObject.<span style="color: #0000FF;">FreezeAccount</span>, paymentAccount.<span style="color: #0000FF;">FreezeAccount</span>, <span style="color: #FF0000;">0.0001</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span></pre></td></tr></table></div>

<p>第三版出来了，这时候我想起淘宝QA TEAM的一篇文章，我想到用反射去做一个简单的比较，而不用对于每个属性都做对比。（但是我犯了一个错误，我只是“想到”，问没有去重新看一次那篇文章，我写的那个方法有缺点！）</p>
<p>先看看用反射比较属性方法的代码：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF;">public</span> <span style="color: #0600FF;">void</span> ObjectAreEqual<span style="color: #008000;">&lt;</span>t<span style="color: #008000;">&gt;</span><span style="color: #000000;">&#40;</span>T expected, T actual, List<span style="color: #008000;">&lt;</span><span style="color: #FF0000;">string</span><span style="color: #008000;">&gt;</span> excludedProperties<span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
	<span style="color: #000000;">System</span>.<span style="color: #0000FF;">Type</span> myType <span style="color: #008000;">=</span> <span style="color: #008000;">typeof</span><span style="color: #000000;">&#40;</span>T<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
	PropertyInfo<span style="color: #000000;">&#91;</span><span style="color: #000000;">&#93;</span> props <span style="color: #008000;">=</span> myType.<span style="color: #0000FF;">GetProperties</span><span style="color: #000000;">&#40;</span>BindingFlags.<span style="color: #0600FF;">Public</span> <span style="color: #008000;">|</span> BindingFlags.<span style="color: #0000FF;">Instance</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
	<span style="color: #0600FF;">foreach</span> <span style="color: #000000;">&#40;</span>var item <span style="color: #0600FF;">in</span> props<span style="color: #000000;">&#41;</span>
	<span style="color: #000000;">&#123;</span>
		<span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span><span style="color: #0600FF;">null</span> <span style="color: #008000;">==</span> excludedProperties <span style="color: #008000;">||</span> <span style="color: #008000;">!</span>excludedProperties.<span style="color: #0000FF;">Contains</span><span style="color: #000000;">&#40;</span>item.<span style="color: #0000FF;">Name</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>
		<span style="color: #000000;">&#123;</span>
			<span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>item.<span style="color: #0000FF;">PropertyType</span>.<span style="color: #0000FF;">Equals</span><span style="color: #000000;">&#40;</span><span style="color: #008000;">typeof</span><span style="color: #000000;">&#40;</span><span style="color: #FF0000;">double</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>
			<span style="color: #000000;">&#123;</span>
				Assert.<span style="color: #0000FF;">AreEqual</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#40;</span><span style="color: #FF0000;">double</span><span style="color: #000000;">&#41;</span>item.<span style="color: #0000FF;">GetValue</span><span style="color: #000000;">&#40;</span>expected, <span style="color: #0600FF;">null</span><span style="color: #000000;">&#41;</span>, <span style="color: #000000;">&#40;</span><span style="color: #FF0000;">double</span><span style="color: #000000;">&#41;</span>item.<span style="color: #0000FF;">GetValue</span><span style="color: #000000;">&#40;</span>actual, <span style="color: #0600FF;">null</span><span style="color: #000000;">&#41;</span>, <span style="color: #FF0000;">0.0001</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
			<span style="color: #000000;">&#125;</span>
			<span style="color: #0600FF;">else</span> <span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>item.<span style="color: #0000FF;">PropertyType</span>.<span style="color: #0000FF;">Equals</span><span style="color: #000000;">&#40;</span><span style="color: #008000;">typeof</span><span style="color: #000000;">&#40;</span><span style="color: #FF0000;">float</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>
			<span style="color: #000000;">&#123;</span>
				Assert.<span style="color: #0000FF;">AreEqual</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#40;</span><span style="color: #FF0000;">float</span><span style="color: #000000;">&#41;</span>item.<span style="color: #0000FF;">GetValue</span><span style="color: #000000;">&#40;</span>expected, <span style="color: #0600FF;">null</span><span style="color: #000000;">&#41;</span>, <span style="color: #000000;">&#40;</span><span style="color: #FF0000;">float</span><span style="color: #000000;">&#41;</span>item.<span style="color: #0000FF;">GetValue</span><span style="color: #000000;">&#40;</span>actual, <span style="color: #0600FF;">null</span><span style="color: #000000;">&#41;</span>, <span style="color: #FF0000;">0.0001</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
			<span style="color: #000000;">&#125;</span>
			<span style="color: #0600FF;">else</span>
			<span style="color: #000000;">&#123;</span>
				Assert.<span style="color: #0000FF;">AreEqual</span><span style="color: #000000;">&#40;</span>item.<span style="color: #0000FF;">GetValue</span><span style="color: #000000;">&#40;</span>expected, <span style="color: #0600FF;">null</span><span style="color: #000000;">&#41;</span>, item.<span style="color: #0000FF;">GetValue</span><span style="color: #000000;">&#40;</span>actual, <span style="color: #0600FF;">null</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
			<span style="color: #000000;">&#125;</span>
		<span style="color: #000000;">&#125;</span>
	<span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span><span style="color: #008000;">&lt;/</span><span style="color: #FF0000;">string</span><span style="color: #008000;">&gt;&lt;/</span>t<span style="color: #008000;">&gt;</span></pre></td></tr></table></div>

<p>比较简单，就是获取所有的Property，然后做Assert，特别针对了double和float做了处理，因为对于浮点数，Assert.AreEqual方法需要指定一个可接受的误差值。excludedProperties这个列表保存了不需要验证的属性名字。整个测试代码如下：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #000000;">&#91;</span>TestMethod<span style="color: #000000;">&#93;</span>
<span style="color: #0600FF;">public</span> <span style="color: #0600FF;">void</span> GetPaymentAccountByOwnerID<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
	<span style="color: #FF0000;">int</span> ownerId <span style="color: #008000;">=</span> <span style="color: #FF0000;">1300100000</span><span style="color: #008000;">;</span>
	<span style="color: #008080; font-style: italic;">//Delete the account</span>
	TestHelper.<span style="color: #0000FF;">DeletePaymentAccountByOwnerId</span><span style="color: #000000;">&#40;</span>ownerId<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
	<span style="color: #008080; font-style: italic;">//Here should be create an account</span>
	PaymentAccount paymentAccount <span style="color: #008000;">=</span> PaymentGateway.<span style="color: #0000FF;">PaymentProvider</span>.<span style="color: #0000FF;">GetPaymentAccountByOwnerID</span><span style="color: #000000;">&#40;</span>ownerId, AccountOwnerType.<span style="color: #0000FF;">NormalUser</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
	<span style="color: #008080; font-style: italic;">//Verify the payment account instance</span>
	PaymentAccount expected <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> PaymentAccount<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
	PaymentAccountAssertion<span style="color: #000000;">&#40;</span>expected, paymentAccount<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span>
&nbsp;
<span style="color: #0600FF;">private</span> <span style="color: #0600FF;">void</span> PaymentAccountAssertion<span style="color: #000000;">&#40;</span>PaymentAccount expectedObject, PaymentAccount paymentAccount<span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
	Assert.<span style="color: #0000FF;">IsTrue</span><span style="color: #000000;">&#40;</span>paymentAccount.<span style="color: #0000FF;">AccountID</span> <span style="color: #008000;">&gt;</span> <span style="color: #FF0000;">0</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
	Assert.<span style="color: #0000FF;">AreEqual</span><span style="color: #000000;">&#40;</span>DateTime.<span style="color: #0000FF;">Now</span>.<span style="color: #0000FF;">DayOfYear</span>, paymentAccount.<span style="color: #0000FF;">CreateTime</span>.<span style="color: #0000FF;">DayOfYear</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
	Assert.<span style="color: #0000FF;">AreEqual</span><span style="color: #000000;">&#40;</span>DateTime.<span style="color: #0000FF;">Now</span>.<span style="color: #0000FF;">DayOfYear</span>, paymentAccount.<span style="color: #0000FF;">UpdateTime</span>.<span style="color: #0000FF;">DayOfYear</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
	List<span style="color: #008000;">&lt;</span><span style="color: #FF0000;">string</span><span style="color: #008000;">&gt;</span> ExcludedProperties <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> List<span style="color: #008000;">&lt;/</span><span style="color: #FF0000;">string</span><span style="color: #008000;">&gt;&lt;</span><span style="color: #FF0000;">string</span><span style="color: #008000;">&gt;</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> <span style="color: #666666;">&quot;AccountID&quot;</span>, <span style="color: #666666;">&quot;CreateTime&quot;</span>, <span style="color: #666666;">&quot;UpdateTime&quot;</span> <span style="color: #000000;">&#125;</span><span style="color: #008000;">;</span>
&nbsp;
	TestUtilityGateway.<span style="color: #0000FF;">CustomizedAssert</span>.<span style="color: #0000FF;">ObjectAreEqual</span><span style="color: #008000;">&lt;</span>paymentaccount<span style="color: #008000;">&gt;</span><span style="color: #000000;">&#40;</span>expectedObject, paymentAccount, ExcludedProperties<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span><span style="color: #008000;">&lt;/</span>paymentaccount<span style="color: #008000;">&gt;&lt;/</span><span style="color: #FF0000;">string</span><span style="color: #008000;">&gt;</span></pre></td></tr></table></div>

<p>下来说说问题：<br />
1. ObjectAreEqual这个方法的最后一个参数不好，那个ExcludedProperties的列表，其实是我懒惰的产物，应该参照 子排牛柳 的设计方法，把需要比较的属性名传递进去。我当初的想法是，那个自定义Assert方法里面的前3条语句已经验证了我那3个属性了，然后我传个参数进去告诉那个方法“你不要验证这3个属性了”。懒惰啊！这样的设计有个问题，我用个比喻吧，我让我女朋友下楼去超市帮我买点东西，我是应该告诉她，“你帮我买ABCDE”呢？还是应该说“你别给我买FGHIJK&#8230;”呢？</p>
<p>2. if (null == excludedProperties || !excludedProperties.Contains(item.Name)) 这句话写的真别扭！也不好！</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%2Fwhiteboxtesting%2Frefactoring-unit-test%2F&amp;title=%E6%B5%8B%E8%AF%95%E4%BB%A3%E7%A0%81%E9%87%8D%E6%9E%84%E5%AE%9E%E4%BE%8B&amp;annotation=Martin%20Fowler%E7%9A%84%E3%80%8A%E9%87%8D%E6%9E%84%E3%80%8B%E8%BF%99%E6%9C%AC%E4%B9%A6%E5%9F%BA%E6%9C%AC%E4%B8%8A%E6%AF%8F%E4%B8%AA%E7%A8%8B%E5%BA%8F%E5%91%98%E9%83%BD%E4%BC%9A%E7%9C%8B%EF%BC%8C%E5%AF%B9%E4%BA%8E%E5%81%9A%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E7%9A%84%E6%B5%8B%E8%AF%95%E5%B7%A5%E7%A8%8B%E5%B8%88%E6%9D%A5%E8%AF%B4%EF%BC%8C%E6%B5%8B%E8%AF%95%E7%9A%84%E4%BB%A3%E7%A0%81%E6%9C%AC%E8%BA%AB%E4%B9%9F%E6%98%AF%E7%A8%8B%E5%BA%8F%EF%BC%8C%E4%B9%9F%E9%9C%80%E8%A6%81%E9%87%8D%E6%9E%84%E3%80%82%E6%9C%80%E8%BF%91%E5%9C%A8%E7%9C%8B%E3%80%8AXUnit%20Test%20Patterns%E3%80%8B%EF%BC%8C%E6%8A%8A%E4%BB%A5%E5%89%8D%E7%9A%84%E5%81%9A%E7%9A%84%E4%B8%9C%E8%A5%BF%E9%87%8D%E6%96%B0%E6%A2%B3%E7%90" 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%2Fwhiteboxtesting%2Frefactoring-unit-test%2F&amp;title=%E6%B5%8B%E8%AF%95%E4%BB%A3%E7%A0%81%E9%87%8D%E6%9E%84%E5%AE%9E%E4%BE%8B&amp;bodytext=Martin%20Fowler%E7%9A%84%E3%80%8A%E9%87%8D%E6%9E%84%E3%80%8B%E8%BF%99%E6%9C%AC%E4%B9%A6%E5%9F%BA%E6%9C%AC%E4%B8%8A%E6%AF%8F%E4%B8%AA%E7%A8%8B%E5%BA%8F%E5%91%98%E9%83%BD%E4%BC%9A%E7%9C%8B%EF%BC%8C%E5%AF%B9%E4%BA%8E%E5%81%9A%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E7%9A%84%E6%B5%8B%E8%AF%95%E5%B7%A5%E7%A8%8B%E5%B8%88%E6%9D%A5%E8%AF%B4%EF%BC%8C%E6%B5%8B%E8%AF%95%E7%9A%84%E4%BB%A3%E7%A0%81%E6%9C%AC%E8%BA%AB%E4%B9%9F%E6%98%AF%E7%A8%8B%E5%BA%8F%EF%BC%8C%E4%B9%9F%E9%9C%80%E8%A6%81%E9%87%8D%E6%9E%84%E3%80%82%E6%9C%80%E8%BF%91%E5%9C%A8%E7%9C%8B%E3%80%8AXUnit%20Test%20Patterns%E3%80%8B%EF%BC%8C%E6%8A%8A%E4%BB%A5%E5%89%8D%E7%9A%84%E5%81%9A%E7%9A%84%E4%B8%9C%E8%A5%BF%E9%87%8D%E6%96%B0%E6%A2%B3%E7%90" 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%2Frefactoring-unit-test%2F&amp;title=%E6%B5%8B%E8%AF%95%E4%BB%A3%E7%A0%81%E9%87%8D%E6%9E%84%E5%AE%9E%E4%BE%8B&amp;notes=Martin%20Fowler%E7%9A%84%E3%80%8A%E9%87%8D%E6%9E%84%E3%80%8B%E8%BF%99%E6%9C%AC%E4%B9%A6%E5%9F%BA%E6%9C%AC%E4%B8%8A%E6%AF%8F%E4%B8%AA%E7%A8%8B%E5%BA%8F%E5%91%98%E9%83%BD%E4%BC%9A%E7%9C%8B%EF%BC%8C%E5%AF%B9%E4%BA%8E%E5%81%9A%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E7%9A%84%E6%B5%8B%E8%AF%95%E5%B7%A5%E7%A8%8B%E5%B8%88%E6%9D%A5%E8%AF%B4%EF%BC%8C%E6%B5%8B%E8%AF%95%E7%9A%84%E4%BB%A3%E7%A0%81%E6%9C%AC%E8%BA%AB%E4%B9%9F%E6%98%AF%E7%A8%8B%E5%BA%8F%EF%BC%8C%E4%B9%9F%E9%9C%80%E8%A6%81%E9%87%8D%E6%9E%84%E3%80%82%E6%9C%80%E8%BF%91%E5%9C%A8%E7%9C%8B%E3%80%8AXUnit%20Test%20Patterns%E3%80%8B%EF%BC%8C%E6%8A%8A%E4%BB%A5%E5%89%8D%E7%9A%84%E5%81%9A%E7%9A%84%E4%B8%9C%E8%A5%BF%E9%87%8D%E6%96%B0%E6%A2%B3%E7%90" 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%2Frefactoring-unit-test%2F&amp;t=%E6%B5%8B%E8%AF%95%E4%BB%A3%E7%A0%81%E9%87%8D%E6%9E%84%E5%AE%9E%E4%BE%8B" 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%2Frefactoring-unit-test%2F&title=%E6%B5%8B%E8%AF%95%E4%BB%A3%E7%A0%81%E9%87%8D%E6%9E%84%E5%AE%9E%E4%BE%8B" 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%2Frefactoring-unit-test%2F&title=%E6%B5%8B%E8%AF%95%E4%BB%A3%E7%A0%81%E9%87%8D%E6%9E%84%E5%AE%9E%E4%BE%8B&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=%E6%B5%8B%E8%AF%95%E4%BB%A3%E7%A0%81%E9%87%8D%E6%9E%84%E5%AE%9E%E4%BE%8B&amp;link=http%3A%2F%2Fmagustest.com%2Fblog%2Fwhiteboxtesting%2Frefactoring-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%2Frefactoring-unit-test%2F&amp;title=%E6%B5%8B%E8%AF%95%E4%BB%A3%E7%A0%81%E9%87%8D%E6%9E%84%E5%AE%9E%E4%BE%8B" 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%2Frefactoring-unit-test%2F&amp;title=%E6%B5%8B%E8%AF%95%E4%BB%A3%E7%A0%81%E9%87%8D%E6%9E%84%E5%AE%9E%E4%BE%8B&amp;body=Martin%20Fowler%E7%9A%84%E3%80%8A%E9%87%8D%E6%9E%84%E3%80%8B%E8%BF%99%E6%9C%AC%E4%B9%A6%E5%9F%BA%E6%9C%AC%E4%B8%8A%E6%AF%8F%E4%B8%AA%E7%A8%8B%E5%BA%8F%E5%91%98%E9%83%BD%E4%BC%9A%E7%9C%8B%EF%BC%8C%E5%AF%B9%E4%BA%8E%E5%81%9A%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E7%9A%84%E6%B5%8B%E8%AF%95%E5%B7%A5%E7%A8%8B%E5%B8%88%E6%9D%A5%E8%AF%B4%EF%BC%8C%E6%B5%8B%E8%AF%95%E7%9A%84%E4%BB%A3%E7%A0%81%E6%9C%AC%E8%BA%AB%E4%B9%9F%E6%98%AF%E7%A8%8B%E5%BA%8F%EF%BC%8C%E4%B9%9F%E9%9C%80%E8%A6%81%E9%87%8D%E6%9E%84%E3%80%82%E6%9C%80%E8%BF%91%E5%9C%A8%E7%9C%8B%E3%80%8AXUnit%20Test%20Patterns%E3%80%8B%EF%BC%8C%E6%8A%8A%E4%BB%A5%E5%89%8D%E7%9A%84%E5%81%9A%E7%9A%84%E4%B8%9C%E8%A5%BF%E9%87%8D%E6%96%B0%E6%A2%B3%E7%90" 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=%E6%B5%8B%E8%AF%95%E4%BB%A3%E7%A0%81%E9%87%8D%E6%9E%84%E5%AE%9E%E4%BE%8B&uri=http%3A%2F%2Fmagustest.com%2Fblog%2Fwhiteboxtesting%2Frefactoring-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=%E6%B5%8B%E8%AF%95%E4%BB%A3%E7%A0%81%E9%87%8D%E6%9E%84%E5%AE%9E%E4%BE%8B%20-%20http%3A%2F%2Fmagustest.com%2Fblog%2Fwhiteboxtesting%2Frefactoring-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-pattern/' rel='bookmark' title='Permanent Link: 单元测试中的常用测试模式'>单元测试中的常用测试模式</a></li>
<li><a href='http://magustest.com/blog/whiteboxtesting/beginning-nmock/' rel='bookmark' title='Permanent Link: NMock2入门经验'>NMock2入门经验</a></li>
<li><a href='http://magustest.com/blog/automationtesting/data-driven-codedui-test/' rel='bookmark' title='Permanent Link: 实现数据驱动的CodedUI Test'>实现数据驱动的CodedUI Test</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://magustest.com/blog/whiteboxtesting/refactoring-unit-test/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>单元测试中三种准备Test Fixture的方法比较</title>
		<link>http://magustest.com/blog/whiteboxtesting/three-different-test-fixture-setup-approach/</link>
		<comments>http://magustest.com/blog/whiteboxtesting/three-different-test-fixture-setup-approach/#comments</comments>
		<pubDate>Tue, 17 Mar 2009 10:09:19 +0000</pubDate>
		<dc:creator>magus</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[白盒测试]]></category>
		<category><![CDATA[软件测试]]></category>
		<category><![CDATA[单元测试]]></category>

		<guid isPermaLink="false">http://magustest.com/blog/?p=375</guid>
		<description><![CDATA[首先说一下Test Fixture，我不知道怎么样翻译这个Test Fixture，没能搜到一个翻译的比较合适的。最让我气愤的是某人翻译的一本书中，直接把Test Fixture翻译成为测试夹具，这明显就是什么词霸词典硬翻译出来的，我强烈鄙视这样不负责任的翻译行为。 The test fixture is everything we need to have in place to exercise the SUT 我觉得这是一个对Test Fixture的一个很清晰明了的定义，就是运行被测软件所需要的一切东西，这个“东西”不单只是数据，同时还包括对被测软件的准备，例如实例化某个被测方法所在的类，准备数据库的ConnectionString等。通常来说，有三种方法来准备Test Fixture。 1. 内联方式：这种方式就是直接在测试方法中编写准备Test Fixture的代码。用这种方法的缺点是很容易造成代码的重复，出现很多复制粘贴的代码。同时，如果这个SETUP的过程比较复杂，也会降低测试代码的可读性，可维护性。另外的一个问题就是，这种方法很容易会带来测试数据Hard code的隐患。既然有那么多缺点，这种方法还有什么生命力呢？首先，可能对于初学者来说，这种方法是最简单的；其次，在一些只需要准备简单的Test Fixture的场合中，这种方法还是给编写测试的人提供了便利。 2. 委托方式：简单来说就是把Test Fixture的准备抽取为一个外部的方法，然后在需要的时候进行调用。这种方式的好处就是使得测试代码可读性更强，并且这部分的SETUP代码可以重用。而且这种做法可以屏蔽对SETUP过程的认知，使得测试人员的关注点落在真正的测试代码上面，而不是如何SETUP。 3. 隐式方式：很多xUnit框架的实现都提供了不同的隐式SETUP和TEARDOWN。例如MSTEST里面的[TestInitialize]和[TestCleanup]标签，就提供了一种隐式准备Test Fixture的支持。就是在每一个测试方法运行前，都会执行一次标有[TestInitialize]标签的方法。使用这种方法的好处就是写一次就能在各个测试中都实现了Test Fixture的准备，不用每次都显示地调用一个外部方法，不过缺点也不少： 可能会令测试比较难懂，因为这些隐式调用不是必须的，有可能会被遗漏掉。 不能使用哦本地变量来保存对象，只能用test class 里面的filed或者property 变相地使用了全局变量 在做单元测试的过程中，需要灵活地运用这三种Test Fixture的准备方法。例如在我的工作当中，我在以下情况使用到了隐式准备方式： 在某一个测试项目中，由于测试的数据不多，所以我使用了XmlSerializer，把测试的数据都放在一个XML文件中，然后利用XmlSerializer把XML中的数据映射到相应的配置类中。对于这样的情况，这些测试数据在测试运行的全过程中都需要用到，所以我选择了在测试类初始化的时候，只运行1次，来准备这些测试数据（Test Fixture的一部分）。 1 2 3 4 5 6 7 &#91;ClassInitialize&#40;&#41;&#93; public static void MyClassInitialize&#40;TestContext [...]


Related posts:<ol><li><a href='http://magustest.com/blog/net/automatic-generate-xml-instance-by-using-xsd/' rel='bookmark' title='Permanent Link: 用XSD自动生成XML对应的.NET实体类'>用XSD自动生成XML对应的.NET实体类</a></li>
<li><a href='http://magustest.com/blog/automationtesting/data-driven-codedui-test/' rel='bookmark' title='Permanent Link: 实现数据驱动的CodedUI Test'>实现数据驱动的CodedUI Test</a></li>
<li><a href='http://magustest.com/blog/net/aspnet-web-config-priority/' rel='bookmark' title='Permanent Link: ASP.NET中配置文件web.config的优先级'>ASP.NET中配置文件web.config的优先级</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>首先说一下Test Fixture，我不知道怎么样翻译这个Test Fixture，没能搜到一个翻译的比较合适的。最让我气愤的是某人翻译的一本书中，直接把Test Fixture翻译成为测试夹具，这明显就是什么词霸词典硬翻译出来的，我强烈鄙视这样不负责任的翻译行为。</p>
<p>The test fixture is everything we need to have in place to exercise the SUT</p>
<p>我觉得这是一个对Test Fixture的一个很清晰明了的定义，就是运行被测软件所需要的一切东西，这个“东西”不单只是数据，同时还包括对被测软件的准备，例如实例化某个被测方法所在的类，准备数据库的ConnectionString等。通常来说，有三种方法来准备Test Fixture。</p>
<p>1. 内联方式：这种方式就是直接在测试方法中编写准备Test Fixture的代码。用这种方法的缺点是很容易造成代码的重复，出现很多复制粘贴的代码。同时，如果这个SETUP的过程比较复杂，也会降低测试代码的可读性，可维护性。另外的一个问题就是，这种方法很容易会带来测试数据Hard code的隐患。既然有那么多缺点，这种方法还有什么生命力呢？首先，可能对于初学者来说，这种方法是最简单的；其次，在一些只需要准备简单的Test Fixture的场合中，这种方法还是给编写测试的人提供了便利。<br />
<span id="more-375"></span><br />
2. 委托方式：简单来说就是把Test Fixture的准备抽取为一个外部的方法，然后在需要的时候进行调用。这种方式的好处就是使得测试代码可读性更强，并且这部分的SETUP代码可以重用。而且这种做法可以屏蔽对SETUP过程的认知，使得测试人员的关注点落在真正的测试代码上面，而不是如何SETUP。</p>
<p>3. 隐式方式：很多xUnit框架的实现都提供了不同的隐式SETUP和TEARDOWN。例如MSTEST里面的[TestInitialize]和[TestCleanup]标签，就提供了一种隐式准备Test Fixture的支持。就是在每一个测试方法运行前，都会执行一次标有[TestInitialize]标签的方法。使用这种方法的好处就是写一次就能在各个测试中都实现了Test Fixture的准备，不用每次都显示地调用一个外部方法，不过缺点也不少：</p>
<ul>
<li>可能会令测试比较难懂，因为这些隐式调用不是必须的，有可能会被遗漏掉。</li>
<li> 不能使用哦本地变量来保存对象，只能用test class 里面的filed或者property</li>
<li> 变相地使用了全局变量</li>
</ul>
<p>在做单元测试的过程中，需要灵活地运用这三种Test Fixture的准备方法。例如在我的工作当中，我在以下情况使用到了隐式准备方式：</p>
<p>在某一个测试项目中，由于测试的数据不多，所以我使用了XmlSerializer，把测试的数据都放在一个XML文件中，然后利用XmlSerializer把XML中的数据映射到相应的配置类中。对于这样的情况，这些测试数据在测试运行的全过程中都需要用到，所以我选择了在测试类初始化的时候，只运行1次，来准备这些测试数据（Test Fixture的一部分）。</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #000000;">&#91;</span>ClassInitialize<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;">static</span> <span style="color: #0600FF;">void</span> MyClassInitialize<span style="color: #000000;">&#40;</span>TestContext testContext<span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
    XmlSerializer xmlSerializer <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> XmlSerializer<span style="color: #000000;">&#40;</span><span style="color: #008000;">typeof</span><span style="color: #000000;">&#40;</span>Config<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
    FileStream fs <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> FileStream<span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;Config.xml&quot;</span>, FileMode.<span style="color: #0000FF;">Open</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
    config <span style="color: #008000;">=</span> <span style="color: #000000;">&#40;</span>Config<span style="color: #000000;">&#41;</span>xmlSerializer.<span style="color: #0000FF;">Deserialize</span><span style="color: #000000;">&#40;</span>fs<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span></pre></td></tr></table></div>

<p>还是在同一个项目中，我想让每一个测试之间互相不要受到影响，所以我在[TestInitialize()]方法中对于一个Web Service的客户端进行初始化，保证每一次运行测试前，这个客户端都是“新”的</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #000000;">&#91;</span>TestInitialize<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> MyTestInitialize<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
   USi18nService <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> InteropWebSerivce<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
   USi18nService.<span style="color: #0000FF;">Url</span> <span style="color: #008000;">=</span> config.<span style="color: #0000FF;">USi18nAddress</span><span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span></pre></td></tr></table></div>

<p>在另外的一个项目中，需要对一个方法进行测试，该方法的功能是根据Email地址从PreSignup表里面获取相关的资料，那么首先要做的就是完成一个PreSignup的操作，才能检查这个方法。而完成PreSignup操作并不是所有的测试都需要的，所以我不选择隐式调用，而是选择委托调用，调用一个外部的帮助方法，来帮助我完成PreSignup操作；同时这个PreSignup的操作在其他一些测试中也是需要的，所以也达到了重用的效果。</p>
<p>那么在什么时候会用到内联方法来准备Test Fixture呢？其实我自己经常用这种方法，有以下一个场景，我需要对一个方法进行测试，这个方法要做的事情就是检查一个电话号码是否符合规范，那么我就会先创建一个List，然后在List里面填充了各种不同的电话号码，然后在后面用一个foreach语句把List里面的数据遍历一遍，可能这些电话号码的数据只在这一个方法里面才有用，所以我没有选择把它抽取成一个方法。</p>
<p>其实不同的单元测试框架有不同的思想，例如在NUnit里面，一个测试类的标签就是叫[Test Fixture]，其实作者的设计思想就是一个测试类，就是一套Test Fixture；如果不是一套Test Fixture，那么不要把测试方法写到一起。其实这三种方法各有所长，在我刚开始学习和尝试做单元测试的时候，我刚接触到类似[Setup][TearDown]这样的隐式调用的时候，我觉得这就是银弹，我要充分使用它。但是随着工作的深入，发现这个隐式调用会带来一些问题，然后就慢慢转用了调外部方法，或者直接内联到测试方法中。只有结合实际情况，结合的上下文来运用这些方法，才能真正提高单元测试代码的质量，减少我们的工作量。</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%2Fthree-different-test-fixture-setup-approach%2F&amp;t=%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E4%B8%AD%E4%B8%89%E7%A7%8D%E5%87%86%E5%A4%87Test%20Fixture%E7%9A%84%E6%96%B9%E6%B3%95%E6%AF%94%E8%BE%83" 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%2Fthree-different-test-fixture-setup-approach%2F&title=%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E4%B8%AD%E4%B8%89%E7%A7%8D%E5%87%86%E5%A4%87Test%20Fixture%E7%9A%84%E6%96%B9%E6%B3%95%E6%AF%94%E8%BE%83" 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%2Fthree-different-test-fixture-setup-approach%2F&title=%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E4%B8%AD%E4%B8%89%E7%A7%8D%E5%87%86%E5%A4%87Test%20Fixture%E7%9A%84%E6%96%B9%E6%B3%95%E6%AF%94%E8%BE%83&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%E4%B8%89%E7%A7%8D%E5%87%86%E5%A4%87Test%20Fixture%E7%9A%84%E6%96%B9%E6%B3%95%E6%AF%94%E8%BE%83&amp;link=http%3A%2F%2Fmagustest.com%2Fblog%2Fwhiteboxtesting%2Fthree-different-test-fixture-setup-approach%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%2Fthree-different-test-fixture-setup-approach%2F&amp;title=%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E4%B8%AD%E4%B8%89%E7%A7%8D%E5%87%86%E5%A4%87Test%20Fixture%E7%9A%84%E6%96%B9%E6%B3%95%E6%AF%94%E8%BE%83" 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%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E4%B8%AD%E4%B8%89%E7%A7%8D%E5%87%86%E5%A4%87Test%20Fixture%E7%9A%84%E6%96%B9%E6%B3%95%E6%AF%94%E8%BE%83&uri=http%3A%2F%2Fmagustest.com%2Fblog%2Fwhiteboxtesting%2Fthree-different-test-fixture-setup-approach%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%E4%B8%89%E7%A7%8D%E5%87%86%E5%A4%87Test%20Fixture%E7%9A%84%E6%96%B9%E6%B3%95%E6%AF%94%E8%BE%83%20-%20http%3A%2F%2Fmagustest.com%2Fblog%2Fwhiteboxtesting%2Fthree-different-test-fixture-setup-approach%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/net/automatic-generate-xml-instance-by-using-xsd/' rel='bookmark' title='Permanent Link: 用XSD自动生成XML对应的.NET实体类'>用XSD自动生成XML对应的.NET实体类</a></li>
<li><a href='http://magustest.com/blog/automationtesting/data-driven-codedui-test/' rel='bookmark' title='Permanent Link: 实现数据驱动的CodedUI Test'>实现数据驱动的CodedUI Test</a></li>
<li><a href='http://magustest.com/blog/net/aspnet-web-config-priority/' rel='bookmark' title='Permanent Link: ASP.NET中配置文件web.config的优先级'>ASP.NET中配置文件web.config的优先级</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://magustest.com/blog/whiteboxtesting/three-different-test-fixture-setup-approach/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>控制反转有助于提高程序的可测试性</title>
		<link>http://magustest.com/blog/whiteboxtesting/inversion-of-control-improve-testabilit/</link>
		<comments>http://magustest.com/blog/whiteboxtesting/inversion-of-control-improve-testabilit/#comments</comments>
		<pubDate>Thu, 12 Mar 2009 04:11:10 +0000</pubDate>
		<dc:creator>magus</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[白盒测试]]></category>
		<category><![CDATA[单元测试]]></category>

		<guid isPermaLink="false">http://magustest.com/blog/?p=372</guid>
		<description><![CDATA[控制反转，英文是Inversion of Control，简称IoC。这个概念在JAVA的Spring框架中比较常见，在.NET的开发中，Ioc或者其的变种依赖注入DI（Dependency Injection）是不太常见的。一般来说，类A要使用类B，类A会在其内部对类B进行控制，比较典型的做法就是在类A中创建一个类B的实例；而控制反转，就是把一个已经创建好的类B实例交给类A去控制。 例子： 有一个Member的类，他需要调用一个Web service的客户端接口，在这个类的构造函数里面，创建了一个WebServiceClientA对象。这里的WebServiceClientA类是实现了WebServiceClient接口的。 1 2 3 4 5 6 7 8 class Member &#123; WebServiceClient client; Member&#40;&#41; &#123; client = new WebServiceClientA&#40;&#34;10.60.0.11&#34;&#41;; &#125; &#125; 问题来了，对于这个类，我们怎么去测试？在构造函数里面已经初始化了一个WebServiceClientA，并且指定了这个WebServiceClientA的IP是10.60.0.11。那假如说开发环境不能连接到这台服务器上，那么怎么测试。这个问题可以通过对IP地址这个参数写到配置文件里面就能解决，其实这个跟IoC没有什么关系。 1 2 3 4 5 6 7 8 class Member &#123; WebServiceClient client; Member&#40;&#41; &#123; client = new WebServiceClientA&#40;ConfigurationManager.AppSettings&#91;&#34;ServerIP&#34;&#93;&#41;; &#125; &#125; 现在又有问题了，如果WebServiceClientA类没有完成，但是此时却要进行测试，怎么办？又假如说WebServiceClientA类是很难被创建的，怎么办？Mock也有劲使不上啊。 其实在构造函数里面是不应该有创建对象的操作，也就是尽可能不要有new操作，我们把WebServiceClient作为构造函数的一个参数，传递进去，这样程序的可测试性就有了提高，这时候可以对WebServiceClient使用Mock对象了。 1 2 3 [...]


Related posts:<ol><li><a href='http://magustest.com/blog/whiteboxtesting/introduction-to-pex-automated-white-box-testing-for-dotnet/' rel='bookmark' title='Permanent Link: PEX-.NET自动化白盒测试工具的介绍(1)'>PEX-.NET自动化白盒测试工具的介绍(1)</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>控制反转，英文是Inversion of Control，简称IoC。这个概念在JAVA的Spring框架中比较常见，在.NET的开发中，Ioc或者其的变种依赖注入DI（Dependency Injection）是不太常见的。一般来说，类A要使用类B，类A会在其内部对类B进行控制，比较典型的做法就是在类A中创建一个类B的实例；而控制反转，就是把一个已经创建好的类B实例交给类A去控制。<br />
例子：<br />
<span id="more-372"></span><br />
有一个Member的类，他需要调用一个Web service的客户端接口，在这个类的构造函数里面，创建了一个WebServiceClientA对象。这里的WebServiceClientA类是实现了WebServiceClient接口的。</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #FF0000;">class</span> Member
<span style="color: #000000;">&#123;</span>
    WebServiceClient client<span style="color: #008000;">;</span>
    Member<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
    <span style="color: #000000;">&#123;</span>
        client <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> WebServiceClientA<span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;10.60.0.11&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
    <span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span></pre></td></tr></table></div>

<p>问题来了，对于这个类，我们怎么去测试？在构造函数里面已经初始化了一个WebServiceClientA，并且指定了这个WebServiceClientA的IP是10.60.0.11。那假如说开发环境不能连接到这台服务器上，那么怎么测试。这个问题可以通过对IP地址这个参数写到配置文件里面就能解决，其实这个跟IoC没有什么关系。</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #FF0000;">class</span> Member
<span style="color: #000000;">&#123;</span>
    WebServiceClient client<span style="color: #008000;">;</span>
    Member<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
    <span style="color: #000000;">&#123;</span>
        client <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> WebServiceClientA<span style="color: #000000;">&#40;</span>ConfigurationManager.<span style="color: #0000FF;">AppSettings</span><span style="color: #000000;">&#91;</span><span style="color: #666666;">&quot;ServerIP&quot;</span><span style="color: #000000;">&#93;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
    <span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span></pre></td></tr></table></div>

<p>现在又有问题了，如果WebServiceClientA类没有完成，但是此时却要进行测试，怎么办？又假如说WebServiceClientA类是很难被创建的，怎么办？Mock也有劲使不上啊。<br />
其实在构造函数里面是不应该有创建对象的操作，也就是尽可能不要有new操作，我们把WebServiceClient作为构造函数的一个参数，传递进去，这样程序的可测试性就有了提高，这时候可以对WebServiceClient使用Mock对象了。</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #FF0000;">class</span> Member
<span style="color: #000000;">&#123;</span>
    WebServiceClient client<span style="color: #008000;">;</span>
    Member<span style="color: #000000;">&#40;</span>WebServiceClient c<span style="color: #000000;">&#41;</span>
    <span style="color: #000000;">&#123;</span>
        client <span style="color: #008000;">=</span> c<span style="color: #008000;">;</span>
    <span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span></pre></td></tr></table></div>

<p>这跟著名的好莱坞原则(Hollywood Principle)有几分相似，don&#8217;t call us, we&#8217;ll call you。你不要自己创建一个实现了WebServiceClient接口的对象，我给你传一个。</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%2Fwhiteboxtesting%2Finversion-of-control-improve-testabilit%2F&amp;title=%E6%8E%A7%E5%88%B6%E5%8F%8D%E8%BD%AC%E6%9C%89%E5%8A%A9%E4%BA%8E%E6%8F%90%E9%AB%98%E7%A8%8B%E5%BA%8F%E7%9A%84%E5%8F%AF%E6%B5%8B%E8%AF%95%E6%80%A7&amp;annotation=%E6%8E%A7%E5%88%B6%E5%8F%8D%E8%BD%AC%EF%BC%8C%E8%8B%B1%E6%96%87%E6%98%AFInversion%20of%20Control%EF%BC%8C%E7%AE%80%E7%A7%B0IoC%E3%80%82%E8%BF%99%E4%B8%AA%E6%A6%82%E5%BF%B5%E5%9C%A8JAVA%E7%9A%84Spring%E6%A1%86%E6%9E%B6%E4%B8%AD%E6%AF%94%E8%BE%83%E5%B8%B8%E8%A7%81%EF%BC%8C%E5%9C%A8.NET%E7%9A%84%E5%BC%80%E5%8F%91%E4%B8%AD%EF%BC%8CIoc%E6%88%96%E8%80%85%E5%85%B6%E7%9A%84%E5%8F%98%E7%A7%8D%E4%BE%9D%E8%B5%96%E6%B3%A8%E5%85%A5DI%EF%BC%88Dependency%20Injection%EF%BC%89%E6%98%AF%E4%B8%8D%E5%A4%AA%E5%B8%B8%E8%A7%81%E7%9A%84%E3%80%82%E4%B8%80%E8%88%AC%E6%9D%A5%E8%AF%B4%EF%BC%8C%E7%B1%BBA%E8%A6%81%E4%BD%BF%E7%94%A8%E7%B1%BBB%EF%BC%8C" 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%2Fwhiteboxtesting%2Finversion-of-control-improve-testabilit%2F&amp;title=%E6%8E%A7%E5%88%B6%E5%8F%8D%E8%BD%AC%E6%9C%89%E5%8A%A9%E4%BA%8E%E6%8F%90%E9%AB%98%E7%A8%8B%E5%BA%8F%E7%9A%84%E5%8F%AF%E6%B5%8B%E8%AF%95%E6%80%A7&amp;bodytext=%E6%8E%A7%E5%88%B6%E5%8F%8D%E8%BD%AC%EF%BC%8C%E8%8B%B1%E6%96%87%E6%98%AFInversion%20of%20Control%EF%BC%8C%E7%AE%80%E7%A7%B0IoC%E3%80%82%E8%BF%99%E4%B8%AA%E6%A6%82%E5%BF%B5%E5%9C%A8JAVA%E7%9A%84Spring%E6%A1%86%E6%9E%B6%E4%B8%AD%E6%AF%94%E8%BE%83%E5%B8%B8%E8%A7%81%EF%BC%8C%E5%9C%A8.NET%E7%9A%84%E5%BC%80%E5%8F%91%E4%B8%AD%EF%BC%8CIoc%E6%88%96%E8%80%85%E5%85%B6%E7%9A%84%E5%8F%98%E7%A7%8D%E4%BE%9D%E8%B5%96%E6%B3%A8%E5%85%A5DI%EF%BC%88Dependency%20Injection%EF%BC%89%E6%98%AF%E4%B8%8D%E5%A4%AA%E5%B8%B8%E8%A7%81%E7%9A%84%E3%80%82%E4%B8%80%E8%88%AC%E6%9D%A5%E8%AF%B4%EF%BC%8C%E7%B1%BBA%E8%A6%81%E4%BD%BF%E7%94%A8%E7%B1%BBB%EF%BC%8C" 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%2Finversion-of-control-improve-testabilit%2F&amp;title=%E6%8E%A7%E5%88%B6%E5%8F%8D%E8%BD%AC%E6%9C%89%E5%8A%A9%E4%BA%8E%E6%8F%90%E9%AB%98%E7%A8%8B%E5%BA%8F%E7%9A%84%E5%8F%AF%E6%B5%8B%E8%AF%95%E6%80%A7&amp;notes=%E6%8E%A7%E5%88%B6%E5%8F%8D%E8%BD%AC%EF%BC%8C%E8%8B%B1%E6%96%87%E6%98%AFInversion%20of%20Control%EF%BC%8C%E7%AE%80%E7%A7%B0IoC%E3%80%82%E8%BF%99%E4%B8%AA%E6%A6%82%E5%BF%B5%E5%9C%A8JAVA%E7%9A%84Spring%E6%A1%86%E6%9E%B6%E4%B8%AD%E6%AF%94%E8%BE%83%E5%B8%B8%E8%A7%81%EF%BC%8C%E5%9C%A8.NET%E7%9A%84%E5%BC%80%E5%8F%91%E4%B8%AD%EF%BC%8CIoc%E6%88%96%E8%80%85%E5%85%B6%E7%9A%84%E5%8F%98%E7%A7%8D%E4%BE%9D%E8%B5%96%E6%B3%A8%E5%85%A5DI%EF%BC%88Dependency%20Injection%EF%BC%89%E6%98%AF%E4%B8%8D%E5%A4%AA%E5%B8%B8%E8%A7%81%E7%9A%84%E3%80%82%E4%B8%80%E8%88%AC%E6%9D%A5%E8%AF%B4%EF%BC%8C%E7%B1%BBA%E8%A6%81%E4%BD%BF%E7%94%A8%E7%B1%BBB%EF%BC%8C" 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%2Finversion-of-control-improve-testabilit%2F&amp;t=%E6%8E%A7%E5%88%B6%E5%8F%8D%E8%BD%AC%E6%9C%89%E5%8A%A9%E4%BA%8E%E6%8F%90%E9%AB%98%E7%A8%8B%E5%BA%8F%E7%9A%84%E5%8F%AF%E6%B5%8B%E8%AF%95%E6%80%A7" 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%2Finversion-of-control-improve-testabilit%2F&title=%E6%8E%A7%E5%88%B6%E5%8F%8D%E8%BD%AC%E6%9C%89%E5%8A%A9%E4%BA%8E%E6%8F%90%E9%AB%98%E7%A8%8B%E5%BA%8F%E7%9A%84%E5%8F%AF%E6%B5%8B%E8%AF%95%E6%80%A7" 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%2Finversion-of-control-improve-testabilit%2F&title=%E6%8E%A7%E5%88%B6%E5%8F%8D%E8%BD%AC%E6%9C%89%E5%8A%A9%E4%BA%8E%E6%8F%90%E9%AB%98%E7%A8%8B%E5%BA%8F%E7%9A%84%E5%8F%AF%E6%B5%8B%E8%AF%95%E6%80%A7&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=%E6%8E%A7%E5%88%B6%E5%8F%8D%E8%BD%AC%E6%9C%89%E5%8A%A9%E4%BA%8E%E6%8F%90%E9%AB%98%E7%A8%8B%E5%BA%8F%E7%9A%84%E5%8F%AF%E6%B5%8B%E8%AF%95%E6%80%A7&amp;link=http%3A%2F%2Fmagustest.com%2Fblog%2Fwhiteboxtesting%2Finversion-of-control-improve-testabilit%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%2Finversion-of-control-improve-testabilit%2F&amp;title=%E6%8E%A7%E5%88%B6%E5%8F%8D%E8%BD%AC%E6%9C%89%E5%8A%A9%E4%BA%8E%E6%8F%90%E9%AB%98%E7%A8%8B%E5%BA%8F%E7%9A%84%E5%8F%AF%E6%B5%8B%E8%AF%95%E6%80%A7" 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%2Finversion-of-control-improve-testabilit%2F&amp;title=%E6%8E%A7%E5%88%B6%E5%8F%8D%E8%BD%AC%E6%9C%89%E5%8A%A9%E4%BA%8E%E6%8F%90%E9%AB%98%E7%A8%8B%E5%BA%8F%E7%9A%84%E5%8F%AF%E6%B5%8B%E8%AF%95%E6%80%A7&amp;body=%E6%8E%A7%E5%88%B6%E5%8F%8D%E8%BD%AC%EF%BC%8C%E8%8B%B1%E6%96%87%E6%98%AFInversion%20of%20Control%EF%BC%8C%E7%AE%80%E7%A7%B0IoC%E3%80%82%E8%BF%99%E4%B8%AA%E6%A6%82%E5%BF%B5%E5%9C%A8JAVA%E7%9A%84Spring%E6%A1%86%E6%9E%B6%E4%B8%AD%E6%AF%94%E8%BE%83%E5%B8%B8%E8%A7%81%EF%BC%8C%E5%9C%A8.NET%E7%9A%84%E5%BC%80%E5%8F%91%E4%B8%AD%EF%BC%8CIoc%E6%88%96%E8%80%85%E5%85%B6%E7%9A%84%E5%8F%98%E7%A7%8D%E4%BE%9D%E8%B5%96%E6%B3%A8%E5%85%A5DI%EF%BC%88Dependency%20Injection%EF%BC%89%E6%98%AF%E4%B8%8D%E5%A4%AA%E5%B8%B8%E8%A7%81%E7%9A%84%E3%80%82%E4%B8%80%E8%88%AC%E6%9D%A5%E8%AF%B4%EF%BC%8C%E7%B1%BBA%E8%A6%81%E4%BD%BF%E7%94%A8%E7%B1%BBB%EF%BC%8C" 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=%E6%8E%A7%E5%88%B6%E5%8F%8D%E8%BD%AC%E6%9C%89%E5%8A%A9%E4%BA%8E%E6%8F%90%E9%AB%98%E7%A8%8B%E5%BA%8F%E7%9A%84%E5%8F%AF%E6%B5%8B%E8%AF%95%E6%80%A7&uri=http%3A%2F%2Fmagustest.com%2Fblog%2Fwhiteboxtesting%2Finversion-of-control-improve-testabilit%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=%E6%8E%A7%E5%88%B6%E5%8F%8D%E8%BD%AC%E6%9C%89%E5%8A%A9%E4%BA%8E%E6%8F%90%E9%AB%98%E7%A8%8B%E5%BA%8F%E7%9A%84%E5%8F%AF%E6%B5%8B%E8%AF%95%E6%80%A7%20-%20http%3A%2F%2Fmagustest.com%2Fblog%2Fwhiteboxtesting%2Finversion-of-control-improve-testabilit%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/introduction-to-pex-automated-white-box-testing-for-dotnet/' rel='bookmark' title='Permanent Link: PEX-.NET自动化白盒测试工具的介绍(1)'>PEX-.NET自动化白盒测试工具的介绍(1)</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://magustest.com/blog/whiteboxtesting/inversion-of-control-improve-testabilit/feed/</wfw:commentRss>
		<slash:comments>0</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>自动化白盒测试工具PEX应用实例 &#8211; 发现ZUNE死机的BUG</title>
		<link>http://magustest.com/blog/whiteboxtesting/using-pex-in-unit-test/</link>
		<comments>http://magustest.com/blog/whiteboxtesting/using-pex-in-unit-test/#comments</comments>
		<pubDate>Sat, 10 Jan 2009 06:26:34 +0000</pubDate>
		<dc:creator>magus</dc:creator>
				<category><![CDATA[白盒测试]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[PEX]]></category>
		<category><![CDATA[单元测试]]></category>

		<guid isPermaLink="false">http://magustest.com/blog/?p=306</guid>
		<description><![CDATA[在12月的时候，我在博客里面介绍了一个自动化单元测试工具&#8211;PEX。在上一篇博客中，又讲述了微软ZUNE在闰年最后一天死机的原因。现在把这两篇文章串起来，跟大家分享一下如何用PEX帮助改善代码的质量。 首先来看一下用PEX测试ZUNE处理日期的方法的结果，如图： 大家可以复习一下被测代码： 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 while &#40;days &#62; 365&#41; &#123; if &#40;DateTime.IsLeapYear&#40;year&#41;&#41; &#123; if &#40;days &#62; 366&#41; &#123; days -= 366; year += 1; &#125; &#125; else &#123; days -= 365; year += 1; &#125; &#125; 从图中可以看到PEX总共运行了73次，产生了5个测试用例，其中2个测试用例是运行失败的，还有2个测试用例在运行过程中超出了设定的运行次数（其实这2个用例就找到了ZUNE的那个BUG）。我们分别来看看PEX生成的几个用例。第一行测试数据是days=0, year=1；这条测试数据是能够通过测试的。第二行和第三行测试数据是测试运行失败的，days是一个很大的整数，这两个测试虽然是失败的测试，但是不需要关心，因为实际中日期不可能到达那个数值，所以可以认为这是无效的测试数据。再来看最后的两条测试数据，都是超过了单个测试运行的次数，可以怀疑其中有死循环。 经过PEX初步的诊断，我们需要给PEX增加一些限制，使得生成的测试数据更加有代表性，更加有意义。 1 2 [...]


Related posts:<ol><li><a href='http://magustest.com/blog/whiteboxtesting/100-percent-statement-coverage-not-enough/' rel='bookmark' title='Permanent Link: 微软ZUNE死机原因&#8211;单元测试百分百语句覆盖率是不够的'>微软ZUNE死机原因&#8211;单元测试百分百语句覆盖率是不够的</a></li>
<li><a href='http://magustest.com/blog/whiteboxtesting/refactoring-unit-test/' rel='bookmark' title='Permanent Link: 测试代码重构实例'>测试代码重构实例</a></li>
<li><a href='http://magustest.com/blog/whiteboxtesting/unit-test-pattern/' rel='bookmark' title='Permanent Link: 单元测试中的常用测试模式'>单元测试中的常用测试模式</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>在12月的时候，我在博客里面介绍了一个<a href="http://magustest.com/blog/softwaretesting/whiteboxtesting/introduction-to-pex-automated-white-box-testing-for-dotnet/" target="_blank">自动化单元测试工具&#8211;PEX</a>。在上一篇博客中，又讲述了<a href="http://magustest.com/blog/softwaretesting/whiteboxtesting/100-percent-statement-coverage-not-enough/" target="_blank">微软ZUNE在闰年最后一天死机的原因</a>。现在把这两篇文章串起来，跟大家分享一下如何用PEX帮助改善代码的质量。</p>
<p>首先来看一下用PEX测试ZUNE处理日期的方法的结果，如图：</p>
<p><a href="http://magustest.com/blog/wp-content/uploads/2009/01/no-assumtion1.png"><img class="alignnone size-full wp-image-307" title="no-assumtion" src="http://magustest.com/blog/wp-content/uploads/2009/01/no-assumtion1.png" alt="" width="500" height="198" /></a><br />
<span id="more-306"></span><br />
大家可以复习一下被测代码：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF;">while</span> <span style="color: #000000;">&#40;</span>days <span style="color: #008000;">&gt;</span> <span style="color: #FF0000;">365</span><span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
	<span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>DateTime.<span style="color: #0000FF;">IsLeapYear</span><span style="color: #000000;">&#40;</span>year<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>
	<span style="color: #000000;">&#123;</span>
		<span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>days <span style="color: #008000;">&gt;</span> <span style="color: #FF0000;">366</span><span style="color: #000000;">&#41;</span>
		<span style="color: #000000;">&#123;</span>
			days <span style="color: #008000;">-=</span> <span style="color: #FF0000;">366</span><span style="color: #008000;">;</span>
			year <span style="color: #008000;">+=</span> <span style="color: #FF0000;">1</span><span style="color: #008000;">;</span>
		<span style="color: #000000;">&#125;</span>
	<span style="color: #000000;">&#125;</span>
	<span style="color: #0600FF;">else</span>
	<span style="color: #000000;">&#123;</span>
		days <span style="color: #008000;">-=</span> <span style="color: #FF0000;">365</span><span style="color: #008000;">;</span>
		year <span style="color: #008000;">+=</span> <span style="color: #FF0000;">1</span><span style="color: #008000;">;</span>
	<span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span></pre></td></tr></table></div>

<p>从图中可以看到PEX总共运行了73次，产生了5个测试用例，其中2个测试用例是运行失败的，还有2个测试用例在运行过程中超出了设定的运行次数（其实这2个用例就找到了ZUNE的那个BUG）。我们分别来看看PEX生成的几个用例。第一行测试数据是days=0, year=1；这条测试数据是能够通过测试的。第二行和第三行测试数据是测试运行失败的，days是一个很大的整数，这两个测试虽然是失败的测试，但是不需要关心，因为实际中日期不可能到达那个数值，所以可以认为这是无效的测试数据。再来看最后的两条测试数据，都是超过了单个测试运行的次数，可以怀疑其中有死循环。</p>
<p>经过PEX初步的诊断，我们需要给PEX增加一些限制，使得生成的测试数据更加有代表性，更加有意义。</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #000000;">&#91;</span>PexMethod<span style="color: #000000;">&#93;</span>
<span style="color: #0600FF;">public</span> <span style="color: #0600FF;">void</span> abcd<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">int</span> days, <span style="color: #FF0000;">int</span> year<span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
	PexAssume.<span style="color: #0000FF;">IsTrue</span><span style="color: #000000;">&#40;</span>days <span style="color: #008000;">&lt;</span> <span style="color: #FF0000;">367</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
	PexAssume.<span style="color: #0000FF;">IsTrue</span><span style="color: #000000;">&#40;</span>days <span style="color: #008000;">&gt;</span> <span style="color: #FF0000;">0</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
	PexAssume.<span style="color: #0000FF;">IsTrue</span><span style="color: #000000;">&#40;</span>year <span style="color: #008000;">&lt;</span> <span style="color: #FF0000;">3001</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
	PexAssume.<span style="color: #0000FF;">IsTrue</span><span style="color: #000000;">&#40;</span>year <span style="color: #008000;">&gt;</span> <span style="color: #FF0000;">0</span><span style="color: #000000;">&#41;</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></td></tr></table></div>

<p>在调用被测方法之前，是4条PexAssume语句，这4条语句可以告诉PEX，需要生成的测试数据中days是在1到369之间取值， year是在1到2999之间取值。有了这样的限制以后，PEX产生是结果会更加好，见下图：</p>
<p><a href="http://magustest.com/blog/wp-content/uploads/2009/01/pex_result1.png"><img class="alignnone size-full wp-image-311" title="pex_result" src="http://magustest.com/blog/wp-content/uploads/2009/01/pex_result1.png" alt="" width="485" height="157" /></a></p>
<p>点击最后一条测试结果，查看Details：</p>
<p><a href="http://magustest.com/blog/wp-content/uploads/2009/01/test-case-for-endless-loop1.png"><img class="alignnone size-full wp-image-312" title="test-case-for-endless-loop" src="http://magustest.com/blog/wp-content/uploads/2009/01/test-case-for-endless-loop1.png" alt="" width="499" height="246" /></a></p>
<p>我们可以看到已经生成了普通的单元测试了。这个单元测试就可以留着以后做回归测试用了。</p>
<p>把他复制到相应的CS文件中，然后删除掉Ignore属性，Description属性可要可不要。最后测试如下：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #000000;">&#91;</span>TestMethod<span style="color: #000000;">&#93;</span>
<span style="color: #0600FF;">public</span> <span style="color: #0600FF;">void</span> abcd24<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
	<span style="color: #0600FF;">this</span>.<span style="color: #0000FF;">abcd</span><span style="color: #000000;">&#40;</span><span style="color: #FF0000;">366</span>, <span style="color: #FF0000;">400</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span></pre></td></tr></table></div>

<p>PEX可以说是一个革命性的测试工具，如果有兴趣的朋友可以上<a href="http://social.msdn.microsoft.com/Forums/en-US/pex/threads/" target="_blank">MSDN论坛的PEX版块</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%2Fusing-pex-in-unit-test%2F&amp;t=%E8%87%AA%E5%8A%A8%E5%8C%96%E7%99%BD%E7%9B%92%E6%B5%8B%E8%AF%95%E5%B7%A5%E5%85%B7PEX%E5%BA%94%E7%94%A8%E5%AE%9E%E4%BE%8B%20-%20%E5%8F%91%E7%8E%B0ZUNE%E6%AD%BB%E6%9C%BA%E7%9A%84BUG" 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%2Fusing-pex-in-unit-test%2F&title=%E8%87%AA%E5%8A%A8%E5%8C%96%E7%99%BD%E7%9B%92%E6%B5%8B%E8%AF%95%E5%B7%A5%E5%85%B7PEX%E5%BA%94%E7%94%A8%E5%AE%9E%E4%BE%8B%20-%20%E5%8F%91%E7%8E%B0ZUNE%E6%AD%BB%E6%9C%BA%E7%9A%84BUG" 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%2Fusing-pex-in-unit-test%2F&title=%E8%87%AA%E5%8A%A8%E5%8C%96%E7%99%BD%E7%9B%92%E6%B5%8B%E8%AF%95%E5%B7%A5%E5%85%B7PEX%E5%BA%94%E7%94%A8%E5%AE%9E%E4%BE%8B%20-%20%E5%8F%91%E7%8E%B0ZUNE%E6%AD%BB%E6%9C%BA%E7%9A%84BUG&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%E7%99%BD%E7%9B%92%E6%B5%8B%E8%AF%95%E5%B7%A5%E5%85%B7PEX%E5%BA%94%E7%94%A8%E5%AE%9E%E4%BE%8B%20-%20%E5%8F%91%E7%8E%B0ZUNE%E6%AD%BB%E6%9C%BA%E7%9A%84BUG&amp;link=http%3A%2F%2Fmagustest.com%2Fblog%2Fwhiteboxtesting%2Fusing-pex-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%2Fusing-pex-in-unit-test%2F&amp;title=%E8%87%AA%E5%8A%A8%E5%8C%96%E7%99%BD%E7%9B%92%E6%B5%8B%E8%AF%95%E5%B7%A5%E5%85%B7PEX%E5%BA%94%E7%94%A8%E5%AE%9E%E4%BE%8B%20-%20%E5%8F%91%E7%8E%B0ZUNE%E6%AD%BB%E6%9C%BA%E7%9A%84BUG" 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=%E8%87%AA%E5%8A%A8%E5%8C%96%E7%99%BD%E7%9B%92%E6%B5%8B%E8%AF%95%E5%B7%A5%E5%85%B7PEX%E5%BA%94%E7%94%A8%E5%AE%9E%E4%BE%8B%20-%20%E5%8F%91%E7%8E%B0ZUNE%E6%AD%BB%E6%9C%BA%E7%9A%84BUG&uri=http%3A%2F%2Fmagustest.com%2Fblog%2Fwhiteboxtesting%2Fusing-pex-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=%E8%87%AA%E5%8A%A8%E5%8C%96%E7%99%BD%E7%9B%92%E6%B5%8B%E8%AF%95%E5%B7%A5%E5%85%B7PEX%E5%BA%94%E7%94%A8%E5%AE%9E%E4%BE%8B%20-%20%E5%8F%91%E7%8E%B0ZUNE%E6%AD%BB%E6%9C%BA%E7%9A%84BUG%20-%20http%3A%2F%2Fmagustest.com%2Fblog%2Fwhiteboxtesting%2Fusing-pex-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/100-percent-statement-coverage-not-enough/' rel='bookmark' title='Permanent Link: 微软ZUNE死机原因&#8211;单元测试百分百语句覆盖率是不够的'>微软ZUNE死机原因&#8211;单元测试百分百语句覆盖率是不够的</a></li>
<li><a href='http://magustest.com/blog/whiteboxtesting/refactoring-unit-test/' rel='bookmark' title='Permanent Link: 测试代码重构实例'>测试代码重构实例</a></li>
<li><a href='http://magustest.com/blog/whiteboxtesting/unit-test-pattern/' rel='bookmark' title='Permanent Link: 单元测试中的常用测试模式'>单元测试中的常用测试模式</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://magustest.com/blog/whiteboxtesting/using-pex-in-unit-test/feed/</wfw:commentRss>
		<slash:comments>1</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>在ASP.NET单元测试中进行调试</title>
		<link>http://magustest.com/blog/whiteboxtesting/how-to-debug-in-aspdotnet-unit-test/</link>
		<comments>http://magustest.com/blog/whiteboxtesting/how-to-debug-in-aspdotnet-unit-test/#comments</comments>
		<pubDate>Mon, 22 Dec 2008 13:10:07 +0000</pubDate>
		<dc:creator>magus</dc:creator>
				<category><![CDATA[白盒测试]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[单元测试]]></category>

		<guid isPermaLink="false">http://magustest.com/blog/?p=237</guid>
		<description><![CDATA[在前一篇关于在单元测试中使用HttpContext的文章中，本人提到了用ASP.NET单元测试的一个缺点是不能调试，今天我推翻我自己错误的论调，其实在ASP.NET单元测试中也是能调试的。 以前我以为ASP.NET单元测试就运行于WEB服务器上，所以我用Debug来运行，那么ASP.NET单元测试就自动Attach到Web服务器，就能调试了。但是实际上要让ASP.NET单元测试可以调试的话，正确的做法应该是： 在Web.config中，找到&#60;compilation debug=&#8221;false&#8221;/&#62;这个节点，然后把debug属性改为true 在ASP.NET单元测试代码的最开始处添加这样一句话“System.Diagnostics.Debugger.Break()” 运行该ASP.NET单元测试 在运行单元测试的时候，会有一个提示框出来，说程序遇到一个断点，是否进入调试，当然是选择调试啦。如图： 选中Debug这个程序以后，会有第二个提示框出来，让我们选择用哪个程序来进行调试，可以选择一个合适的VSTS，如图： 选上一个VSTS的实例以后，程序就会停在System.Diagnostics.Debugger.Break()这条语句上，这时候再按一下F5，让程序继续运行，当程序遇到下一个断点，就会停下来了，从此就可以调试ASP.NET的单元测试了。 Share and Enjoy: No related posts.


No related posts.]]></description>
			<content:encoded><![CDATA[<p>在前一篇关于<a href="http://magustest.com/blog/softwaretesting/using-httpcontext-in-unittest/" target="_blank">在单元测试中使用HttpContext</a>的文章中，本人提到了用ASP.NET单元测试的一个缺点是不能调试，今天我推翻我自己错误的论调，其实在ASP.NET单元测试中也是能调试的。</p>
<p>以前我以为ASP.NET单元测试就运行于WEB服务器上，所以我用Debug来运行，那么ASP.NET单元测试就自动Attach到Web服务器，就能调试了。但是实际上要让ASP.NET单元测试可以调试的话，正确的做法应该是：</p>
<ol>
<li>在Web.config中，找到&lt;compilation debug=&#8221;false&#8221;/&gt;这个节点，然后把debug属性改为true</li>
<li>在ASP.NET单元测试代码的最开始处添加这样一句话“System.Diagnostics.Debugger.Break()”</li>
<li>运行该ASP.NET单元测试</li>
</ol>
<p>在运行单元测试的时候，会有一个提示框出来，说程序遇到一个断点，是否进入调试，当然是选择调试啦。如图：<br />
<span id="more-237"></span><br />
<a href="http://magustest.com/blog/wp-content/uploads/2008/12/asddotnet-unit-test-prompt1.png"><img class="alignnone size-full wp-image-240" title="asddotnet-unit-test-prompt" src="http://magustest.com/blog/wp-content/uploads/2008/12/asddotnet-unit-test-prompt1.png" alt="" width="500" height="295" /></a></p>
<p>选中Debug这个程序以后，会有第二个提示框出来，让我们选择用哪个程序来进行调试，可以选择一个合适的VSTS，如图：</p>
<p><a href="http://magustest.com/blog/wp-content/uploads/2008/12/asddotnet-unit-test-select-vsts1.png"><img class="alignnone size-full wp-image-241" title="asddotnet-unit-test-select-vsts" src="http://magustest.com/blog/wp-content/uploads/2008/12/asddotnet-unit-test-select-vsts1.png" alt="" width="408" height="441" /></a></p>
<p>选上一个VSTS的实例以后，程序就会停在System.Diagnostics.Debugger.Break()这条语句上，这时候再按一下F5，让程序继续运行，当程序遇到下一个断点，就会停下来了，从此就可以调试ASP.NET的单元测试了。</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%2Fhow-to-debug-in-aspdotnet-unit-test%2F&amp;title=%E5%9C%A8ASP.NET%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E4%B8%AD%E8%BF%9B%E8%A1%8C%E8%B0%83%E8%AF%95&amp;bodytext=%E5%9C%A8%E5%89%8D%E4%B8%80%E7%AF%87%E5%85%B3%E4%BA%8E%E5%9C%A8%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E4%B8%AD%E4%BD%BF%E7%94%A8HttpContext%E7%9A%84%E6%96%87%E7%AB%A0%E4%B8%AD%EF%BC%8C%E6%9C%AC%E4%BA%BA%E6%8F%90%E5%88%B0%E4%BA%86%E7%94%A8ASP.NET%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E7%9A%84%E4%B8%80%E4%B8%AA%E7%BC%BA%E7%82%B9%E6%98%AF%E4%B8%8D%E8%83%BD%E8%B0%83%E8%AF%95%EF%BC%8C%E4%BB%8A%E5%A4%A9%E6%88%91%E6%8E%A8%E7%BF%BB%E6%88%91%E8%87%AA%E5%B7%B1%E9%94%99%E8%AF%AF%E7%9A%84%E8%AE%BA%E8%B0%83%EF%BC%8C%E5%85%B6%E5%AE%9E%E5%9C%A8ASP.NET%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E4%B8%AD%E4%B9%9F%E6%98%AF%E8%83%BD%E8%B0%83%E8%AF%95%E7%9A%84%E3%80%82%0A%0A%E4%BB%A5%E5%89%8D%E6%88%91%E4%BB%A5%E4%B8%BAA" 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%2Fhow-to-debug-in-aspdotnet-unit-test%2F&amp;title=%E5%9C%A8ASP.NET%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E4%B8%AD%E8%BF%9B%E8%A1%8C%E8%B0%83%E8%AF%95&amp;notes=%E5%9C%A8%E5%89%8D%E4%B8%80%E7%AF%87%E5%85%B3%E4%BA%8E%E5%9C%A8%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E4%B8%AD%E4%BD%BF%E7%94%A8HttpContext%E7%9A%84%E6%96%87%E7%AB%A0%E4%B8%AD%EF%BC%8C%E6%9C%AC%E4%BA%BA%E6%8F%90%E5%88%B0%E4%BA%86%E7%94%A8ASP.NET%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E7%9A%84%E4%B8%80%E4%B8%AA%E7%BC%BA%E7%82%B9%E6%98%AF%E4%B8%8D%E8%83%BD%E8%B0%83%E8%AF%95%EF%BC%8C%E4%BB%8A%E5%A4%A9%E6%88%91%E6%8E%A8%E7%BF%BB%E6%88%91%E8%87%AA%E5%B7%B1%E9%94%99%E8%AF%AF%E7%9A%84%E8%AE%BA%E8%B0%83%EF%BC%8C%E5%85%B6%E5%AE%9E%E5%9C%A8ASP.NET%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E4%B8%AD%E4%B9%9F%E6%98%AF%E8%83%BD%E8%B0%83%E8%AF%95%E7%9A%84%E3%80%82%0A%0A%E4%BB%A5%E5%89%8D%E6%88%91%E4%BB%A5%E4%B8%BAA" 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%2Fhow-to-debug-in-aspdotnet-unit-test%2F&amp;t=%E5%9C%A8ASP.NET%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E4%B8%AD%E8%BF%9B%E8%A1%8C%E8%B0%83%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%2Fwhiteboxtesting%2Fhow-to-debug-in-aspdotnet-unit-test%2F&title=%E5%9C%A8ASP.NET%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E4%B8%AD%E8%BF%9B%E8%A1%8C%E8%B0%83%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%2Fwhiteboxtesting%2Fhow-to-debug-in-aspdotnet-unit-test%2F&title=%E5%9C%A8ASP.NET%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E4%B8%AD%E8%BF%9B%E8%A1%8C%E8%B0%83%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=%E5%9C%A8ASP.NET%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E4%B8%AD%E8%BF%9B%E8%A1%8C%E8%B0%83%E8%AF%95&amp;link=http%3A%2F%2Fmagustest.com%2Fblog%2Fwhiteboxtesting%2Fhow-to-debug-in-aspdotnet-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%2Fhow-to-debug-in-aspdotnet-unit-test%2F&amp;title=%E5%9C%A8ASP.NET%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E4%B8%AD%E8%BF%9B%E8%A1%8C%E8%B0%83%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%2Fwhiteboxtesting%2Fhow-to-debug-in-aspdotnet-unit-test%2F&amp;title=%E5%9C%A8ASP.NET%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E4%B8%AD%E8%BF%9B%E8%A1%8C%E8%B0%83%E8%AF%95&amp;body=%E5%9C%A8%E5%89%8D%E4%B8%80%E7%AF%87%E5%85%B3%E4%BA%8E%E5%9C%A8%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E4%B8%AD%E4%BD%BF%E7%94%A8HttpContext%E7%9A%84%E6%96%87%E7%AB%A0%E4%B8%AD%EF%BC%8C%E6%9C%AC%E4%BA%BA%E6%8F%90%E5%88%B0%E4%BA%86%E7%94%A8ASP.NET%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E7%9A%84%E4%B8%80%E4%B8%AA%E7%BC%BA%E7%82%B9%E6%98%AF%E4%B8%8D%E8%83%BD%E8%B0%83%E8%AF%95%EF%BC%8C%E4%BB%8A%E5%A4%A9%E6%88%91%E6%8E%A8%E7%BF%BB%E6%88%91%E8%87%AA%E5%B7%B1%E9%94%99%E8%AF%AF%E7%9A%84%E8%AE%BA%E8%B0%83%EF%BC%8C%E5%85%B6%E5%AE%9E%E5%9C%A8ASP.NET%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E4%B8%AD%E4%B9%9F%E6%98%AF%E8%83%BD%E8%B0%83%E8%AF%95%E7%9A%84%E3%80%82%0A%0A%E4%BB%A5%E5%89%8D%E6%88%91%E4%BB%A5%E4%B8%BAA" 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%9C%A8ASP.NET%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E4%B8%AD%E8%BF%9B%E8%A1%8C%E8%B0%83%E8%AF%95&uri=http%3A%2F%2Fmagustest.com%2Fblog%2Fwhiteboxtesting%2Fhow-to-debug-in-aspdotnet-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%9C%A8ASP.NET%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E4%B8%AD%E8%BF%9B%E8%A1%8C%E8%B0%83%E8%AF%95%20-%20http%3A%2F%2Fmagustest.com%2Fblog%2Fwhiteboxtesting%2Fhow-to-debug-in-aspdotnet-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>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://magustest.com/blog/whiteboxtesting/how-to-debug-in-aspdotnet-unit-test/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
