<?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>Elegant Code &#187; Testing/QA</title>
	<atom:link href="http://elegantcode.com/tag/testingqa/feed/" rel="self" type="application/rss+xml" />
	<link>http://elegantcode.com</link>
	<description></description>
	<lastBuildDate>Sun, 12 Feb 2012 04:40:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.5</generator>
		<item>
		<title>Report on STPcon</title>
		<link>http://elegantcode.com/2008/05/06/report-on-stpcon/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=report-on-stpcon</link>
		<comments>http://elegantcode.com/2008/05/06/report-on-stpcon/#comments</comments>
		<pubDate>Wed, 07 May 2008 03:18:36 +0000</pubDate>
		<dc:creator>Scott Schimanski</dc:creator>
				<category><![CDATA[Esoterica]]></category>
		<category><![CDATA[Testing/QA]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2008/05/06/report-on-stpcon/</guid>
		<description><![CDATA[Recently I attended STPcon, Software Test and Performance Convention, put on by BZ Media.  It was held at the Marriott in San Mateo CA, not far from the San Francisco airport. The first day was a session on Rapid Testing presented by Michael Bolton (no, not that Michael Bolton).  It was a shortened version of [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I attended <a href="http://www.stpcon.com/">STPcon</a>, Software Test and Performance Convention, put on by BZ Media.  It was held at the Marriott in San Mateo CA, not far from the San Francisco airport.</p>
<p>The first day was a session on Rapid Testing presented by <a href="http://www.developsense.com/">Michael Bolton</a> (no, not that Michael Bolton).  It was a shortened version of a three day session he usually presents.  It was a fantastic presentation.  Michael is a great speaker and great teacher.  I have been reading his articles in various magazines for a few years now.  It was great to see him in person and learn from him.  He talked about rapid testing techniques, new ways to look at exploratory testing and how to find the highest risk defects fast.</p>
<p>The keynote speech was from <a href="http://www.amibug.com/whoweare.asp">Rob Sabourin</a> on testing in an scrum environment.  Like Michael, I have read many of his articles as well.  He is a dynamic (shall we say animated?) speaker.  He has a wealth of experience in software testing and is willing to share.  As an added bonus, I got to ride with him on the shuttle to the hotel and from the hotel back to the airport.  I greatly enjoyed the conversation.  Thank you for sharing Rob.</p>
<p>There were some other great speakers there as well including <a href="http://xndev.blogspot.com/">Matt Heusser</a> and <a href="http://www.happytester.com/pages/675478/index.htm">Hans Buwalda</a>.  They also set up plenty of time during the conference for networking.</p>
<p>It was a terrific conference.  I have been to general software development conferences before  but this is the first one specific to software testing.  Software testing seems like a relatively unknown portion of software engineering.  Sure, there are lots of articles on test cases and test plans.  But really looking at what software testing entails, what a good tester does when hunting that elusive bug, what separates the average tester from the great tester is a vast field ripe for exploration.  This conference renewed my excitement to join in the discovery.</p>
]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2008/05/06/report-on-stpcon/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Thanks to BDD</title>
		<link>http://elegantcode.com/2008/05/01/thanks-to-bdd/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=thanks-to-bdd</link>
		<comments>http://elegantcode.com/2008/05/01/thanks-to-bdd/#comments</comments>
		<pubDate>Thu, 01 May 2008 18:49:48 +0000</pubDate>
		<dc:creator>Alex Mueller</dc:creator>
				<category><![CDATA[Architecture and Design]]></category>
		<category><![CDATA[BDD]]></category>
		<category><![CDATA[Testing/QA]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2008/05/01/thanks-to-bdd/</guid>
		<description><![CDATA[I have been doing code reviews frequently this past week and have been remarking on the naming conventions of test methods. In a effort to try and find the rules of BDD naming conventions, I came across Dan North&#8217;s introduction to BDD, which is a great starting point, and a blog post by David Laribee [...]]]></description>
			<content:encoded><![CDATA[<p>I have been doing code reviews frequently this past week and have been remarking on the naming conventions of test methods. In a effort to try and find the rules of BDD naming conventions, I came across <a title="Dan North&#39;s introduction to BDD" href="http://dannorth.net/introducing-bdd" target="_blank">Dan North&#8217;s introduction to BDD</a>, which is a great starting point, and a blog post by <a title="David Laribee" href="http://codebetter.com/blogs/david_laribee/archive/2007/12/17/approaching-bdd.aspx" target="_blank">David Laribee</a> that has made a good impression on me. You can read up on BDD to learn more, this post will not go into detail about it. </p>
<p>From what I gathered from David Laribee&#8217;s <a title="article" href="http://codebetter.com/blogs/david_laribee/archive/2007/12/17/approaching-bdd.aspx" target="_blank">article</a>, I like this. I REALLY like this. </p>
<p><img src="http://codebetter.com/blogs/david_laribee/WindowsLiveWriter/ApproachingBDD_AED1/resharper-specs_3.jpg" /> </p>
<p>By changing namespace, class, and method names, the behavior of each spec (test) is clearly revealed. In a larger suite of tests, if there are failures, I can more easily see what is failing and what trends, if any, are resulting in my failures. Before, I would name my test method names to describe a behavior, &quot;Some concept should do this when given that.&quot; Getting the namespace and class name involved provides a more legible test result. </p>
<p>While reviewing a test case for a peer, I took this approach and arrived at the following scenario. I am changing the names of the methods to hide details. The original test method was &quot;FilterToEndPointTestReport.&quot; Making this more readable, using my previous approach, we arrived at &quot;FilterShouldUpdateStatusOnReportWhenDefaultFilterValueIsChanged.&quot; Great, that is better, but&#8230;</p>
<p>Applying the approach described in David&#8217;s post, I now have this.</p>
<div style="border-right: gray 1px solid; padding-right: 4px; padding-left: 4px; font-size: 8pt; border-top: gray 1px solid; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &#39;Courier New&#39;, courier, monospace; background-color: #f4f4f4">
<div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   1:</span> <span style="color: #0000ff">namespace</span> Specs_for_Filters</pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   2:</span> {</pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   3:</span>   <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> When_default_filter_value_is_changed : FilterTestFixture</pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   4:</span>   {</pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   5:</span>     [Test]</pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   6:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> Endpoint_should_be_updated_on_report {}</pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   7:</span>     </pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   8:</span>     [Test]</pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   9:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> Endpoint_should_be_updated_on_grid {}</pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  10:</span>     </pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  11:</span>     [Test]</pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  12:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> Endpoint_should_be_updated_on_chart {}</pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  13:</span>   }</pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  14:</span>   </pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  15:</span>   <span style="color: #0000ff">public</span> <span style="color: #0000ff">abstract</span> <span style="color: #0000ff">class</span> FilterTestFixture</pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  16:</span>   {</pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  17:</span>     <span style="color: #008000">// provide common functionality that will be used </span></pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  18:</span>     <span style="color: #008000">// among behavior-driven filter test classes.</span></pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  19:</span>   }</pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  20:</span> }</pre>
</p></div>
</div>
<p>When my tests run, their resulting output is more legible. This approach helps me to think about my tests in terms of behavior rather than implementation. In my opinion, my test cases are now more abstract and more succinct. </p>
]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2008/05/01/thanks-to-bdd/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Removing Duplicate Code in Functions</title>
		<link>http://elegantcode.com/2008/04/08/removing-duplicate-code-in-functions/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=removing-duplicate-code-in-functions</link>
		<comments>http://elegantcode.com/2008/04/08/removing-duplicate-code-in-functions/#comments</comments>
		<pubDate>Wed, 09 Apr 2008 04:06:40 +0000</pubDate>
		<dc:creator>Alex Mueller</dc:creator>
				<category><![CDATA[Architecture and Design]]></category>
		<category><![CDATA[Testing/QA]]></category>
		<category><![CDATA[Tools and Utilities]]></category>
		<category><![CDATA[Unit Testing]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2008/04/08/removing-duplicate-code-in-functions/</guid>
		<description><![CDATA[Duplicate code to me is wrong. Writing duplicate code to me is like using poor grammar. If I am unaware of it, I am none the wiser. However, if I knowingly use poor grammar or duplicate code, I feel bad. After seeing too many duplications across methods in one or more classes, I decided to [...]]]></description>
			<content:encoded><![CDATA[<p>Duplicate code to me is wrong. Writing duplicate code to me is like using poor grammar. If I am unaware of it, I am none the wiser. However, if I knowingly use poor grammar or duplicate code, I feel bad.</p>
<p>After seeing too many duplications across methods in one or more classes, I decided to investigate a way to remove these. I am always looking to remove duplicate code, even code that shares similarities, I look to refator. Removing duplications is important to adapt more easily to change. When a code change is required, we should only have to make it in one place. The following article will show two relatively simple means to address this code smell, delegates and an Aspect-Oriented approach.</p>
<p>The example I am using in this article is seen below. It is a unit test class, StackFixture class, and it is extremely trivial. This is a typical unit test taken from <a target="_blank" href="http://www.amazon.com/Test-Driven-Development-Microsoft-NET-Professional/dp/0735619484/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1207679353&amp;sr=8-1" title="Test-Driven Development in Microsoft .NET">Test-Driven Development in Microsoft .NET</a>. I have added the logging functionality as an easy means to show how these types of DRY violations can occur. While the duplications in this example deal with logging, they could pertain to other, more complex, functionality as well. The approaches to removing duplications across methods in this article can work with these simple scenarios, as well as more complex ones.</p>
<p>Take for example this sample test case. Each test method logs a message before and after executing the test logic. This violates DRY. We want to keep our test logic in our method, but factor out the duplicate logging. Again, if we were not logging, but doing some repetitive logic, we could factor that out as well.</p>
<p style="font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border: gray 1px solid; padding: 4px">
<p style="font-size: 8pt; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   1:</span> [TestFixture]</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   2:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> StackFixture : AbstractBaseFixture</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   3:</span> {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   4:</span>     <span style="color: #0000ff">private</span> Stack stack;</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   5:</span> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   6:</span>     [SetUp]</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   7:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> SetUp()</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   8:</span>     {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   9:</span>         stack = <span style="color: #0000ff">new</span> Stack();</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  10:</span>     }</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  11:</span> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  12:</span>     [Test]</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  13:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> Empty()</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  14:</span>     {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  15:</span>         Log.Info(<span style="color: #006080">"Starting Empty test"</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  16:</span></pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  17:</span>         Assert.IsTrue(stack.IsEmpty);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  18:</span></pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  19:</span>         Log.Info(<span style="color: #006080">"Ending Empty test"</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  20:</span>     }</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  21:</span> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  22:</span>     [Test]</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  23:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> PushOne()</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  24:</span>     {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  25:</span>         Log.Info(<span style="color: #006080">"Starting PushOne test"</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  26:</span> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  27:</span>         stack.Push(<span style="color: #006080">"first element"</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  28:</span>         Assert.IsFalse(stack.IsEmpty, <span style="color: #006080">"After Push, IsEmpty should be false."</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  29:</span> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  30:</span>         Log.Info(<span style="color: #006080">"Ending PushOne test"</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  31:</span>     }</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  32:</span> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  33:</span>     [Test]</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  34:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> Pop()</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  35:</span>     {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  36:</span>         Log.Info(<span style="color: #006080">"Starting Pop test"</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  37:</span> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  38:</span>         stack.Push(<span style="color: #006080">"first element"</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  39:</span>         stack.Pop();</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  40:</span>         Assert.IsTrue(stack.IsEmpty, <span style="color: #006080">"After Push - Pop, IsEmpty should be true."</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  41:</span> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  42:</span>         Log.Info(<span style="color: #006080">"Ending Pop test"</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  43:</span>     }</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  44:</span> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  45:</span>     [Test]</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  46:</span>     [ExpectedException(<span style="color: #0000ff">typeof</span>(InvalidOperationException))]</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  47:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> PopEmptyStack()</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  48:</span>     {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  49:</span>         Log.Info(<span style="color: #006080">"Starting PopEmptyStack test"</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  50:</span> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  51:</span>         stack.Pop();</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  52:</span> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  53:</span>         Log.Info(<span style="color: #006080">"Ending PopEmptyStack test"</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  54:</span>     }</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  55:</span> }</pre>
<p><strong>Remove Duplications with Delegates</strong></p>
<p>Quite simply, we can remove our method duplications using a delegate, in this case, the <a target="_blank" href="http://msdn2.microsoft.com/en-us/library/system.action.aspx" title="System.Action delegate">System.Action delegate</a>. Thanks to <a target="_blank" href="http://www.ayende.com/" title="Ayende">Ayende</a> for helping me understand this option. We create a method, TestMethod (as shown below), and add it to our StackFixture class. The method takes two strings (string beforeMessage and string afterMessage) and the Action delegate, representing the test method logic. We will call this method within our test cases.</p>
<p style="font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border: gray 1px solid; padding: 4px">
<p style="font-size: 8pt; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   1:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> TestMethod(<span style="color: #0000ff">string</span> beforeMessage, <span style="color: #0000ff">string</span> afterMessage, Action action)</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   2:</span> {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   3:</span>     <span style="color: #008000">// before</span></pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   4:</span>     Log.Info(beforeMessage);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   5:</span></pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   6:</span>     <span style="color: #008000">// invoke our method</span></pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   7:</span>     action();</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   8:</span></pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   9:</span>     <span style="color: #008000">// after</span></pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  10:</span>     Log.Info(afterMessage);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  11:</span> }</pre>
<p>Then, in our tests, we replace the following test method&#8230;</p>
<p style="font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border: gray 1px solid; padding: 4px">
<p style="font-size: 8pt; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   1:</span> [Test]</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   2:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> Pop()</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   3:</span> {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   4:</span>     Log.Info(<span style="color: #006080">"Starting Pop test"</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   5:</span> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   6:</span>     stack.Push(<span style="color: #006080">"first element"</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   7:</span>     stack.Pop();</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   8:</span>     Assert.IsTrue(stack.IsEmpty, <span style="color: #006080">"After Push - Pop, IsEmpty should be true."</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   9:</span> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  10:</span>     Log.Info(<span style="color: #006080">"Ending Pop test"</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  11:</span> }</pre>
<p>With the same method using our delegate approach.</p>
<p style="font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border: gray 1px solid; padding: 4px">
<p style="font-size: 8pt; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   1:</span> [Test]</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   2:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> Pop()</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   3:</span> {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   4:</span>     TestMethod(<span style="color: #006080">"Starting Pop test"</span>, <span style="color: #006080">"Ending Pop test"</span>,</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   5:</span>                <span style="color: #0000ff">delegate</span></pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   6:</span>                    {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   7:</span>                        stack.Push(<span style="color: #006080">"first element"</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   8:</span>                        stack.Pop();</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   9:</span>                        Assert.IsTrue(stack.IsEmpty, <span style="color: #006080">"After Push - Pop, IsEmpty should be true."</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  10:</span>                    });</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  11:</span> }</pre>
<p>We can replace each of our test methods with the same TestMethod using the <a target="_blank" href="http://msdn2.microsoft.com/en-us/library/system.action.aspx" title="System.Action delegate">System.Action delegate</a>. It will then easy to omit our before and after strings replacing them with &#8220;action.Method.Name,&#8221; or some other intelligent logic to determine what to log.</p>
<p>This approach works well, but delegates are often difficult to understand. If this solution suits your needs, make sure the implementation is easily maintainable. What is nice about this approach is how simple it is. There is no need to reference any assemblies outside of the .Net framework, i.e. no third party dependencies.</p>
<p><strong>The Aspect-Oriented Approach</strong></p>
<p><a target="_blank" href="http://en.wikipedia.org/wiki/Aspect-oriented_programming" title="Aspect-Oriented Programming">Aspect-Oriented Programming</a> (AOP) is an entirely different animal. It certainly deserves more than just a blog post. Please read more about it online. This article will not explain the details of AOP.</p>
<p>If you are reading this, welcome back. I will assume you are now familiar with AOP. There are several options for AOP frameworks. Some frameworks I have used are <a target="_blank" href="http://www.springframework.net/" title="Spring.net">Spring.net</a>, <a target="_blank" href="http://www.castleproject.org/" title="Castle Project">Castle Project</a>, and <a target="_blank" href="http://www.postsharp.org/" title="PostSharp">PostSharp</a>. The former two provide IoC capabilities as well. I suggest using a well-supported framework, one with community support and frequent updates. Investigate for yourself, there are several nice options available.</p>
<p><strong>AOP with Castle DynamicProxy</strong></p>
<p><a target="_blank" href="http://hammett.castleproject.org/" title="Hamilton Verissimo">Hamilton Verissimo</a> put together a good <a target="_blank" href="http://www.codeproject.com/KB/cs/hamiltondynamicproxy.aspx" title="sample using Castle's DynamicProxy">sample using Castle&#8217;s DynamicProxy</a>. It is a nice, clean implementation.This worked fine for me and would work well in other situations. However, in my scenario, if I were to use this approach, I needed to have each of my test classes extend from MarshalByRef. In addition, I would need to modify the underlying NUnit framework to create my proxies in order to provide advice. Since I could not do the latter, or did not want to investigate, I searched for other AOP options.</p>
<p>The DynamicProxy aproach to solving your AOP needs is a great option. It just did not work in my situation, only because NUnit executes each of my methods. I would need to somehow intercept the creation of my test class, create a proxy of it, and execute the test methods on it.</p>
<p><strong>AOP with PostSharp</strong></p>
<p><a target="_blank" href="http://www.postsharp.org" title="Gael Fraiteur's PostSharp">Gael Fraiteur&#8217;s PostSharp</a> is a great option for AOP needs. It is extremely clean and easy to use. It is the simplest AOP framework I have used. I suggest watching Gael&#8217;s <a target="_blank" href="http://www.postsharp.org/about/video/" title="video tutorial">video tutorial</a>.</p>
<p>The first thing I needed to do, besides downloading and installing PostSharp, is to add two references to my project, PostSharp.Laos and PostSharp.Public. After that, I create a simple class extending OnMethodInvocationAspect, called LoggingMethodInvocationAspect.</p>
<p style="font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border: gray 1px solid; padding: 4px">
<p style="font-size: 8pt; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   1:</span> [Serializable]</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   2:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">sealed</span> <span style="color: #0000ff">class</span> LoggingMethodInvocationAspect : OnMethodInvocationAspect</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   3:</span> {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   4:</span>     <span style="color: #0000ff">private</span> ILogger log;</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   5:</span> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   6:</span>     <span style="color: #0000ff">public</span> LoggingMethodInvocationAspect(ILogger logger)</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   7:</span>     {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   8:</span>         log = logger;</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   9:</span>     {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  10:</span> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  11:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">override</span> <span style="color: #0000ff">void</span> OnInvocation(MethodInvocationEventArgs eventArgs)</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  12:</span>     {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  13:</span>         <span style="color: #008000">// before</span></pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  14:</span>         log.Info(<span style="color: #006080">"OnInvocation Before proceed"</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  15:</span> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  16:</span>         <span style="color: #008000">// invoke</span></pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  17:</span>         eventArgs.Proceed();</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  18:</span> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  19:</span>         <span style="color: #008000">// after</span></pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  20:</span>         log.Info(<span style="color: #006080">"OnInvocation After proceed"</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  21:</span>     }</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  22:</span> }</pre>
<p>At this point, all we need to do is apply our aspect on target methods. The &#8220;AttributeTargetMembers&#8221; attribute can use wildcards. This tells the AOP framework to only intercept those methods in the &#8220;MathService&#8221; class that start with &#8220;Test.&#8221; Below is the sample where I specify the target assembly, target type (class or classes to intercept), and target methods to intercept. There are many features beyond what I am showing so do further investigation.</p>
<p style="font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border: gray 1px solid; padding: 4px">
<p style="font-size: 8pt; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   1:</span> [assembly: ClassLibrary.SampleInterfaces.LoggingMethodInvocationAspect(</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   2:</span>     AttributeTargetAssemblies = <span style="color: #006080">"ClassLibrary.UnitTesting.Sandbox"</span>,</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   3:</span>     AttributeTargetTypes = <span style="color: #006080">"ClassLibrary.UnitTesting.Sandbox.MathService"</span>,</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   4:</span>     AttributeTargetMembers = <span style="color: #006080">"Test*"</span>)]</pre>
<p>Finally, my StackFixture class now looks something like this. Notice that the duplicate logging logic is now removed and each test method is prefixed with &#8220;Test&#8221; in the method name. This is so that PostSharp can filter what methods to intercept.</p>
<p style="font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border: gray 1px solid; padding: 4px">
<p style="font-size: 8pt; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   1:</span> [assembly: ClassLibrary.SampleInterfaces.LoggingMethodInvocationAspect(</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   2:</span>   AttributeTargetAssemblies = <span style="color: #006080">"ClassLibrary.UnitTesting.Sandbox"</span>,</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   3:</span>   AttributeTargetTypes = <span style="color: #006080">"ClassLibrary.UnitTesting.Sandbox.MathService"</span>,</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   4:</span>   AttributeTargetMembers = <span style="color: #006080">"Test*"</span>)]</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   5:</span></pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   6:</span> [TestFixture]</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   7:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> StackFixture</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   8:</span> {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   9:</span>     <span style="color: #0000ff">private</span> Stack stack;</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  10:</span> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  11:</span>     [SetUp]</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  12:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> SetUp()</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  13:</span>     {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  14:</span>         stack = <span style="color: #0000ff">new</span> Stack();</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  15:</span>     }</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  16:</span> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  17:</span>     [TearDown]</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  18:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> TearDown(){}</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  19:</span> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  20:</span>     [Test]</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  21:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> TestEmpty()</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  22:</span>     {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  23:</span>         Assert.IsTrue(stack.IsEmpty);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  24:</span>     }</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  25:</span> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  26:</span>     [Test]</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  27:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> TestPushOne()</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  28:</span>     {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  29:</span>         stack.Push(<span style="color: #006080">"first element"</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  30:</span>         Assert.IsFalse(stack.IsEmpty, <span style="color: #006080">"After Push, IsEmpty should be false."</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  31:</span>     }</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  32:</span> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  33:</span>     [Test]</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  34:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> TestPop()</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  35:</span>     {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  36:</span>         stack.Push(<span style="color: #006080">"first element"</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  37:</span>         stack.Pop();</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  38:</span>         Assert.IsTrue(stack.IsEmpty, <span style="color: #006080">"After Push - Pop, IsEmpty should be true."</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  39:</span>     }</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  40:</span> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  41:</span>     [Test]</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  42:</span>     [ExpectedException(<span style="color: #0000ff">typeof</span>(InvalidOperationException))]</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  43:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> TestPopEmptyStack()</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  44:</span>     {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  45:</span>         stack.Pop();</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  46:</span>     }</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  47:</span> }</pre>
<p>The end result, a StackFixture test class with duplicate logging logic removed. The PostSharp AOP framework post-processes the compiled assembly and inserts itself, easily providing points of interception.</p>
<p>The PostSharp approach does involve a third-party dependency, but I feel like it is cleaner than the delegate approach. Gael informed me future versions of PostSharp will provide a more configurable solution than adding the [assembly ...] reference for the aspects, perhaps an XML configuration option. This can be done today, but involves some work.</p>
<p>Whether you use delegates, AOP, or some other approach, remove duplicate code wherever possible. I am happy to use either approach in my projects. There are tradeoffs to either solution, so investigate for yourself.</p>
]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2008/04/08/removing-duplicate-code-in-functions/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Mocking nested methods</title>
		<link>http://elegantcode.com/2008/04/07/mocking-nested-methods/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mocking-nested-methods</link>
		<comments>http://elegantcode.com/2008/04/07/mocking-nested-methods/#comments</comments>
		<pubDate>Tue, 08 Apr 2008 02:16:09 +0000</pubDate>
		<dc:creator>Chris Brandsma</dc:creator>
				<category><![CDATA[Mock Objects]]></category>
		<category><![CDATA[TDD]]></category>
		<category><![CDATA[Testing/QA]]></category>
		<category><![CDATA[Unit Testing]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2008/04/07/mocking-nested-methods/</guid>
		<description><![CDATA[I am writing this as a way to document something that is possible, but you probably shouldn&#8217;t do unless you really need to.&#160; Also, I&#8217;m sure this is not new, I just can&#8217;t find any mention of it on Google right now.&#160; Which probably means it is a bad idea.&#160; After all, if the Internet, [...]]]></description>
			<content:encoded><![CDATA[<p>I am writing this as a way to document something that is possible, but you probably shouldn&#8217;t do unless you really need to.&nbsp; Also, I&#8217;m sure this is not new, I just can&#8217;t find any mention of it on Google right now.&nbsp; Which probably means it is a bad idea.&nbsp; After all, if the Internet, the keeper of all that is right and true, doesn&#8217;t know about something it must be wrong.</p>
<h2>The problem</h2>
<p>You have two methods (Foo and Bar), and Foo calls method Bar.&nbsp; It will look like this:</p>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">int</span> Foo()
{
    <span class="rem">// stuff happens here</span>
    <span class="kwrd">int</span> i = Bar();
    <span class="rem">// do more stuff here</span>&nbsp;&nbsp;&nbsp; return i + 5}

<span class="kwrd">public</span> <span class="kwrd">int</span> Bar()
{
   <span class="rem">// do some logic</span>
   <span class="kwrd">return</span> 1;
}</pre>
<p>Now you need to test both methods.&nbsp; Bar can be easily tested like this (this should work for NUnit and MBUnit tests &#8212; assuming both methods exist in a class call MyClass):</p>
<pre class="csharpcode">[Test]
<span class="kwrd">public</span> <span class="kwrd">void</span> Bar_Test()
{
    MyClass c = <span class="kwrd">new</span> MyClass();
   <span class="kwrd">int</span> result = c.Bar();
   Assert.AreEqual(1, result);
}</pre>
<p>Now we test Foo:</p>
<pre class="csharpcode">[Test]
<span class="kwrd">public</span> <span class="kwrd">void</span> Foo_Test()
{
   MyClass c = <span class="kwrd">new</span> MyClass();
   <span class="kwrd">int</span> result = c.Foo();
   Assert.AreEqual(6, result);
}</pre>
<p>Here is where we have an issue.&nbsp; What if the result of Bar changes?&nbsp; That will break the test.&nbsp; So now we have a brittle test.&nbsp; Any time Bar changes, we have to change all of the Bar tests, but also the Foo tests, so we have added complexity to our tests as well.&nbsp; Now if Foo (or Bar) was in a separate class, this wouldn&#8217;t be an issue, but they are in the same class.&nbsp; And as much as I like small classes, this seems too trivial to split up (even in the context of an extremely trivial example). </p>
<h2>The Solution</h2>
<p>What I would like to do is Mock the method Bar.&nbsp; You can do that with a delegate.</p>
<p>Without really getting into what a delegate is, I will just show the code.&nbsp; So here are my two methods, with a delegate added in for good measure.</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">delegate</span> <span class="kwrd">int</span> BarDelegate();

<span class="kwrd">public</span> BarDelegate Bar;

<span class="kwrd">public</span> MyClass()
{
    Bar = BarInternal;
}

<span class="kwrd">public</span> <span class="kwrd">int</span> Foo()
{
    <span class="rem">// stuff happens here</span>
    <span class="kwrd">int</span> i = Bar();
    <span class="rem">// do more stuff here    </span>
    <span class="kwrd">return</span> i + 5;
}

<span class="kwrd">public</span> <span class="kwrd">int</span> BarInternal()
{
   <span class="rem">// do some logic</span>
   <span class="kwrd">return</span> 1;
}</pre>
<p>OK, here is what I did:</p>
<ol>
<li>Renamed Bar to BarInternal
<li>BarDelegate delegate
<li>Created a variable named Bar to point to the method BarInternal
<li>Created a constructor to hook up Bar to BarInternal.</li>
</ol>
<p>Now all of my code can still use the method Bar just like it was there, but in actuality it is calling BarInternal.&nbsp; I have now created one layer of indirection to my method Bar so it can now be mocked and tested.</p>
<p>Here is my new test for Foo:</p>
<pre class="csharpcode">[Test]
<span class="kwrd">public</span> <span class="kwrd">void</span> FooTest()
{
    MyClass c = <span class="kwrd">new</span> MyClass()
    c.Bar = BarMethodForTest;
    <span class="kwrd">int</span> result = target.Foo();
    Assert.AreEqual(7, result);
}

<span class="kwrd">private</span> <span class="kwrd">int</span> BarMethodForTest()
{
    <span class="kwrd">return</span> 2;
}</pre>
<p>So what is new with the test is the BarMethodForTest that is passed to c.Bar and I have coded BarMethodForTest to always return 2.&nbsp; When I set c.Bar to my new method, BarInternal (the default method) is no longer called.</p>
<p>Actually, if I wanted to I could simplify this further by setting c.Bar with an anonymous delegate like this:</p>
<pre class="csharpcode">[Test]
<span class="kwrd">public</span> <span class="kwrd">void</span> FooTest()
{
    MyClass c = <span class="kwrd">new</span> MyClass()
    c.Bar = <span class="kwrd">delegate</span>() { <span class="kwrd">return</span> 2; }
    <span class="kwrd">int</span> result = target.Foo();
    Assert.AreEqual(7, result);
}</pre>
<h2>Stepping Back</h2>
<p>OK, take a step back and look at this again with a critical eye.&nbsp; Have I really solved the problem?&nbsp;&nbsp; Yes and no.&nbsp; The real problem was that my methods were too complex to simply test.&nbsp; Now my methods are simple to test, but the code is complex to read.&nbsp; All I&#8217;ve done is shifted the complexity from one class to the other.&nbsp; A better solution would to have created another class and further abstracted out the logic.</p>
<p>At the same time, my class is not overly burdened by the change either.&nbsp; In lieu of a real refactoring, I do consider this a viable solution to the problem.&nbsp; So by all means do this &#8212; but make sure you are out of alternatives first.</p>
]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2008/04/07/mocking-nested-methods/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Getting started in performance testing</title>
		<link>http://elegantcode.com/2008/03/16/getting-started-in-performance-testing/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=getting-started-in-performance-testing</link>
		<comments>http://elegantcode.com/2008/03/16/getting-started-in-performance-testing/#comments</comments>
		<pubDate>Sun, 16 Mar 2008 20:47:22 +0000</pubDate>
		<dc:creator>Scott Schimanski</dc:creator>
				<category><![CDATA[Testing/QA]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2008/03/16/getting-started-in-performance-testing/</guid>
		<description><![CDATA[Over that past nine months or so, I have been learning the art performance testing. There is certainly lot more to it then mearly taking a load tool, pounding your web site with a couple hundred (or more) super users and waiting for the crash. There is planning what to test and what type of tests [...]]]></description>
			<content:encoded><![CDATA[<p>Over that past nine months or so, I have been learning the art performance testing. There is certainly lot more to it then mearly taking a load tool, pounding your web site with a couple hundred (or more) super users and waiting for the crash. There is planning what to test and what type of tests you need, determine usage habits, learning what tools are out there and how to use them e<font face="Times New Roman">ffectively</font> as well as understanding how to analyize all that data. And that&#8217;s just the tip of the iceberg.  I am still a newbie as there is a lot to learn. However, here are my suggestions for getting started.</p>
<p>Read anything by you can get your hands on written by Scott Barber (<a href="http://www.perftestplus.com/scott_blog.php">http://www.perftestplus.com/scott_blog.php</a>). Start with this one:</p>
<p><strong>Performance Testing Guidance for Web Applications <a href="http://msdn2.%20microsoft.%20com/en-us/%20library/bb924375%20.aspx"><u><font color="#0000ff">http://msdn2. microsoft. com/en-us/ library/bb924375 .aspx</font></u></a>. It is a Microsoft document written by Scott Barber and others that gives a great overview of the process of performance testing. It is not technical and is not tool specific. It gives you an idea of the steps involved and things to plan for in your performance testing efforts.</p>
<p></strong>Next, read this one:</p>
<p><strong>User experience, not metrics <a href="http://www.ibm.%20com/developerwor%20ks/rational/%20library/4228.%20html"><u><font color="#0000ff">http://www.ibm. com/developerwor ks/rational/ library/4228. html</font></u></a> It goes deeper into performance testing. It is written around the IBM Rational toolset, however you can use the information against any performance toolset.</p>
<p></strong>Then go to this one:</p>
<p><strong>Beyond performance testing <a href="http://www.ibm.%20com/developerwor%20ks/rational/%20library/4169.%20html"><u><font color="#0000ff">http://www.ibm. com/developerwor ks/rational/ library/4169. html</font></u></a></p>
<p></strong>For books, I would recommend <strong>Performance Testing Microsoft .NET Web Applications</strong> by the Microsoft ACE team, especially if you are testing products developed using Microsoft tools. It is written around the older performance testing tools from Microsoft, but there is lots of good info.  There seem to be a couple other performance testing books out there, but I have not read them. As I do, I&#8217;ll post book reports.  A good book on statistics can hurt either. <img src='http://elegantcode.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Can anyone out there in the blogosphere comment on books you have read related to performance testing?</p>
<p>For tools, I would recommend playing around with the freely available tools out there.   For example:</p>
<p>Apache JMeter: <a href="http://jakarta.apache.org/jmeter/"><u><font color="#0000ff">http://jakarta. apache.org/ jmeter/</font></u></a></p>
<p>Radview Webload: <a href="http://www.webload.org/"><u><font color="#0000ff">http://www.webload. org/</font></u></a></p>
<p>The Grinder: <a href="http://grinder.%20sourceforge.%20net/"><u><font color="#0000ff">http://grinder. sourceforge. net/</font></u></a></p>
<p>OpenSTA: <a href="http://opensta.org/">http://opensta.org/</a></p>
<p>Also look at the pay-for tools. You may not use them, but get to know the products, what they do and how they do it. Some examples:</p>
<p>Borland Silk: <a href="http://www.borland.com/us/products/silk/silkperformer/index.html"><u><font color="#0000ff">http://www.borland. com/us/products/ silk/silkperform er/index. html</font></u></a></p>
<p>HP (Mecury) LoadRunner: <a href="https://h10078.www1.hp.com/cda/hpms/display/main/hpms_content.jsp?zn=bto&amp;cp=1-11-126-17%5E8_4000_100"><u><font color="#0000ff">https://h10078. www1.hp.com/ cda/hpms/ display/main/ hpms_content. jsp?zn=bto&amp;cp=1-11-126- 17%5E8_4000_ 100</font></u></a>__</p>
<p>Empirix ELoad: <a href="http://www.empirix.com/index.asp"><u><font color="#0000ff">http://www.empirix. com/index. asp</font></u></a></p>
<p>IBM Rational Performance Tester: <a href="http://www-306.ibm.com/software/awdtools/tester/performance/"><u><font color="#0000ff">http://www-306. ibm.com/software /awdtools/ tester/performan ce/</font></u></a></p>
<p>Microsoft Visual Studio Team Systems Testers Edition: <a href="http://msdn2.microsoft.com/en-us/vsts2008/products/bb933754.aspx"><u><font color="#0000ff">http://msdn2. microsoft. com/en-us/ vsts2008/ products/ bb933754. aspx</font></u></a></p>
<p>Happy testing,</p>
<p>Scott</p>
]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2008/03/16/getting-started-in-performance-testing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Tests are the Requirements</title>
		<link>http://elegantcode.com/2008/02/05/the-tests-are-the-requirements/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=the-tests-are-the-requirements</link>
		<comments>http://elegantcode.com/2008/02/05/the-tests-are-the-requirements/#comments</comments>
		<pubDate>Wed, 06 Feb 2008 01:56:30 +0000</pubDate>
		<dc:creator>David Starr</dc:creator>
				<category><![CDATA[TDD]]></category>
		<category><![CDATA[Testing/QA]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2008/02/05/the-tests-are-the-requirements/</guid>
		<description><![CDATA[I get an amazing amount of pushback to this idea which I see as a perfectly natural chain of logical deduction. Let&#8217;s try it, shall we? Specifications are typically written before code as instructions for what the code SHOULD do. Tests, (written before or after the code), are a set of instructions detailing what the [...]]]></description>
			<content:encoded><![CDATA[<p>I get an amazing amount of pushback to this idea which I see as a perfectly natural chain of logical deduction. Let&#8217;s try it, shall we?</p>
<ol>
<li>Specifications are typically written before code as instructions for what the code SHOULD do.</li>
<li>Tests, (written before or after the code), are a set of instructions detailing what the code MUST do. If we can&#8217;t pass the tests, then we cant release the product.</li>
<li>Specifications have no enforcement mechanism beyond human beings.</li>
<li>Tests may be automated and the enforcement of them may be as well. Without passing a suite of regression tests, for example, the software under test (SUT) may not be deployed to the drop point on a network.</li>
</ol>
<p>Tests act as a gate keeper. Regardless of how few or poor our tests are, they serve to ensure the software meets the specifications. This is why we refer to passing a test as PASSING. Passing a test means that we can get beyond it. Functional requirements written in a document have no such enforcement ability.</p>
<p>Ideally, tests are an expression of the functional requirements such that we have a validation tool for the functional requirements. If this is true, are not tests the functional requirements in an executable form?</p>
<p>This is why tools like <a target="_blank" href="http://fitnesse.org">Fitnesse</a> exist. Can we as developers accomplish the same level of testing with a Unit Testing framework? You bet, but the frameworks don&#8217;t typically provide the nice syntax and user experience business users need to create the tests. This is exactly what Fitnesse strives to provide, a way for business users to specify requirements in an automat-able form.</p>
<h2>Some Other Observations</h2>
<ul>
<li>Tests, while ideally written before code, still rarely are. Most tests are written after the code is written. These tests include regression tests, acceptance tests, unit tests, etc. All kinds of tests are at play here.</li>
<li>A MS Word document can&#8217;t break the build.</li>
</ul>
<p>If these things are all true, then how can we possibly consider the tests anything BUT the functional requirements. They may not have that label at the top of the page, but tests fundamentally define acceptance of the system.</p>
<p>I just don&#8217;t understand how this doesn&#8217;t compute for some folks.</p>
]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2008/02/05/the-tests-are-the-requirements/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>TeamCity Tryout</title>
		<link>http://elegantcode.com/2008/01/30/teamcity-tryout/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=teamcity-tryout</link>
		<comments>http://elegantcode.com/2008/01/30/teamcity-tryout/#comments</comments>
		<pubDate>Thu, 31 Jan 2008 03:25:40 +0000</pubDate>
		<dc:creator>Chris Brandsma</dc:creator>
				<category><![CDATA[TDD]]></category>
		<category><![CDATA[Testing/QA]]></category>
		<category><![CDATA[Tools and Utilities]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2008/01/30/teamcity-tryout/</guid>
		<description><![CDATA[I&#8217;m doing a gig for a local company (a non-software company) that is trying to build a development team.&#160; My job is two-fold: 1. help them get some software up and started so they have something to build on, 2. train their current staff (consisting of one developer) on good patterns and practices for software [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m doing a gig for a local company (a non-software company) that is trying to build a development team.&nbsp; My job is two-fold: 1. help them get some software up and started so they have something to build on, 2. train their current staff (consisting of one developer) on good patterns and practices for software development.&nbsp; </p>
<p>The project is interesting and the people are pleasant, not a bad gig at all.&nbsp; So far I&#8217;m manage to put source control in place (SubVersion via the <a href="http://www.visualsvn.com/server/">VisualSVN Server</a> &#8212; they really have the best install around for windows), they are getting on board with TDD, I&#8217;m slowly working in User Stories into their process (by osmosis really), and I decided to try to go the extra mile and get a bit of Continuous Integration going.</p>
<p>In the past I would have hit up <a href="http://cruisecontrol.sourceforge.net/">CruiseControl</a>, struggled for a few days, swore, kicked a couple of dogs, and then get everything working.&nbsp; This time I thought I might be able to spare the dog by trying <a href="http://www.jetbrains.com/teamcity/">TeamCity</a> from <a href="http://www.jetbrains.com/">JetBrains</a>.&nbsp; Result, the dog got an extra treat this week.&nbsp; </p>
<p>I got the entire friggen process up and working in about three hours.&nbsp; And that was on the first try!&nbsp;&nbsp; Most of that time was spend fixing dependency issue in the projects (which were my fault, not TeamCity&#8217;s &#8212; that is why you want one of these things after all).&nbsp; </p>
<p>The first process I set up was to create a test build.&nbsp; The test build did these things: </p>
<ol>
<li>Monitor Subversion to changes in my project, if there are changes, downloaded them and proceed to step 2.&nbsp; Otherwise: repeat step 1.</li>
<li>Compile all the source.&nbsp; I chose to build the project from the solution file.&nbsp; If this were an internal project I might use a Nant script, but considering the client I just stuck with the solution file.</li>
<li>Run all unit tests. Report any failures.</li>
<li>Let me know all is well.</li>
</ol>
<p>For #4, I had to log onto the TeamCity web site (created by the install), and install the client task tray application (similar to CC.Tray for CruiseControl really).&nbsp; The only annoyance with any of the tools is that the TeamCity tray application doesn&#8217;t make any noise, and it isn&#8217;t very configurable (like CCTray is).</p>
<p>But, for an extra bonus step I set up a second build to recreated the test web site on command.&nbsp; This second build took 30 minutes.&nbsp; The TeamCity&#8217;s configuration web site has an option to copy an existing build.&nbsp; I made a few modifications and I was good to go.&nbsp;&nbsp; The two modifications were: change the build directory, and no to monitor subversion for changes.&nbsp; I want this build to be kicked off manually.</p>
<p>So now, the only part of the process that is not automated is the move to production.&nbsp; I have to make web.config changes for that (meaning I have to do some custom msbuild work to swap connection strings).&nbsp; But all in all I am very happy with where things are at considering the amount of time spent.</p>
<p>CruiseControl might be more configurable and have a better tool set, and for a different project on a different team, I might go down that road again.&nbsp; But for an inexperienced team, or for a project with non-demanding build requirements, TeamCity is an excellent tool. </p>
<p>I am officially a TeamCity convert. </p>
]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2008/01/30/teamcity-tryout/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Rhino Mocks presentation &#8211; version 3.3</title>
		<link>http://elegantcode.com/2008/01/28/rhino-mocks-presentation-version-33/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=rhino-mocks-presentation-version-33</link>
		<comments>http://elegantcode.com/2008/01/28/rhino-mocks-presentation-version-33/#comments</comments>
		<pubDate>Tue, 29 Jan 2008 04:17:50 +0000</pubDate>
		<dc:creator>Chris Brandsma</dc:creator>
				<category><![CDATA[Mock Objects]]></category>
		<category><![CDATA[TDD]]></category>
		<category><![CDATA[Testing/QA]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2008/01/28/rhino-mocks-presentation-version-33/</guid>
		<description><![CDATA[There has been some interest (two people) in updating my Rhino Mocks presentation and re-publishing it. This is from a presentation that I gave for the West Michigan Day of .Net back in May 2007 (ages ago). This presentation consists of a Power Point deck with minimal slides (it was for a code camp) and [...]]]></description>
			<content:encoded><![CDATA[<p>There has been some interest (two people) in updating my Rhino Mocks presentation and re-publishing it. This is from a presentation that I gave for the West Michigan Day of .Net back in May 2007 (ages ago).</p>
<p>This presentation consists of a Power Point deck with minimal slides (it was for a code camp) and a sample project written MVP style (WinForms &#8211; not web forms).&nbsp; That is where the meat of the presentation was, the slide deck is just there to give a taste of what mock objects are supposed to do.</p>
<p>Anyway, the big change was that I updated the sample projects mocking code to Rhino Mocks 3.3 syntax.&nbsp; This uses the Record and Playback methods now.&nbsp; But I did leave one test method using the old syntax for comparison sake.</p>
<p>For all of the tests to run you will have to download and install the <a href="http://www.codeplex.com/MSFTDBProdSamples">Adventure Works LT database from CodePlex</a>.</p>
<p><a href="http://www.chrisbrandsma.com/RhinoMockDemo.zip">Download the presentation here.</a></p>
<p>Enjoy.</p>
]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2008/01/28/rhino-mocks-presentation-version-33/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Rhino Mocks With Code Coverage</title>
		<link>http://elegantcode.com/2007/11/29/rhino-mocks-with-code-coverage/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=rhino-mocks-with-code-coverage</link>
		<comments>http://elegantcode.com/2007/11/29/rhino-mocks-with-code-coverage/#comments</comments>
		<pubDate>Fri, 30 Nov 2007 04:27:16 +0000</pubDate>
		<dc:creator>David Starr</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[TDD]]></category>
		<category><![CDATA[Testing/QA]]></category>
		<category><![CDATA[Visual Studio]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2007/11/29/rhino-mocks-with-code-coverage/</guid>
		<description><![CDATA[So there I am coding along with Unit Testing awesomeness and I decide I want to to try the VS2008 code coverage tool. A quick visit to Test &#62; Edit Test Run Configurations &#62; Local Test Run to turn on code coverage on my product assembly and I am in the money, or so I [...]]]></description>
			<content:encoded><![CDATA[<p>So there I am coding along with Unit Testing awesomeness and I decide I want to to try the VS2008 code coverage tool. A quick visit to<br />
Test &gt; Edit Test Run Configurations &gt; Local Test Run<br />
to turn on code coverage on my product assembly and I am in the money, or so I think. When I try to run my tests I get this little number:</p>
<p><a href="http://elegantcode.com/wp-content/uploads/2007/11/image14.png"><img border="0" width="348" src="http://elegantcode.com/wp-content/uploads/2007/11/image-thumb14.png" alt="image" height="293" style="border: 0px" /></a></p>
<p>Clicking on the <u>Test run error</u> link reveals the following error.</p>
<blockquote><p>Failed to queue test run &#8216;starr@TEXAS 2007-11-29 21:13:48&#8242;: Test Run deployment issue: The location of the file or directory &#8216;c:\projects\bowlingkata\bowlingscorelib_test\bin\debug\Rhino.Mocks.dll&#8217; is not trusted.</p></blockquote>
<p>The code coverage tool wants to be able to run in full trust mode. Makes sense, actually. So what&#8217;s the quickest way to patch this up an keep moving? Since Rhino.Mocks.dll is strongly named and signed and all, this turns out to be the easiest thing to do for me:</p>
<p><a href="http://elegantcode.com/wp-content/uploads/2007/11/image15.png"><img border="0" width="353" src="http://elegantcode.com/wp-content/uploads/2007/11/image-thumb15.png" alt="image" height="73" style="border: 0px" /></a></p>
<p>I am running my Unit Tests with Code Coverage turned on in my test configuration and Rhino Mocks is helping me increase code coverage. What is it, you ask?</p>
<p><a href="http://elegantcode.com/wp-content/uploads/2007/11/image16.png"><img border="0" width="452" src="http://elegantcode.com/wp-content/uploads/2007/11/image-thumb16.png" alt="image" height="97" style="border: 0px" /></a></p>
<p style="display: inline; margin: 0px; padding: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:58c5d8e9-19a4-4f50-a79b-0be9ea27d8f3" class="wlWriterSmartContent">Technorati Tags: <a rel="tag" href="http://technorati.com/tags/Rhino%20Mocks">Rhino Mocks</a>,<a rel="tag" href="http://technorati.com/tags/TDD">TDD</a>,<a rel="tag" href="http://technorati.com/tags/Visual%20Studio">Visual Studio</a></p>
]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2007/11/29/rhino-mocks-with-code-coverage/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Tracking down an unhandled exception</title>
		<link>http://elegantcode.com/2007/11/19/tracking-down-an-unhandled-exception/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tracking-down-an-unhandled-exception</link>
		<comments>http://elegantcode.com/2007/11/19/tracking-down-an-unhandled-exception/#comments</comments>
		<pubDate>Tue, 20 Nov 2007 05:58:10 +0000</pubDate>
		<dc:creator>Alex Mueller</dc:creator>
				<category><![CDATA[Testing/QA]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2007/11/19/tracking-down-an-unhandled-exception/</guid>
		<description><![CDATA[Recently I was tracking down an unwanted error that has been recycling my application pool. One app pool recycling is one too many for me. The error details were useless, but a quick search put me on the right path. The error was the following. EventType clr20r3, P1 w3wp.exe, P2 6.0.3790.1830, P3 42435be1, P4 mscorlib, [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I was tracking down an unwanted error that has been recycling my application pool. One app pool recycling is one too many for me. The error details were useless, but a quick search put me on the right path. The error was the following.</p>
<blockquote><p>EventType clr20r3, P1 w3wp.exe, P2 6.0.3790.1830, P3 42435be1, P4 mscorlib, P5 2.0.0.0, P6 4333ab80, P7 bd0, P8 59, P9 system.nullreferenceexception, P10 NIL.</p></blockquote>
<p>Searching for an error this cryptic reassured me that I need to take measures to improve the details of my error handling. As a result, I immediately created two HttpHandlers to deal with unhandled exceptions such as this one, and one for more generic error handling. By logging more detailed information, I can better detect the error and fix it. This is nothing new, but definitely important. A good article on reporting unhandled exceptions can be found here, <a target="_blank" href="http://www.eggheadcafe.com/articles/20060305.asp" title="ASP.NET 2.0 Unhandled Exception Issues">ASP.NET 2.0 Unhandled Exception Issues</a>.</p>
<p>After implementing this solution, my error reared its ugly head again, and a detailed error log was recorded. Perfect! As I am reading the detailed error message and stack trace, I am finding myself even more confused. Nothing in the stack trace could be found in my code. After another internet search, I found one dedicated thread specifically for this error. The error details are below.</p>
<blockquote><p>System.NullReferenceException: Object reference not set to an instance of an object.<br />
    at System.Web.SessionState.SessionStateModule.PollLockedSessionCallback(Object state)<br />
    at System.Threading._TimerCallback.TimerCallback_Context(Object state)<br />
    at System.Threading.ExecutionContext.runTryCode(Object userData)<br />
    at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)<br />
    at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)<br />
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)<br />
    at System.Threading._TimerCallback.PerformTimerCallback(Object state)</p></blockquote>
<p>   <br />
Closing the chapter on this error, the only thread I found with details on this can be found here, <a target="_blank" href="http://forums.asp.net/p/1132396/1857198.aspx#1857198" title="Null Reference Exception in SessionStateModule">Null Reference Exception in SessionStateModule</a>. The fix turned out to be a Microsoft hotfix that I had to install on my servers that basically updated the aspnet_wp.exe, System.Web.dll, and webengine.dll. With the fix in place, so far so good &#8211; no signs of the error after three weeks of peak usage.</p>
<p><strong>Lessons Learned</strong></p>
<p>Errors that occur outside of the main application context will cause the application pool to be recycled in ASP.NET 2.0 by default. While this default can be disabled, it is a better approach to throw more detailed information about each error. Using the unhandled exception HttpModule will help isolate errors that originate on threads outside of the application’s context. When catching errors, provide as much detailed information as possible to give yourself a fighting chance.</p>
]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2007/11/19/tracking-down-an-unhandled-exception/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

