<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Blair Conrad</title>
	<atom:link href="http://blairconrad.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://blairconrad.wordpress.com</link>
	<description>one and one and one is three</description>
	<lastBuildDate>Wed, 21 Dec 2011 14:04:48 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='blairconrad.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://1.gravatar.com/blavatar/b5fdd86d3396405b7329eacc47beca2a?s=96&#038;d=http%3A%2F%2Fs2.wp.com%2Fi%2Fbuttonw-com.png</url>
		<title>Blair Conrad</title>
		<link>http://blairconrad.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://blairconrad.wordpress.com/osd.xml" title="Blair Conrad" />
	<atom:link rel='hub' href='http://blairconrad.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Best all-around .NET coverage tool &#8211; OpenCover</title>
		<link>http://blairconrad.wordpress.com/2011/12/15/best-all-around-net-coverage-tool-opencover/</link>
		<comments>http://blairconrad.wordpress.com/2011/12/15/best-all-around-net-coverage-tool-opencover/#comments</comments>
		<pubDate>Thu, 15 Dec 2011 15:23:49 +0000</pubDate>
		<dc:creator>Blair Conrad</dc:creator>
				<category><![CDATA[Testing]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[Coverage]]></category>
		<category><![CDATA[OpenCover]]></category>

		<guid isPermaLink="false">http://blairconrad.wordpress.com/?p=1268</guid>
		<description><![CDATA[This post is the conclusion of a series chronicling my search for a .NET coverage tool. This is the gala awards show, where my chosen coverage tool is announced. If you&#8217;ve come this far, you&#8217;ve probably already read the title, and it won&#8217;t surprise you to learn that I&#8217;ve chosen OpenCover. It offered the best [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blairconrad.wordpress.com&amp;blog=11276730&amp;post=1268&amp;subd=blairconrad&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<div style="padding-left:.5em;padding-right:.5em;margin-left:2em;margin-right:2em;border:1px solid #EEE;background-color:#f8f8f8;">This post is the conclusion of a series chronicling my <a href="/2011/07/18/can-you-cover-me-looking-for-a-net-coverage-tool/">search for a .NET coverage tool</a>.</div>
<p>This is the gala awards show, where my chosen coverage tool is announced. </p>
<p>If you&#8217;ve come this far, you&#8217;ve probably already read the title, and it won&#8217;t surprise you to learn that I&#8217;ve chosen <a href="https://github.com/sawilde/opencover">OpenCover</a>. It offered the best fit for my requirements &#8211; the only areas where I found it lacking were in the &#8220;nice to haves&#8221;. Witness:</p>
<ul>
<li>OpenCover is pretty easy to <strong>run from the command line</strong> &#8211; second only to NCover.</li>
<li>It can (with the help of ReportGenerator) generated <strong>coverage reports in XML and HTML</strong>.</li>
<li>OpenCover has an integrated <strong>auto-deploy</strong>, so it can be bundled with the source tree and new developers or build servers just work &#8211; dotCover has no such option, and I was not able to use NCover this way.</li>
<li>I&#8217;ve been able to <strong>link with TypeMock Isolator</strong> with little trouble, and the new Isolator may obviate the need for my small workaround.</li>
<li><strong>It&#8217;s free</strong>. Aside from the obvious benefit, it&#8217;s nice to not have to count licenses when adding developers and/or build server nodes.</li>
<li>There&#8217;s <b>no GUI integration</b>, but this was a nice to have. If some developer is absolutely dying to have this, my boss&#8217;s boss has indicated that money could be available for individual licenses of something like dotCover.</li>
<li>There&#8217;s <b>no support for integrating with IIS</b>. We don&#8217;t need this right now, so that&#8217;s okay. Again, if we one or two developers find a need, we have the option of buying a license of some other tool. Even better, support <a href="https://github.com/sawilde/opencover/issues/36">may be coming soon</a>.</li>
</ul>
<p>After considering OpenCover&#8217;s strengths in the areas I absolutely needed, and its weaknesses, which all appear to be in areas that I care a little less about, I recommended it the boss&#8217;s boss, who was agreed with the assessment and was happy to keep a little money in his pocket for now.</p>
<p>So, I grabbed 2.0.802, incorporated it into one product&#8217;s build, and out popped coverage numbers. Very exciting. I did notice a few things, though:</p>
<ol>
<li>Branch coverage has been added since I last evaluated the product!</li>
<li>One fairly complicated integration-style testfixture is not runnable under OpenCover &#8211; the class tested creates a background thread and starting the thread results in a <code>System.AccessViolationException</code>. I was unable to determine the cause of this, and have temporarily removed the test from coverage, instead executing it with NUnit directly. I&#8217;m going to continue investigating this problem.</li>
<li>Since I&#8217;m XCopy deploying, I was bitten by <a href="https://github.com/sawilde/opencover/issues/52">the dependency on the  Microsoft Visual C++ 2010 Redistributable Package</a> &#8211; I ended up including the DLLs in my imported bundle, and all was well, but I worry a little about the stability of this solution.</li>
<li>The time taken to execute our tests (there are over 5000, and many hit a database) increased from about 7 minutes to about 8. This is an acceptable degradation, since the test run isn&#8217;t the bottleneck in our build process.</li>
<li>The number of &#8220;Cannot instrument  as no PDB could be loaded&#8221; messages is daunting. I&#8217;m hoping that things will be improved once I get a build that contains a fix for <a href="https://github.com/sawilde/opencover/issues/40">issue 40</a>.</li>
</ol>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/blairconrad.wordpress.com/1268/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/blairconrad.wordpress.com/1268/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/blairconrad.wordpress.com/1268/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/blairconrad.wordpress.com/1268/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/blairconrad.wordpress.com/1268/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/blairconrad.wordpress.com/1268/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/blairconrad.wordpress.com/1268/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/blairconrad.wordpress.com/1268/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/blairconrad.wordpress.com/1268/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/blairconrad.wordpress.com/1268/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/blairconrad.wordpress.com/1268/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/blairconrad.wordpress.com/1268/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/blairconrad.wordpress.com/1268/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/blairconrad.wordpress.com/1268/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blairconrad.wordpress.com&amp;blog=11276730&amp;post=1268&amp;subd=blairconrad&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blairconrad.wordpress.com/2011/12/15/best-all-around-net-coverage-tool-opencover/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<georss:point>43.465187 -80.522372</georss:point>
		<geo:lat>43.465187</geo:lat>
		<geo:long>-80.522372</geo:long>
		<media:content url="http://1.gravatar.com/avatar/707860a1ae9745187b83023e2655e03c?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">blairconrad</media:title>
		</media:content>
	</item>
		<item>
		<title>Hasty Impressions: NCover</title>
		<link>http://blairconrad.wordpress.com/2011/11/09/hasty-impressions-ncover/</link>
		<comments>http://blairconrad.wordpress.com/2011/11/09/hasty-impressions-ncover/#comments</comments>
		<pubDate>Wed, 09 Nov 2011 13:00:20 +0000</pubDate>
		<dc:creator>Blair Conrad</dc:creator>
				<category><![CDATA[Testing]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[Coverage]]></category>
		<category><![CDATA[HastyImpressions]]></category>
		<category><![CDATA[IIS]]></category>
		<category><![CDATA[Isolator]]></category>
		<category><![CDATA[NCover]]></category>
		<category><![CDATA[TypeMock]]></category>

		<guid isPermaLink="false">http://blairconrad.wordpress.com/?p=1200</guid>
		<description><![CDATA[This post is part of a continuing series chronicling my search for a .NET coverage tool. Today I&#8217;m looking at my fourth candidate: NCover. I tried NCover 3.4.18.6937. The Cost NCover Complete is $479 plus $179 for a 1-year subscription (which gives free version updates). I thought this was a little steep. NCover Classic is [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blairconrad.wordpress.com&amp;blog=11276730&amp;post=1200&amp;subd=blairconrad&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<div style="padding-left:.5em;padding-right:.5em;margin-left:2em;margin-right:2em;border:1px solid #EEE;background-color:#f8f8f8;">This post is part of a continuing series chronicling my <a href="/2011/07/18/can-you-cover-me-looking-for-a-net-coverage-tool/">search for a .NET coverage tool</a>.</div>
<p>Today I&#8217;m looking at my fourth candidate: <a href="http://www.ncover.com/">NCover</a>.</p>
<p>I tried NCover 3.4.18.6937. </p>
<h2>The Cost</h2>
<p>NCover Complete is $479 plus $179 for a 1-year subscription (which gives free version updates). I thought this was <b>a little steep</b>. NCover Classic is $199/$99. I looked at NCover Complete, because that&#8217;s the kind of trial version they give out. Also, the feature set for Classic was too similar to that offered by other tools that cost less. Check out the <a href="http://www.ncover.com/pages/feature_comparison">feature comparison</a>, if you like.</p>
<h2>Support</h2>
<p>I haven&#8217;t had enough problems to really stress the support network, but I will say this &#8211; the NCover chaps are really keen on keeping in touch with people who have trial copies of the program. I&#8217;ve received 3 separate e-mails from my assigned NCover rep in the 2 weeks since I first installed my trial copy. I replied to one of these, asking for a clarification on the VS integration (see below), and got a speedy response.<br />
It&#8217;s nice to see such a <b>high level of customer support</b>, but I do feel just a little bit smothered&hellip;</p>
<h2>VS integration</h2>
<p>The best advice from the NCover folks is to <a href="http://docs.ncover.com/how-to/running-ncover-from-visual-studio/">create an external tool to launch NCover</a>. That&#8217;s an okay solution if you want to run all the unit tests in a project and profile them, but it <b>lacks flexibility</b>. Then to actually look at the report, you have to launch the NCover Explorer and load the report.</p>
<p>There&#8217;s additional advice at the end of the <i>Running NCover from Visual Studio</i> video &#8211; if you want a more integrated Visual Studio experience, you should obtain <a href="http://testdriven.net/">TestDriven.Net</a>. That probably works well enough, but I&#8217;m not wild about paying an additional $189 per head (roughly) for a test runner that (in my opinion, and excepting the NCover integration of course) is a less robust solution than the one that <a href="http://www.jetbrains.com/resharper/features/unit_testing.html">comes bundled with ReSharper</a>.</p>
<p>Oh. There&#8217;s one more feature that I found &#8211; once you are examining a coverage report, you can <code>Edit in VS.NET</code>, which opens the appropriate file in Visual Studio. This is somewhat convenient, but doesn&#8217;t warp you to the correct line, which is a bit of a letdown.</p>
<h2>Command Line Execution</h2>
<p>The command line offers many and varied options for configuring the coverage run. Here&#8217;s a sample invocation:<br />
<pre class="brush: plain; light: true;">
NCover.Console.exe //exclude-assemblies BookFinder.Tests //xml ..\..\coverage.nccover nunit-console.exe bin\debug\BookFinder.Tests.dll
</pre></p>
<p>Upon execution, NCover tells me this:<br />
<pre class="brush: plain; light: true;">
Adding the '/noshadow' argument to the NUnit command line to ensure NCover can gather coverage data.
To prevent this behavior, use the //literal argument.
</pre></p>
<p>I really like that it defaults to passing the recommended <code>/noshadow</code> to NUnit. The <code>//</code> switches are also a good touch &#8211; it makes providing arguments to the executable being covered a lot easier. These features make the command line invocation <b>the best I&#8217;ve seen</b> among coverage tools.</p>
<h2>GUI Runner</h2>
<p><a href="http://blairconrad.files.wordpress.com/2011/10/runncover.png"><img src="http://blairconrad.files.wordpress.com/2011/10/runncover.png?w=226&#038;h=300" alt="NCover options" title="RunNCover" width="226" height="300" /></a><a href="http://blairconrad.files.wordpress.com/2011/10/ncoverexplorer.png"><img src="http://blairconrad.files.wordpress.com/2011/10/ncoverexplorer.png?w=300&#038;h=231" alt="" title="NCoverExplorer" width="300" height="231" /></a></p>
<p>The GUI runner looks just like a GUI wrapper on top of the command line options &#8211; they appear to support the same level of configuration. After the tests have been run, the NCoverExplorer allows one to browse the results and to save a report as XML or HTML.</p>
<h2>XML Report</h2>
<p>Reports are generated either from the GUI runner or by using the NCover.Reporting executable, which has a plethora of options for choosing XML or HTML reports of various flavours.<br />
XML reports contain all the information you might want to summarize for inclusion in build output, but they&#8217;re <b>hard to understand</b>. Witness:<br />
<pre class="brush: xml; light: true;">
&lt;stats acp=&quot;95&quot; afp=&quot;80&quot; abp=&quot;95&quot; acc=&quot;20&quot; ccavg=&quot;1.5&quot; ccmax=&quot;5&quot; ex=&quot;0&quot; ei=&quot;1&quot; ubp=&quot;12&quot; ul=&quot;40&quot; um=&quot;10&quot; usp=&quot;39&quot; vbp=&quot;63&quot; vl=&quot;89&quot; vsp=&quot;105&quot; mvc=&quot;18&quot; vc=&quot;2&quot; vm=&quot;22&quot; svc=&quot;120&quot;&gt;
</pre><br />
If you stare at this long enough (and correlate with a matching HTML report), you figure out that this means that there are</p>
<ul>
<li>39 <b>u</b>nvisited <b>s</b>equence <b>p</b>oints, and</li>
<li>105 <b>v</b>isited <b>s</b>equence <b>p</b>oints</li>
</ul>
<p>along with various other stats, so using attribute extraction and Math, we could see that 105/144 or 72.9% of the sequence points are covered.</p>
<p>It&#8217;s odd that there are many more reports available for HTML than XML. Notably absent from the XML offering: &#8220;Summary&#8221;. What is it about summaries that make them unsuitable for rendering as XML when HTML is fine?</p>
<h2>Reports of Auto-Deploy</h2>
<p>My Support Guy explained that you can xcopy deploy NCover using the <code>//reg</code> flag, but I <b>did not find any documentation</b> on how to do this. Support Guy claims there is an &#8220;honour system&#8221; kind of licensing model that supports this, but the trial copy I had did not work this way. I eventually abandoned this line of investigation.</p>
<h2>Mature Isolator Support</h2>
<p>From Visual Studio, under the Typemock menu, configure Typemock Isolator to Link with NCover&amp;nsbsp;3.0.<br />
When using the <code>TypeMockStart</code> MSBuild task, use<br />
<pre class="brush: xml; light: true;">
&lt;TypeMockStart Link=&quot;NCover3.0&quot; ProfilerLaunchedFirst=&quot;true&quot;/&gt;
</pre><br />
and it <b>just works</b>, assuming you have TypeMock Isolator installed or <a href="/2010/06/06/auto-deploying-typemock-isolator-without-trashing-the-installation/">set to auto-deploy</a>.</p>
<h2>IIS</h2>
<p>IIS coverage is available, simply by selecting it from the <b>GUI runner options or from the command line</b> using the <code>//iis</code> switch. Other Windows Services can be covered in the same manner. Note though, that these features are only available in the Complete flavour of NCover 3.0.</p>
<h2>Sequence Point coverage</h2>
<p><b>Supported</b>, as well as branch point coverage and other metrics, including <a href="http://en.wikipedia.org/wiki/Cyclomatic_complexity">cyclomatic complexity</a>. Nice options to have, although probably a little advanced for my team&#8217;s current needs and experience.</p>
<h2>Conclusion</h2>
<p><strong>Pros:</strong></p>
<ul>
<li>sequence point and branch coverage</li>
<li>large feature set, including trends, cyclomatic complexity analysis, and much much more</li>
<li>commercial product with strong support</li>
<li>report merging</li>
<li>easy IIS profiling</li>
<li>supports Isolator</li>
</ul>
<p><strong>Cons:</strong></p>
<ul>
<li>costly</li>
<li>weak IDE integration</li>
<li>inconsistent (comparing XML to HTML) report offerings</li>
<li>confusing auto-deploy</li>
</ul>
<p>I expected to be blown away by NCover&mdash;from all reports, it&#8217;s the Cadillac of .NET coverage tools. After demoing it, I figured I&#8217;d end up desperately trying to make a case to the Money Guy to shell out hundreds of dollars per developer (and build server), but this did not happen.<br />
While NCover definitely has lots of features, it&#8217;s lacking some pretty important ones as well, notably IDE integration. Other features just weren&#8217;t as I expected &#8211; the cornucopia of report types is impressive, but overkill for a team just starting out, and many of the report types aren&#8217;t available in XML and/or are very minor variations on other report types.<br />
Ultimately, I don&#8217;t see what NCover offers to justify its price tag, especially across a large team. If ever I felt a need to have one of the specialized report, I&#8217;d consider obtaining a single license for tactical use, but I can&#8217;t imagine any more than that.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/blairconrad.wordpress.com/1200/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/blairconrad.wordpress.com/1200/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/blairconrad.wordpress.com/1200/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/blairconrad.wordpress.com/1200/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/blairconrad.wordpress.com/1200/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/blairconrad.wordpress.com/1200/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/blairconrad.wordpress.com/1200/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/blairconrad.wordpress.com/1200/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/blairconrad.wordpress.com/1200/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/blairconrad.wordpress.com/1200/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/blairconrad.wordpress.com/1200/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/blairconrad.wordpress.com/1200/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/blairconrad.wordpress.com/1200/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/blairconrad.wordpress.com/1200/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blairconrad.wordpress.com&amp;blog=11276730&amp;post=1200&amp;subd=blairconrad&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blairconrad.wordpress.com/2011/11/09/hasty-impressions-ncover/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<georss:point>43.465187 -80.522372</georss:point>
		<geo:lat>43.465187</geo:lat>
		<geo:long>-80.522372</geo:long>
		<media:content url="http://1.gravatar.com/avatar/707860a1ae9745187b83023e2655e03c?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">blairconrad</media:title>
		</media:content>

		<media:content url="http://blairconrad.files.wordpress.com/2011/10/runncover.png?w=226" medium="image">
			<media:title type="html">RunNCover</media:title>
		</media:content>

		<media:content url="http://blairconrad.files.wordpress.com/2011/10/ncoverexplorer.png?w=300" medium="image">
			<media:title type="html">NCoverExplorer</media:title>
		</media:content>
	</item>
		<item>
		<title>Hasty Impressions: OpenCover</title>
		<link>http://blairconrad.wordpress.com/2011/08/15/hasty-impressions-opencover/</link>
		<comments>http://blairconrad.wordpress.com/2011/08/15/hasty-impressions-opencover/#comments</comments>
		<pubDate>Mon, 15 Aug 2011 13:00:40 +0000</pubDate>
		<dc:creator>Blair Conrad</dc:creator>
				<category><![CDATA[Testing]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[Coverage]]></category>
		<category><![CDATA[dotCover]]></category>
		<category><![CDATA[HastyImpressions]]></category>
		<category><![CDATA[IIS]]></category>
		<category><![CDATA[Isolator]]></category>
		<category><![CDATA[MightyMoose]]></category>
		<category><![CDATA[TypeMock]]></category>

		<guid isPermaLink="false">http://blairconrad.wordpress.com/?p=1163</guid>
		<description><![CDATA[This post is part of a continuing series chronicling my search for a .NET coverage tool. Today I&#8217;m looking at my third candidate: OpenCover. OpenCover is developed by Shaun Wilde. He was a developer on (and is the only remaining maintainer of) PartCover. He&#8217;s used what he learned working on PartCover to develop OpenCover, but [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blairconrad.wordpress.com&amp;blog=11276730&amp;post=1163&amp;subd=blairconrad&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<div style="padding-left:.5em;padding-right:.5em;margin-left:2em;margin-right:2em;border:1px solid #EEE;background-color:#f8f8f8;">This post is part of a continuing series chronicling my <a href="/2011/07/18/can-you-cover-me-looking-for-a-net-coverage-tool/">search for a .NET coverage tool</a>.</div>
<p>Today I&#8217;m looking at my third candidate: <a href="https://github.com/sawilde/opencover">OpenCover</a>.<br />
OpenCover is developed by Shaun Wilde. He was a developer on (and is the only remaining maintainer of) PartCover. He&#8217;s used what he learned working on PartCover to develop OpenCover, but OpenCover is a new implementation, not a port.</p>
<p>I tried OpenCover 1.0.514. Since I downloaded a couple weeks ago there have been 3 more releases, with the 1.0.606 release promising a big performance improvement.</p>
<h2>The Cost</h2>
<p>Free! And you can get the source.</p>
<h2>VS integration</h2>
<p>None that I can find.</p>
<h2>Command Line Execution</h2>
<p>Covering an application from the command line is <strong>easy</strong>, and reminiscent of using PartCover the same way. I used this command to see what code my BookFinder unit tests exercised:</p>
<p><pre class="brush: plain; light: true;">
OpenCover.Console.exe -arch:64 -register target:nunit-console.exe -targetargs:bin\debug\BookFinder.Tests.dll -output:..\..\opencover.xml -filter:+[BookFinder.Core]*
</pre></p>
<p>Let&#8217;s look at that.</p>
<ul>
<li><code>-arch:64</code> &#8211; I&#8217;m running on a 64-bit system. I didn&#8217;t get any results without this.</li>
<li><code>-register</code> &#8211; I&#8217;m auto-deploying OpenCover. More on that later.</li>
<li><code>-target:nunit-console.exe</code> &#8211; I like NUnit</li>
<li><code>-targetargs:bin\debug\BookFinder.Tests.dll</code> &#8211; arguments to NUnit to tell it what assembly to test, and how.</li>
<li><code>-output:..\..\opencover.xml</code> &#8211; where to put the coverage results. This file is not a report &#8211; it&#8217;s intended for machines to read, not humans.</li>
<li><code>-filter:+[BookFinder.Core]*</code> &#8211; BookFinder.Core is the only assembly I was interested in &#8211; it holds the business logic.</li>
</ul>
<h2>GUI Runner</h2>
<p>There isn&#8217;t one, but I have to wonder if there won&#8217;t be. Otherwise, why call the command line coverer <strong>OpenCover.Console.exe</strong>?</p>
<h2>XML Report</h2>
<p>OpenCover doesn&#8217;t generate a human-readable report. Instead, you can postprocess the coverage output. <b><a href="http://www.palmmedia.de/Net/ReportGenerator">ReportGenerator</a> is the recommended tool</b>, and it works like a charm.</p>
<p><pre class="brush: plain; light: true;">
ReportGenerator.exe .\opencover.xml XmlReport Xml
</pre><br />
generates an XML report in the <code>Xml</code> directory. The summary looks like this:</p>
<p><pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;CoverageReport scope=&quot;Summary&quot;&gt;
  &lt;Summary&gt;
    &lt;Generatedon&gt;2011-08-05-2011-08-05&lt;/Generatedon&gt;
    &lt;Parser&gt;OpenCoverParser&lt;/Parser&gt;
    &lt;Assemblies&gt;1&lt;/Assemblies&gt;
    &lt;Files&gt;5&lt;/Files&gt;
    &lt;Coverage&gt;71.6%&lt;/Coverage&gt;
    &lt;Coveredlines&gt;126&lt;/Coveredlines&gt;
    &lt;Coverablelines&gt;176&lt;/Coverablelines&gt;
    &lt;Totallines&gt;495&lt;/Totallines&gt;
  &lt;/Summary&gt;
  &lt;Assemblies&gt;
    &lt;Assembly name=&quot;BookFinder.Core.DLL&quot; coverage=&quot;71.6&quot;&gt;
      &lt;Class name=&quot;BookFinder.BookDepository&quot; coverage=&quot;85.7&quot; /&gt;
      &lt;Class name=&quot;BookFinder.BookListViewModel&quot; coverage=&quot;50&quot; /&gt;
      &lt;Class name=&quot;BookFinder.BoolProperty&quot; coverage=&quot;50&quot; /&gt;
      &lt;Class name=&quot;BookFinder.BoundPropertyStrategy&quot; coverage=&quot;0&quot; /&gt;
      &lt;Class name=&quot;BookFinder.ListProperty&quot; coverage=&quot;75&quot; /&gt;
      &lt;Class name=&quot;BookFinder.Property&quot; coverage=&quot;100&quot; /&gt;
      &lt;Class name=&quot;BookFinder.StringProperty&quot; coverage=&quot;100&quot; /&gt;
      &lt;Class name=&quot;BookFinder.ViewModelBase&quot; coverage=&quot;81&quot; /&gt;
    &lt;/Assembly&gt;
  &lt;/Assemblies&gt;
&lt;/CoverageReport&gt;
</pre></p>
<p>ReportGenerator also generates Html and LaTeX output, with a &#8220;summary&#8221; variant for each of the three output types.</p>
<p>The XML report would be most useful for inclusion in build result reports, but I found the HTML version easy to use to examine coverage results down to the method level.<br />
<a href="http://blairconrad.files.wordpress.com/2011/08/html_summary.png"><img title="html_summary" align="top" src="http://blairconrad.files.wordpress.com/2011/08/html_summary.png?w=270&#038;h=300" alt="HTML Coverage Summary" width="270" height="300" /></a>&nbsp;<a href="http://blairconrad.files.wordpress.com/2011/08/html_detail.png"><img title="html_detail" align="top" src="http://blairconrad.files.wordpress.com/2011/08/html_detail.png?w=300&#038;h=208" alt="HTML Coverage Detail" width="300" height="208" /></a><br />
I appreciate the coverage count by each of the lines &#8211; not as fancy as dotCover&#8217;s &#8220;which tests cover this&#8221;, but it could be a helpful clue when you&#8217;re trying to decide what you need to do to improve your coverage.</p>
<h2>Joining Coverage Runs</h2>
<p>Perhaps your test are scattered in space or time and you want to get an overview of all the code that&#8217;s covered by them. OpenCover doesn&#8217;t really do anything special for you, but <strong>ReportGenerator has your back</strong>. Specify multiple input files on the command line, and the results will be aggregated and added to a comprehensive report:</p>
<p><pre class="brush: plain; light: true;">
ReportGenerator.exe output1.xml;output2.xml;output3.xml XmlReport Xml
</pre></p>
<h2></h2>
<h2>DIY Auto-Deploy</h2>
<p>There&#8217;s no built-in auto-deploy for OpenCover. However, <b>I made my own auto-deployable package</b> like so:</p>
<ol>
<li>install OpenCover</li>
<li>copy the <code>C:\Program Files (x86)\OpenCover</code> directory somewhere &#8211; call this your <i>package directory</i></li>
<li>uninstall OpenCover &#8211; you won&#8217;t need it any more</li>
</ol>
<p>Then I just made sure my coverage build step </p>
<ul>
<li>knew where the OpenCover package directory was (for the build system at the Day Job, I added it to our &#8220;subscribes&#8221;)</li>
<li>used the <code>-register</code> flag mentioned above to register OpenCover before running the tests</li>
</ul>
<p>That&#8217;s it. No muss, no fuss. I did a similar (but easier, since there&#8217;s no registration needed) trick with ReportGenerator, and all of a sudden I have a no-deploy system.</p>
<p>In less than an hour&#8217;s work, I could upgrade a project so the build servers and all the developers could run a coverage target, with no action on their part, other than pulling the updated source tree and building. (Which is pretty much what the build server does all day long anyhow&#8230;)</p>
<h2>DIY (for now) Coverage with Isoloator</h2>
<p>Isoloator and OpenCover don&#8217;t work together out of the box, but thanks to advice I got from <a href="http://www.hmemcpy.com/blog/">Igal Tabachnik</a>, Typemock employee, it was not hard to change this.</p>
<p>Isolator&#8217;s supported coverage tools are partly configurable. There is a <code>typemockconfig.xml</code> under the Isolator install directory &#8211; typically </code>%ProgramFiles (x86)%\Typemock\Isoloator\6.0</code> (or <code>%ProgramFiles%</code>, I suppose). Mr. Tabachnik had me add<br />
<pre class="brush: xml; light: true;"> 
&lt;Profiler Name=&quot;OpenCover&quot; Clsid=&quot;{1542C21D-80C3-45E6-A56C-A9C1E4BEB7B8}&quot; DirectLaunch=&quot;false&quot;&gt;
  &lt;EnvironmentList /&gt;
&lt;/Profiler&gt;
</pre><br />
to the <code>ProfilerList</code> element, and everything meshed. His <a href="http://stackoverflow.com/questions/6698290/can-opencover-be-used-with-typemock-isolator">StackOverflow answer</a> provides full details and suggests that official support for OpenCover will be added to Isolator. </p>
<h2>IIS</h2>
<p>I can't find any special IIS support. I'm not saying OpenCover can't be used to cover an application running in IIS, only that I didn't find any help for it. I may investigate this later.</p>
<h2>Sequence Point coverage</h2>
<p>OpenCover counts sequence points, not statements. Yay!</p>
<h2>Conclusion</h2>
<p><strong>Pros:</strong></p>
<ul>
<li>free</li>
<li>open source</li>
<li>active project</li>
<li>XML/HTML/LaTeX reports (via ReportGenerator)</li>
<li>report merging (via ReportGenerator)</li>
<li>Isolator support is easy to add (and may be included in future Isolators)</li>
<li>auto-deploy package is easy to make</li>
</ul>
<p><strong>Cons:</strong></p>
<ul>
<li>no IDE integration</li>
<li>no help with IIS profiling</li>
</ul>
<p>I really like OpenCover. It's easy to use, relatively full-featured, and free. In a work environment, where there's a tonne of developers who want the in-IDE profiling experience, it may not be the best bet, but I'd use it for my personal .NET projects in a flash. </p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/blairconrad.wordpress.com/1163/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/blairconrad.wordpress.com/1163/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/blairconrad.wordpress.com/1163/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/blairconrad.wordpress.com/1163/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/blairconrad.wordpress.com/1163/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/blairconrad.wordpress.com/1163/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/blairconrad.wordpress.com/1163/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/blairconrad.wordpress.com/1163/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/blairconrad.wordpress.com/1163/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/blairconrad.wordpress.com/1163/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/blairconrad.wordpress.com/1163/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/blairconrad.wordpress.com/1163/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/blairconrad.wordpress.com/1163/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/blairconrad.wordpress.com/1163/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blairconrad.wordpress.com&amp;blog=11276730&amp;post=1163&amp;subd=blairconrad&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blairconrad.wordpress.com/2011/08/15/hasty-impressions-opencover/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<georss:point>43.465187 -80.522372</georss:point>
		<geo:lat>43.465187</geo:lat>
		<geo:long>-80.522372</geo:long>
		<media:content url="http://1.gravatar.com/avatar/707860a1ae9745187b83023e2655e03c?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">blairconrad</media:title>
		</media:content>

		<media:content url="http://blairconrad.files.wordpress.com/2011/08/html_summary.png?w=270" medium="image">
			<media:title type="html">html_summary</media:title>
		</media:content>

		<media:content url="http://blairconrad.files.wordpress.com/2011/08/html_detail.png?w=300" medium="image">
			<media:title type="html">html_detail</media:title>
		</media:content>
	</item>
		<item>
		<title>Hasty Impressions: PartCover</title>
		<link>http://blairconrad.wordpress.com/2011/08/05/hasty-impressions-partcover/</link>
		<comments>http://blairconrad.wordpress.com/2011/08/05/hasty-impressions-partcover/#comments</comments>
		<pubDate>Fri, 05 Aug 2011 12:00:39 +0000</pubDate>
		<dc:creator>Blair Conrad</dc:creator>
				<category><![CDATA[Testing]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[Coverage]]></category>
		<category><![CDATA[HastyImpressions]]></category>
		<category><![CDATA[OpenCover]]></category>
		<category><![CDATA[PartCover]]></category>

		<guid isPermaLink="false">http://blairconrad.wordpress.com/?p=1152</guid>
		<description><![CDATA[This post is part of a continuing series chronicling my search for a .NET coverage tool. Today I&#8217;m looking at my second candidate: PartCover. Technical stuff PartCover has a GUI runner as well as a command-line mode. It integrates with Isolator, but doesn&#8217;t offer any help for those wanting to profile IIS-hosted applications. There are [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blairconrad.wordpress.com&amp;blog=11276730&amp;post=1152&amp;subd=blairconrad&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<div style="padding-left:.5em;padding-right:.5em;margin-left:2em;margin-right:2em;border:1px solid #EEE;background-color:#f8f8f8;">This post is part of a continuing series chronicling my <a href="/2011/07/18/can-you-cover-me-looking-for-a-net-coverage-tool/">search for a .NET coverage tool</a>.</div>
<p>Today I&#8217;m looking at my second candidate: <a href="http://sourceforge.net/projects/partcover/">PartCover</a>. </p>
<h2>Technical stuff</h2>
<p>PartCover has a GUI runner as well as a command-line mode. It integrates with Isolator, but doesn&#8217;t offer any help for those wanting to profile IIS-hosted applications.<br />
There are some XSL files provided that allow one to generate HTML reports, but probably the better way is to use <a href="http://www.palmmedia.de/Net/ReportGenerator">ReportGenerator</a> to make HTML or XML reports.<br />
PartCover claims to be auto-deployable, but I did not try this.</p>
<h2>Project Concerns</h2>
<p>The hardest thing about working with PartCover is learning about PartCover &#8211; finding definitive information about the project&#8217;s state is quite difficult. Searching with Google finds <a href="http://sourceforge.net/projects/partcover/">the SourceForge project</a> which contains a note to see latest news on the <a href="http://partcover.blogspot.com">PartCover blog</a>, which <b>hasn&#8217;t been updated</b> since 17 June 2009. Back at SourceForge, you can download a readme written by Shaun Wilde, which says that he&#8217;s the last active developer and has <b>moved development</b> to <a href="http://github.com/sawilde/partcover.net4">a GitHub project</a>.</p>
<p>At last! A project with recent (26 June 2011) updates. Unfortunately, my trials did not end here. I tried a number of versions, each with their own quirks. Unfortunately, I did not keep as careful track of which version had which problem as I should, and can&#8217;t say which version (from either GitHub or SourceForge) had which problems, but I can describe the problems.</p>
<p>At first I thought things were working really well, but then noticed that I had abnormally high coverage levels on my projects &#8211; one legacy project that I knew had about 5% coverage was registering as over 20%!<br />
I looked at one assembly&#8217;s summary and found 6 classes with 0% coverage and one with 80%, and the assembly was registering an 80%. It turns out that <b>completely uncovered classes were not counting against the total</b>.</p>
<p>I tried other versions, with either the same results, or failures to run altogether. Ultimately, I gave up.</p>
<h2>A Successor</h2>
<p>It turns out that PartCover has a successor of sorts &#8211; Shaun Wilde, the last surviving maintainer of PartCover, has started his own coverage tool &#8211; <a href="https://github.com/sawilde/opencover">OpenCover</a>. It already seems be a viable PartCover replacement, and is in active development, so I&#8217;ll be checking it out as a free, non-IDE-integrated coverage tool.</p>
<h2>Conclusion</h2>
<p><strong>Pros:</strong></p>
<ul>
<li>free!</li>
<li>XML/HTML via ReportGenerator</li>
<li>report merging via ReportGenerator</li>
<li>Isolator support</li>
<li>auto-deployable (reported)</li>
<li>sequence point coverage</li>
</ul>
<p><strong>Cons:</strong></p>
<ul>
<li>no IDE integration</li>
<li>no special IIS support</li>
<li>forked implementations, each with their own warts</li>
<li>not quite abandoned, but not a lot of interest behind the project</li>
</ul>
<p>Until I noticed the high coverage levels, I didn&#8217;t mind PartCover. I figured its lack of price and its Isolator support made it a viable candidate. Unfortunately, the high coverage reports and other problems soured me on the deal, as did the lack of maintenance. I&#8217;m going to look at OpenCover instead.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/blairconrad.wordpress.com/1152/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/blairconrad.wordpress.com/1152/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/blairconrad.wordpress.com/1152/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/blairconrad.wordpress.com/1152/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/blairconrad.wordpress.com/1152/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/blairconrad.wordpress.com/1152/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/blairconrad.wordpress.com/1152/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/blairconrad.wordpress.com/1152/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/blairconrad.wordpress.com/1152/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/blairconrad.wordpress.com/1152/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/blairconrad.wordpress.com/1152/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/blairconrad.wordpress.com/1152/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/blairconrad.wordpress.com/1152/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/blairconrad.wordpress.com/1152/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blairconrad.wordpress.com&amp;blog=11276730&amp;post=1152&amp;subd=blairconrad&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blairconrad.wordpress.com/2011/08/05/hasty-impressions-partcover/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<georss:point>43.465187 -80.522372</georss:point>
		<geo:lat>43.465187</geo:lat>
		<geo:long>-80.522372</geo:long>
		<media:content url="http://1.gravatar.com/avatar/707860a1ae9745187b83023e2655e03c?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">blairconrad</media:title>
		</media:content>
	</item>
		<item>
		<title>Hasty Impressions: dotCover 1.1</title>
		<link>http://blairconrad.wordpress.com/2011/07/29/hasty-impressions-dotcover-1-1/</link>
		<comments>http://blairconrad.wordpress.com/2011/07/29/hasty-impressions-dotcover-1-1/#comments</comments>
		<pubDate>Fri, 29 Jul 2011 12:00:48 +0000</pubDate>
		<dc:creator>Blair Conrad</dc:creator>
				<category><![CDATA[Testing]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[Coverage]]></category>
		<category><![CDATA[dotCover]]></category>
		<category><![CDATA[HastyImpressions]]></category>
		<category><![CDATA[IIS]]></category>
		<category><![CDATA[Isolator]]></category>
		<category><![CDATA[MightyMoose]]></category>
		<category><![CDATA[TypeMock]]></category>

		<guid isPermaLink="false">http://blairconrad.wordpress.com/?p=1049</guid>
		<description><![CDATA[This post is part of a continuing series chronicling my search for a .NET coverage tool. Today I&#8217;m looking at the first candidate: JetBrains dotCover. I tried dotCover 1.1, integrated with ReSharper 5.1 running in VS2008. The Cost A lifetime license, with 1 year of free upgrades is $199 $149 &#8211; a special introductory price. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blairconrad.wordpress.com&amp;blog=11276730&amp;post=1049&amp;subd=blairconrad&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<div style="padding-left:.5em;padding-right:.5em;margin-left:2em;margin-right:2em;border:1px solid #EEE;background-color:#F8F8F8;">
This post is part of a continuing series chronicling my <a href="/2011/07/18/can-you-cover-me-looking-for-a-net-coverage-tool/">search for a .NET coverage tool</a>.
</div>
<p>Today I&#8217;m looking at the first candidate: <a href="http://www.jetbrains.com/dotcover/">JetBrains dotCover</a>.</p>
<p>I tried dotCover 1.1, integrated with ReSharper 5.1 running in VS2008.</p>
<h2>The Cost</h2>
<p>A lifetime license, with 1 year of free upgrades is <s>$199</s> $149 &#8211; a special introductory price.</p>
<p>This isn&#8217;t usurious, but considering that ReSharper C# edition, a tool that changes the way I work every single day, is $249, it&#8217;s enough.</p>
<h2>VS integration</h2>
<p><a href="http://blairconrad.files.wordpress.com/2011/07/cover_with_dotcover2.png"><img style="margin-right:1em;" title="cover with dotCover" src="http://blairconrad.files.wordpress.com/2011/07/cover_with_dotcover2.png?w=174&#038;h=170" alt="cover with dotCover" width="174" height="170" align="left" /></a></p>
<p>This is where I expected dotCover to shine, and it didn&#8217;t disappoint &#8211; the <strong>integration with Visual Studio (and with ReSharper) was excellent</strong>. The first thing I noticed was an extra &#8220;Cover with dotCover&#8221; item in the ReSharper test menu (triggered from the yellow and green ball things). I clicked it, and it ran my tests, bringing up the familiar Unit Test results window.</p>
<p>Once the tests ran, there was pause while dotCover calculated the coverage info, and then the bottom pane filled in with coverage results: green/red bars by every method in the covered assemblies. Clicking on the methods warps to the source code, which is also highlighted &#8211; covered statements have a green background, and uncovered statements have red. In fact, every source file opened in the IDE has the highlighting.</p>
<p><a href="http://blairconrad.files.wordpress.com/2011/07/doccover_bookfinder.png"><img title="dotCover BookFinder tests" src="http://blairconrad.files.wordpress.com/2011/07/doccover_bookfinder.png?w=300&#038;h=233" alt="dotCover BookFinder tests" width="300" height="233" align="top" /></a><a href="http://blairconrad.files.wordpress.com/2011/07/dotcover_covered.png"><img title="dotCover_covered" src="http://blairconrad.files.wordpress.com/2011/07/dotcover_covered.png?w=300&#038;h=187" alt="" width="300" height="187" align="top" /></a></p>
<h3>Finding tests that cover code</h3>
<p>The most interesting feature that dotCover has is the ability to identify which tests covered which lines of code. I&#8217;m not entirely sold on this, thinking it more of a gimmick than anything else. When I first heard about it, I thought &#8220;I don&#8217;t care which test covered which line, so long as the lines are covered. I&#8217;m here to see what <em>isn&#8217;t</em> covered.&#8221;. Yes, I think in italics sometimes.</p>
<p><a href="http://blairconrad.files.wordpress.com/2011/07/dotcover_show_covering_tests.png"><img style="margin-left:1em;margin-bottom:1em;" title="dotCover_show_covering_tests" src="http://blairconrad.files.wordpress.com/2011/07/dotcover_show_covering_tests.png?w=278&#038;h=140" alt="" width="278" height="140" align="right" /></a>Still, I gave it a go. Right-clicking on a line of code (once coverage has been run) brought up a tiny menu full of covered lines of code. I don&#8217;t know why, but it made me happy. I suppose one could use this from time to time to make sure a new test case is exercising what it&#8217;s supposed to, but normally I can tell that by how a new test fails, or by what I&#8217;ve typed just before the test starts working. Worst case, I could always debug through a single test &#8211; something made very easy by the ReSharper test runner.</p>
<p><a href="http://blairconrad.files.wordpress.com/2011/07/dotcover_covering_tests.png"><img class="alignright size-medium wp-image-1080" title="dotCover_covering_tests" src="http://blairconrad.files.wordpress.com/2011/07/dotcover_covering_tests.png" /></a><br />
There was one aspect of this feature that I could imagine someone using &#8211; the ability to <strong>run the tests</strong> that cover a line of code. All that&#8217;s needed is to hit the &#8220;play&#8221; button on the &#8220;Show Covering Tests&#8221; popup. If the full suite of tests takes a very long time to run, this could be useful. Still, it doesn&#8217;t do much for me personally &#8211; if my tests took that long to run, I&#8217;d try speed them up. If nothing else, I would probably just run the test fixture designed to test the class or method in question, instead of my entire bolus of tests.</p>
<p>So, running tests that cover some code is a cool feature, but it&#8217;s <strong>not that useful</strong>. I&#8217;d rather see something like the automatic test runs and really cool &#8220;what&#8217;s covered&#8221; information provided by <a href="http://continuoustests.com/">Mighty-Moose</a>.</p>
<h2>Command Line Execution</h2>
<p>Covering an application from the command line is <b>pretty straightforward</b>. I used this command to see what code my BookFinder unit tests exercised:<br />
<pre class="brush: plain; light: true;">
dotcover cover /TargetExecutable=nunit-console.exe /TargetArguments=.\BookFinder.Tests.dll /Output=dotCoverOutput /Filters=+:BookFinder.Core
</pre><br />
BookFinder.Core is the only assembly I was interested in &#8211; it holds the business logic. &#8220;cover&#8221; takes multiple include and exclude filters, even using wildcards for assemblies, classes, and methods.</p>
<p>One quite cool feature is to use the <b>help subcommand to generate an XML configuration file</b>, which can be used to specify the parameters for the <code>cover</code> command:<br />
<pre class="brush: plain; light: true;">
dotCover help cover coverSettings.xml
</pre><br />
will create a <code>coverSettings.xml</code> file that can be edited to specify the executable, arguments, and filters. Then use it like so:<br />
<pre class="brush: plain; light: true;">
dotCover cover coverSettings.xml
</pre> without having to specify the same batch of parameters all the time.</p>
<h2>Joining Coverage Runs</h2>
<p>Multiple coverage snapshots &#8211; perhaps from running tests on different assemblies, or just from performing different test runs on the same application &#8211; <b>can be merged together</b> into a comprehensive snapshot:<br />
<pre class="brush: plain; light: true;">
dotCover merge /Source snapshot1;snapshot2 /Output mergedsnapshot
</pre><br />
Just include all the snapshots, separated by semicolons. </p>
<h2>XML Report</h2>
<p>After generating snapshots and optionally merging them, they can be  <b>turned into an XML report using the report command</b>:</p>
<p><pre class="brush: plain; light: true;">dotcover report /Source=.\dotCoverOutput /Output=coverageReport.xml</pre></p>
<p>There are options to generate <b>HTML</b> and <b>JSON</b> as well.</p>
<p>Note that if there&#8217;s only one snapshot, the &#8220;merge&#8221; step is not needed. In fact, there&#8217;s even a separate <code>analyse</code> command that will cover and generate a report in one go.</p>
<h2>No Auto-Deploy</h2>
<p>There&#8217;s no auto-deploy for dotCover &#8211; <strong>it needs to be installed</strong>. And since it&#8217;s a plugin, <strong>Visual Studio is a requirement</strong>. This is a small inconvenience for developers and our build servers. Having to put VS on all our test machines is a bit of a bigger deal &#8211; definitely a strike against dotCover.</p>
<h2>TypeMock Isolator support in the future</h2>
<p>The dotCover 1.1 doesn&#8217;t integrate with Isolator 6. Apparently dotCover&#8217;s hooks are a little different than many other profiles (nCover, PartCover, …). I&#8217;ve been talking to representatives from both TypeMock and JetBrains, though, and they tell me that the problem is solved, and an upcoming release of Isolator will integrate with dotCover. <a href="http://forums.typemock.com/viewtopic.php?p=8528">Even better, a pre-release version that supports the latest dotCover EAP is available now</a>.</p>
<h2>IIS</h2>
<p>dotCover <b>covers IIS, but only by using the plugin</b> &#8211; this means that the web server has to have Visual Studio and dotCover installed, and it&#8217;s a manual step to invoke the coverage. In the JetBrains developer community there&#8217;s a <a href="http://devnet.jetbrains.net/thread/30319">discussion about command-line IIS support</a>, but no word from JetBrains staff on when this might come.</p>
<h2>Statement-level coverage</h2>
<p>As <a href="http://vcsjones.com/2011/01/03/dotcover-inaccurate-or-misunderstood/">Kevin Jones notes</a>, dotCover reports coverage of statements coverage, not sequence points. This means that a line like this:<br />
<pre class="brush: plain; light: true;">
return value &gt; 10
      ? Colors.Red
      : Colors.White;
</pre><br />
Will report as completely covered, even if it&#8217;s executed only once &#8211; in order to ensure an accurate coverage report for this idea, the <code>?:</code> would have to be replaced by an if-else block.<br />
This isn&#8217;t necessarily a major strike against the tool, but it&#8217;s worth knowing, as it will skew the results somewhat.</p>
<h2>Conclusion</h2>
<p><b>Pros:</b></p>
<ul>
<li>awesome IDE integration</li>
<li>XML/HTML/JSON reports</li>
<li>report merging</li>
<li>IIS profiling</li>
</ul>
<p><b>Cons:</b></p>
<ul>
<li>moderate price</li>
<li>no auto-deploy</li>
<li>no Isolator support&mdash;yet</li>
</ul>
<p>Overall, I like the tool. I&#8217;m a little disappointed by the lack of auto-deploy and the inability to run IIS coverage from the command line, but those problems can be worked around. I was very impressed with the in-IDE support as well as the automatically generated configuration files using the &#8220;help&#8221; subcommand.<br />
Ordinarily, the I&#8217;d say the current lack of Isolator support is a deal-breaker, but I recently demoed the product to some colleagues, and <b>they went bonkers for the IDE integration</b>. I guess I&#8217;ll be writing JetBrains and TypeMock looking for the betas. </p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/blairconrad.wordpress.com/1049/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/blairconrad.wordpress.com/1049/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/blairconrad.wordpress.com/1049/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/blairconrad.wordpress.com/1049/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/blairconrad.wordpress.com/1049/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/blairconrad.wordpress.com/1049/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/blairconrad.wordpress.com/1049/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/blairconrad.wordpress.com/1049/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/blairconrad.wordpress.com/1049/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/blairconrad.wordpress.com/1049/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/blairconrad.wordpress.com/1049/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/blairconrad.wordpress.com/1049/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/blairconrad.wordpress.com/1049/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/blairconrad.wordpress.com/1049/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blairconrad.wordpress.com&amp;blog=11276730&amp;post=1049&amp;subd=blairconrad&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blairconrad.wordpress.com/2011/07/29/hasty-impressions-dotcover-1-1/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<georss:point>43.465187 -80.522372</georss:point>
		<geo:lat>43.465187</geo:lat>
		<geo:long>-80.522372</geo:long>
		<media:content url="http://1.gravatar.com/avatar/707860a1ae9745187b83023e2655e03c?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">blairconrad</media:title>
		</media:content>

		<media:content url="http://blairconrad.files.wordpress.com/2011/07/cover_with_dotcover2.png" medium="image">
			<media:title type="html">cover with dotCover</media:title>
		</media:content>

		<media:content url="http://blairconrad.files.wordpress.com/2011/07/doccover_bookfinder.png?w=300" medium="image">
			<media:title type="html">dotCover BookFinder tests</media:title>
		</media:content>

		<media:content url="http://blairconrad.files.wordpress.com/2011/07/dotcover_covered.png?w=300" medium="image">
			<media:title type="html">dotCover_covered</media:title>
		</media:content>

		<media:content url="http://blairconrad.files.wordpress.com/2011/07/dotcover_show_covering_tests.png" medium="image">
			<media:title type="html">dotCover_show_covering_tests</media:title>
		</media:content>

		<media:content url="http://blairconrad.files.wordpress.com/2011/07/dotcover_covering_tests.png" medium="image">
			<media:title type="html">dotCover_covering_tests</media:title>
		</media:content>
	</item>
		<item>
		<title>Can you cover me? Looking for a .NET coverage tool</title>
		<link>http://blairconrad.wordpress.com/2011/07/18/can-you-cover-me-looking-for-a-net-coverage-tool/</link>
		<comments>http://blairconrad.wordpress.com/2011/07/18/can-you-cover-me-looking-for-a-net-coverage-tool/#comments</comments>
		<pubDate>Mon, 18 Jul 2011 12:00:40 +0000</pubDate>
		<dc:creator>Blair Conrad</dc:creator>
				<category><![CDATA[Testing]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[Coverage]]></category>
		<category><![CDATA[IIS]]></category>
		<category><![CDATA[Isolator]]></category>
		<category><![CDATA[TypeMock]]></category>

		<guid isPermaLink="false">http://blairconrad.wordpress.com/?p=1031</guid>
		<description><![CDATA[Recently at the Day Job, my boss&#8217;s boss has been on a &#8220;code confidence&#8221; kick. We&#8217;ve always done various levels of automated and manual unit, integration, issue, system, and regression testing, but he&#8217;s looking to improve the process. Part of this push involves getting better at measuring which tests exercise what parts of the code. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blairconrad.wordpress.com&amp;blog=11276730&amp;post=1031&amp;subd=blairconrad&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Recently at the Day Job, my boss&#8217;s boss has been on a &#8220;code confidence&#8221; kick. We&#8217;ve always done various levels of automated and manual unit, integration, issue, system, and regression testing, but he&#8217;s looking to improve the process. Part of this push involves getting better at measuring which tests exercise what parts of the code. We want to know this for the usual reasons: we can identify gaps in our testing, or more likely find opportunities to cover some areas earlier in the testing cycle. It&#8217;d be nice to know that a particularly critical section of code has been adequately exercised by the per-build unit tests, without having to wait for nightly integration testing or wait even longer for a human to get their grubby mitts on it.</p>
<p>To that end, I&#8217;m looking for a .NET coverage tool to dazzle us with tales of test runs. Over the next little while, I&#8217;ll look at a few candidates, summarize my findings, and hopefully come up with a winner.</p>
<h2>Considerations</h2>
<p>Here are some factors that will influence me. Some of these may be negotiable, if a candidate really shines in other areas.</p>
<ul>
<li>We&#8217;d like to see coverage information in our build reports, so the tool should <b>run from the command line</b>.</li>
<li>It&#8217;d be easier to put the coverage info our our build reports if the <b>coverage reports were in XML</b>.</li>
<li>I really prefer a product that <b>has an auto-deploy</b>, so it can be bundled with the source tree and new developers or build servers just work. You may remember the pains I went to to <a href="/auto-deploying-typemock-isolator-without-trashing-the-installation/">auto-deploy TypeMock Isolator</a>.</li>
<li>While I&#8217;m on the subject, one of our products uses Isolator as its mocking framework, so the coverage tool should be able to <b>link with TypeMock Isolator</b>.</li>
<li>We have a web services layer, which will be exercised by unit tests, but if we could gather stats on the layer as it&#8217;s being exercised by the client-facing portion, that would be gravy. To that end, it should be possible to <b>cover IIS</b>.</li>
<li>When I used TestDriven.NET + NCover a few years ago, I enjoyed being able to quickly see what my tests covered. This isn&#8217;t a requirement of our current initiative, but <b>IDE integration</b> would be a bonus.</li>
<li><b>Price</b> is a factor. Money&#8217;s available, but why spend if you don&#8217;t have to? Or at least, why not pay less for an equivalent product.</li>
</ul>
<h2>The Candidates</h2>
<p>Googling has lead me to these candidates, which I&#8217;ll be examining in the next little while:</p>
<ul>
<li><a href="http://www.jetbrains.com/dotcover/">dotCover</a> (<a href="../../07/29/hasty-impressions-dotcover-1-1/">my impression</a>)</li>
<li><a href="http://www.ncover.com/">NCover</a> (<a href="http:../../11/09/hasty-impressions-ncover/">my impression</a>)</li>
<li><a href="http://sourceforge.net/projects/partcover/">PartCover</a> (<a href="../../08/05/hasty-impressions-partcover/">my impression</a>)</li>
<li><a href="https://github.com/sawilde/opencover">OpenCover</a> (<a href="../../08/15/hasty-impressions-opencover/">my impression</a>)</li>
</ul>
<p><b>Update</b>: <a href="../../12/15/best-all-around-net-coverage-tool-opencover/">I picked one</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/blairconrad.wordpress.com/1031/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/blairconrad.wordpress.com/1031/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/blairconrad.wordpress.com/1031/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/blairconrad.wordpress.com/1031/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/blairconrad.wordpress.com/1031/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/blairconrad.wordpress.com/1031/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/blairconrad.wordpress.com/1031/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/blairconrad.wordpress.com/1031/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/blairconrad.wordpress.com/1031/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/blairconrad.wordpress.com/1031/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/blairconrad.wordpress.com/1031/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/blairconrad.wordpress.com/1031/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/blairconrad.wordpress.com/1031/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/blairconrad.wordpress.com/1031/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blairconrad.wordpress.com&amp;blog=11276730&amp;post=1031&amp;subd=blairconrad&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blairconrad.wordpress.com/2011/07/18/can-you-cover-me-looking-for-a-net-coverage-tool/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<georss:point>43.465187 -80.522372</georss:point>
		<geo:lat>43.465187</geo:lat>
		<geo:long>-80.522372</geo:long>
		<media:content url="http://1.gravatar.com/avatar/707860a1ae9745187b83023e2655e03c?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">blairconrad</media:title>
		</media:content>
	</item>
		<item>
		<title>Prime Time Programming, Part 2</title>
		<link>http://blairconrad.wordpress.com/2011/05/09/prime-time-programming-part-2/</link>
		<comments>http://blairconrad.wordpress.com/2011/05/09/prime-time-programming-part-2/#comments</comments>
		<pubDate>Mon, 09 May 2011 11:00:16 +0000</pubDate>
		<dc:creator>Blair Conrad</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Primes]]></category>
		<category><![CDATA[Profiling]]></category>
		<category><![CDATA[ProjectEuler]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://blairconrad.wordpress.com/?p=979</guid>
		<description><![CDATA[Last time I presented a truly horrible prime number generator I was using for Project Euler problems. Then I presented a revamped generator that used trial division. By adding various refinements to the generator, we saw the time required to generate primes less than 107 shrink from hours to 123 seconds. Today I&#8217;ll describe a [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blairconrad.wordpress.com&amp;blog=11276730&amp;post=979&amp;subd=blairconrad&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="../../04/25/primes-part-1/">Last time</a> I presented a truly horrible prime number generator I was using for <a href="http://projecteuler.net/">Project Euler</a> problems. Then I presented a revamped generator that used trial division. By adding various refinements to the generator, we saw the time required to generate primes less than 10<sup>7</sup> shrink from hours to 123 seconds. Today I&#8217;ll describe a different approach.</p>
<h2>Attempt 2: Sieve of Eratosthenes</h2>
<p>The Sieve of Eratosthenes is another method for finding prime numbers.<br />
The algorithm is basically this:</p>
<ol>
<li>make a big array of numbers, from 2 to the highest prime you&#8217;re hoping to find</li>
<li>look for the next number that&#8217;s not crossed off</li>
<li>this number is your next prime</li>
<li>cross off every multiple of the number you just found</li>
<li>so long as the prime you just found is less than the square root of your limit, go to step 2</li>
<li>the uncrossed numbers are prime</li>
</ol>
<p>Suppose we want primes less than or equal to 20. We start with this list:</p>
<table>
<tr>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
<td>10</td>
<td>11</td>
<td>12</td>
<td>13</td>
<td>14</td>
<td>15</td>
<td>16</td>
<td>17</td>
<td>18</td>
<td>19</td>
<td>20</td>
</tr>
</table>
<p>The first uncrossed off number is 2. That&#8217;s our first prime. Cross off all the multiples of 2 (believe it or not, the 4 is crossed off):</p>
<table>
<tr>
<td><b>2</b></td>
<td>3</td>
<td><s><span style="color:#CCC;">4</span></s></td>
<td>5</td>
<td><s><span style="color:#CCC;">6</span></s></td>
<td>7</td>
<td><s><span style="color:#CCC;">8</span></s></td>
<td>9</td>
<td><s><span style="color:#CCC;">10</span></s></td>
<td>11</td>
<td><s><span style="color:#CCC;">12</span></s></td>
<td>13</td>
<td><s><span style="color:#CCC;">14</span></s></td>
<td>15</td>
<td><s><span style="color:#CCC;">16</span></s></td>
<td>17</td>
<td><s><span style="color:#CCC;">18</span></s></td>
<td>19</td>
<td><s><span style="color:#CCC;">20</span></s></td>
</tr>
</table>
<p>The next uncrossed off number is 3. Cross off the multiples:</p>
<table>
<tr>
<td><b>2</b></td>
<td><b>3</b></td>
<td><s><span style="color:#CCC;">4</span></s></td>
<td>5</td>
<td><s><span style="color:#CCC;">6</span></s></td>
<td>7</td>
<td><s><span style="color:#CCC;">8</span></s></td>
<td><s><span style="color:#CCC;">9</span></s></td>
<td><s><span style="color:#CCC;">10</span></s></td>
<td>11</td>
<td><s><span style="color:#CCC;">12</span></s></td>
<td>13</td>
<td><s><span style="color:#CCC;">14</span></s></td>
<td><s><span style="color:#CCC;">15</span></s></td>
<td><s><span style="color:#CCC;">16</span></s></td>
<td>17</td>
<td><s><span style="color:#CCC;">18</span></s></td>
<td>19</td>
<td><s><span style="color:#CCC;">20</span></s></td>
</tr>
</table>
<p>Next, we have 5. Cross off its multiples (actually, they&#8217;re already crossed off because they&#8217;re all also multiples of either 2 or 3):</p>
<table>
<tr>
<td><b>2</b></td>
<td><b>3</b></td>
<td><s><span style="color:#CCC;">4</span></s></td>
<td><b>5</b></td>
<td><s><span style="color:#CCC;">6</span></s></td>
<td>7</td>
<td><s><span style="color:#CCC;">8</span></s></td>
<td><s><span style="color:#CCC;">9</span></s></td>
<td><s><span style="color:#CCC;">10</span></s></td>
<td>11</td>
<td><s><span style="color:#CCC;">12</span></s></td>
<td>13</td>
<td><s><span style="color:#CCC;">14</span></s></td>
<td><s><span style="color:#CCC;">15</span></s></td>
<td><s><span style="color:#CCC;">16</span></s></td>
<td>17</td>
<td><s><span style="color:#CCC;">18</span></s></td>
<td>19</td>
<td><s><span style="color:#CCC;">20</span></s></td>
</tr>
</table>
<p>5 is greater than &radic;20, so stop looping. All the uncrossed off numbers are prime:</p>
<table>
<tr>
<td><b>2</b></td>
<td><b>3</b></td>
<td><s><span style="color:#CCC;">4</span></s></td>
<td><b>5</b></td>
<td><s><span style="color:#CCC;">6</span></s></td>
<td><b>7</b></td>
<td><s><span style="color:#CCC;">8</span></s></td>
<td><s><span style="color:#CCC;">9</span></s></td>
<td><s><span style="color:#CCC;">10</span></s></td>
<td><b>11</b></td>
<td><s><span style="color:#CCC;">12</span></s></td>
<td><b>13</b></td>
<td><s><span style="color:#CCC;">14</span></s></td>
<td><s><span style="color:#CCC;">15</span></s></td>
<td><s><span style="color:#CCC;">16</span></s></td>
<td><b>17</b></td>
<td><s><span style="color:#CCC;">18</span></s></td>
<td><b>19</b></td>
<td><s><span style="color:#CCC;">20</span></s></td>
</tr>
</table>
<h3>A &#8220;borrowed&#8221; implementation</h3>
<p>The <a href="http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes">wikipedia article</a> even provides a Python implementation, which I reproduce here is slightly altered form:</p>
<p><pre class="brush: python;">
def eratosthenes_sieve(m):
    # Create a candidate list within which non-primes will be
    # marked as None; only candidates below sqrt(m) need be checked. 
    candidates = range(m+1)
    fin = int(m**0.5)
 
    # Loop over the candidates, marking out each multiple.
    for i in xrange(2, fin+1):
        if not candidates[i]:
            continue
 
        candidates[2*i::i] = [None] * (m//i - 1)
 
    # Filter out non-primes and return the list.
    return [i for i in candidates[2:] if i]
</pre><br />
I ran this to find my standard list of primes less than 10<sup>7</sup>, and was surprised at the results. The time to completion varied wildly on successive runs. Sometimes over <b>50</b> seconds, and sometimes as low as <b>13</b>. I noticed that when the run times were high, the laptop&#8217;s hard drive was thrashing, and just afterward my other applications were unresponsive. </p>
<p>I reran the test and, with a little help from PerfMon, found out that the memory usage was off the chart. No, seriously. Right off the top. I had to rescale the graph to get everything to fit. the Private Bytes went way up over 200MB. On my 512 MB laptop with Firefox, emacs, and a few background processes, things slow to a crawl. With a smaller set of primes, or on more powerful iron, this implementation may work, but it&#8217;s not going to meet my needs.</p>
<h2>Attempt 3: The Sieve, but slowly cross out the composites</h2>
<p>If allocating a big array of numbers just to cross most of them out right away doesn&#8217;t work, how about we start by allocating nothing and just cross out numbers at the last moment?<br />
The idea is pretty simple: start counting at 2, and keep a record of upcoming composite numbers that we&#8217;ve discovered by looking at multiples of primes so far. Essentially we maintain a rolling wave of the next multiples of 2, 3, 5, &hellip;:</p>
<ol>
<li>let <code>composites = {}</code>, an empty associative array, where each key is a composite number and its value is the prime that it&#8217;s a multiple of</li>
<li>let <code>n = 2</code></li>
<li>if n is a known composite, remove it and insert the next multiple in the list</li>
<li>otherwise, it&#8217;s prime. Yield it and insert a new composite, <code>n<sup>2</sup></code></li>
<li>increment n</li>
<li>go to step 3</li>
</ol>
<h3>Let&#8217;s see how it works</h3>
<table>
<tr>
<th>n</th>
<th>composites</th>
</tr>
<tr>
<td><code>2</td>
<td>{}</code></td>
<td><b>2</b> isn&#8217;t in composites, so yield it. Then insert 2<sup>2</sup> = 4 and increment n.</td>
</tr>
<tr>
<td><code>3</td>
<td>{4:2}</code></td>
<td><b>3</b> isn&#8217;t in composites, so yield it. Then insert 3<sup>2</sup> = 9 and increment n.</td>
</tr>
<tr>
<td><code>4</td>
<td>{4:2, 9:3}</code></td>
<td>4 is in composites, with value 2. Remove it, insert 4 + 2 = 6 and incremenet n.</td>
</tr>
<tr>
<td><code>5</td>
<td>{6:2, 9:3}</code></td>
<td><b>5</b> isn&#8217;t in composites, so yield it. Then insert 5<sup>2</sup> = 25 and increment n.</td>
</tr>
<tr>
<td><code>6</td>
<td>{6:2, 9:3, 25:5}</code></td>
<td>6 is in composites, with value 2. Remove it, insert 6  + 2 = 8 and incremenet n.</td>
</tr>
<tr>
<td><code>7</td>
<td>{8:2, 9:3, 25:5}</code></td>
<td><b>7</b> isn&#8217;t in composites, so yield it. Then insert 7<sup>2</sup> = 49 and increment n.</td>
</tr>
<tr>
<td><code>8</td>
<td>{8:2, 9:3, 25:5, 49:7}</code></td>
<td>8 is in composites, with value 2. Remove it, insert 8 + 2 = 10 and increment n.</td>
</tr>
<tr>
<td><code>9</td>
<td>{9:3, 10:2, 25:5, 49:7}</code></td>
<td>9 is in composites, with value 3. Remove it, insert 9 + 3 = 12 and increment n.</td>
</tr>
<tr>
<td><code>10</td>
<td>{10:2, 12:3, 25:5, 49:7}</code></td>
<td>10 is in composites, with value 2. Remove it, and&#8230; <b>wait</b>.</td>
</tr>
</table>
<p>12 is already in the list, because it&#8217;s a multiple of 3.  We can&#8217;t insert it. We&#8217;ll have to amend the algorithm to account for collisions. If a multiple is already accounted for, keep moving until we find one that isn&#8217;t in the list.</p>
<p>In this case, add another 2 to 12 to get 14 and insert it. Then increment n.</p>
<table>
<tr>
<th>n</th>
<th>composites</th>
</tr>
<tr>
<td><code>11</td>
<td>{12:3, 14:2, 25:5, 49:7}</code></td>
<td><b>11</b> isn&#8217;t in composites, so yield it, insert 11<sup>2</sup> = 121, increment n, and continue&hellip;</td>
</tr>
</table>
<h3>Show me the code</h3>
<p>Here&#8217;s an implementation of the <b>naive algorithm</b> presented above<br />
<pre class="brush: python;">
def sieve():
    composites = {}
    n = 2
    while True:
        factor = composites.pop(n, None)
        if factor:
            q = n + factor
            while composites.has_key(q):
                q += factor
            composites[q] = factor
        else:
            # not there - prime
            composites[n*n] = n
            yield n
        n += 1
</pre><br />
This implementation takes <b>26.8</b> seconds to generate all primes below 10<sup>7</sup>,  close to &#188; the time the best trial division algorithm took.</p>
<h3>Why is this method so great?</h3>
<ul>
<li>Using the associative array values to remember which &#8220;stream&#8221; of multiples each composite comes from means that the array is no bigger than the number of primes we&#8217;ve seen so far</li>
<li>The primes can be yielded as soon they&#8217;re found instead of waiting until the end</li>
<li>Adding p<sup>2</sup> when we find a new prime cuts down on collisions but still ensures that we&#8217;ll keep find all multiples of p, because 2p, 3p, &hellip;, (p-1)p will be weeded out as multiples of lower primes.</li>
<li>There&#8217;s very little wasted work &#8211; finding a new prime number takes O(1) operations &#8211; just checking that the number isn&#8217;t in the associative array and adding the square to the array. Many composites will take more work, but an amount proportional to the number of distinct prime factors the number has. For example, 12 has prime factors 2, 2, and 3. We tried to add 12 to the array twice, once as a multiple of 2 and once as a multiple of 3. Fortunately, the number of distinct factors is severely limited. For numbers less than 10<sup>7</sup>, 9699690 has the most distinct prime factors: 2, 3, 5, 7, 11, 13, 17, 19. This sure beats the 446 divisions trial division took to find that 9999991 was prime.
</ul>
<p>The method already incorporates some of the advantages of the souped-up trial division methods from last time. We only worry about multiples of primes, so there&#8217;s no need to cut out the composite factors. And when checking to see if n is prime, we never consider prime factors larger than &radic;n. Still, there are some optimizations to make.</p>
<h3>That&#8217;s Odd</h3>
<p>In the sample runthrough above, the algorithm checks 4, 6, 8, 10, &hellip; for primality, even though no even number larger than 2 are prime. Here&#8217;s an implementation that avoids that:<br />
<pre class="brush: python; highlight: [3,4,8,10,16];">
 def odd_sieve():
    composites = {}
    yield 2
    n = 3
    while True:
        factor = composites.pop(n, None)
        if factor:
            q = n + 2 * factor
            while composites.has_key(q):
                q += 2 * factor
            composites[q] = factor
        else:
            # not there - prime
            composites[n*n] = n
            yield n
        n += 2
</pre></p>
<p>This method generates primes less than 10<sup>7</sup> in <b>13.4</b> seconds. This is about half the time it took when we didn&#8217;t pre-filter the evens. In the trial division case, when we cut out the even numbers, we were saving almost no work &#8211; one division per even number, out of potentially dozens or hundreds of divisions being performed. This time, we cut out an associative array lookup and insertion, and most numbers are checked by using only a small number of these operations. Let&#8217;s see what else we can do.</p>
<h2>What about 3?</h2>
<p>If skipping the numbers that are divisible by 2 paid off, will skipping those divisible by 3 as well? Probably.<br />
<pre class="brush: python; highlight: [4,5,6,11,18,19];">
def sixish_sieve():
    composites = {}
    yield 2
    yield 3
    step = 2
    n = 5
    while True:
        factor = composites.pop(n, None)
        if factor:
            q = n + 2 * factor
            while q % 6 == 3 or composites.has_key(q):
                q += 2 * factor
            composites[q] = factor
        else:
            # not there - prime
            composites[n*n] = n
            yield n
        n += step
        step = 6 - step
</pre><br />
Now the time to generate primes less than 10<sup>7</sup> is <b>11.9</b> seconds. Again, I think we&#8217;ve hit diminishing returns. We didn&#8217;t get the 1/3 reduction I&#8217;d hoped, probably due to the more complicated &#8220;next multiple&#8221; calculation.</p>
<h3>YAGNI</h3>
<p>Things are going pretty well. There&#8217;s only one thing that bothers me about the latest generator &#8211; we&#8217;re storing too many composites in the associative array. Every time we find a prime number, its square is inserted in the array. Even 9999991<sup>2</sup> is put in the array, even though we&#8217;ll never check to see if any number greater than 10<sup>7</sup> is prime. So, modifying the algorithm to omit storing composites that are too large, we get:<br />
<pre class="brush: python; highlight: [16];">
def sixish_sieve_max():
    composites = {}
    yield 2
    yield 3
    step = 2
    n = 5
    while True:
        factor = composites.pop(n, None)
        if factor:
            q = n + 2 * factor
            while q % 6 == 3 or composites.has_key(q):
                q += 2 * factor
            composites[q] = factor
        else:
            # not there - prime
            if n*n &lt;= highest:
                composites[n*n] = n
            yield n
        n += step
        step = 6 - step
</pre></p>
<p>This generator takes <b>10.8</b> seconds to generate primes below 10<sup>7</sup> &#8211; modest improvement, and one I&#8217;d keep anyhow, since the code is barely more complicated than the previous version. However, the real boost, if there is any, is in the memory usage. When <code>sixish_sieve</code>  generates primes below 10<sup>7</sup>, the private bytes climb up to 52MB, but <code>sixish_sieve_max</code> stays below 25MB. The advantage continues as the problem set grows &#8211; when the upper limit is 2*10<sup>7</sup>, <code>sixish_sieve</code> takes 100MB, but <code>sixish_sieve_max</code> remains at a cool 25MB &#8211; I guess that&#8217;s the difference between storing 1270607 composites and 607.</p>
<h2>Conclusion</h2>
<p>This was a fun and interesting exercise. Being able to look bad at your old code and say &#8220;Boy, that was horrible. I&#8217;m glad I&#8217;m smarter now,&#8221; makes me happy. And embarrassed. I enjoyed seeing how applying incremental changes and even rudimentary profiling yielded provably better results, right up until they showed that I probably needed to abandon my current path (trial division) and jump on a new one.</p>
<p>I&#8217;m sticking with <code>sixish_sieve_max</code> for now. It&#8217;s fast enough to meet my current needs, and will likely remain so until &#8220;CPU inflation&#8221; forces the Project Euler team to increase the size of their problem sets. Of course, maybe by then <i>I&#8217;ll</i> have a faster processor and I won&#8217;t care.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/blairconrad.wordpress.com/979/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/blairconrad.wordpress.com/979/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/blairconrad.wordpress.com/979/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/blairconrad.wordpress.com/979/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/blairconrad.wordpress.com/979/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/blairconrad.wordpress.com/979/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/blairconrad.wordpress.com/979/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/blairconrad.wordpress.com/979/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/blairconrad.wordpress.com/979/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/blairconrad.wordpress.com/979/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/blairconrad.wordpress.com/979/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/blairconrad.wordpress.com/979/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/blairconrad.wordpress.com/979/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/blairconrad.wordpress.com/979/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blairconrad.wordpress.com&amp;blog=11276730&amp;post=979&amp;subd=blairconrad&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blairconrad.wordpress.com/2011/05/09/prime-time-programming-part-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<georss:point>43.465187 -80.522372</georss:point>
		<geo:lat>43.465187</geo:lat>
		<geo:long>-80.522372</geo:long>
		<media:content url="http://1.gravatar.com/avatar/707860a1ae9745187b83023e2655e03c?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">blairconrad</media:title>
		</media:content>
	</item>
		<item>
		<title>Prime Time Programming, Part 1</title>
		<link>http://blairconrad.wordpress.com/2011/04/25/primes-part-1/</link>
		<comments>http://blairconrad.wordpress.com/2011/04/25/primes-part-1/#comments</comments>
		<pubDate>Mon, 25 Apr 2011 11:00:59 +0000</pubDate>
		<dc:creator>Blair Conrad</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Primes]]></category>
		<category><![CDATA[Profiling]]></category>
		<category><![CDATA[ProjectEuler]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://blairconrad.wordpress.com/?p=914</guid>
		<description><![CDATA[From time to time, I find myself caught up in the heady world of Project Euler. It&#8217;s almost like playing Professor Layton or some other puzzle-solving game &#8211; mathematical or programming brain teasers, served in bite-sized pieces. If you look at the Project Euler problems for any length of time, you&#8217;ll notice common themes. One [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blairconrad.wordpress.com&amp;blog=11276730&amp;post=914&amp;subd=blairconrad&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>From time to time, I find myself caught up in the heady world of <a href="http://projecteuler.net/" title="&quot;Project Euler is a series of challenging mathematical/computer programming problems that will require more than just mathematical insights to solve. Although mathematics will help you arrive at elegant and efficient methods, the use of a computer and programming skills will be required to solve most problems.&quot;">Project Euler</a>. It&#8217;s almost like playing <a href="http://professorlaytonds.com/">Professor Layton</a> or some other puzzle-solving game &#8211; mathematical or programming brain teasers, served in bite-sized pieces.</p>
<p>If you look at the Project Euler problems for any length of time, you&#8217;ll notice common themes. One theme is <a href="http://en.wikipedia.org/wiki/Prime_number">prime numbers</a> &#8211; many problems can&#8217;t be solved without generating varying quantities of primes. To that end, I&#8217;d written a prime generator to be shared between problem solutions. Over time, I added functionality and &#8220;optimized&#8221; the generator to improve the running time of my solutions. Everything was great, until I tried <a href="http://projecteuler.net/index.php?section=problems&amp;id=315" title="Digital root clocks">Problem 315</a>, whose solution required a list of primes between 10<sup>7</sup> and 2&times;10<sup>7</sup>. My solution worked, but it ran really slowly &#8211; something like 12 minutes. Now, I&#8217;m not doing myself any favours by writing in Python and running on a 7-year-old laptop, but that&#8217;s still too long.</p>
<h2>My Original Generator</h2>
<p>This is the slow-performing generator that I replaced when working on Problem 315. The squeamish reader may want to avert his eyes.<br />
<pre class="brush: python; collapse: true; light: false; toolbar: true;">
class PrimeGenerator:
    __primes_so_far = [5]
    __increment = 2

    def __init__(self):
        self.__next_index = -1


    def is_prime(self, n):
        if n == 2 or n == 3:
            return True
        elif n % 2 == 0 or n %3 == 0:
            return False
        elif n &lt;= PrimeGenerator.__primes_so_far[-1]:
            # bisecting didn't really help
            return n in PrimeGenerator.__primes_so_far
        else:
            return self.__is_prime(n)

    def __is_prime(self, n):
        limit = math.sqrt(n)
        g = PrimeGenerator()
        g.next() # skip 2
        g.next() # skip 3
        p = g.next()
        while p &lt;= limit:
            if  n % p == 0:
                return False
            p = g.next()
        return True
        
    def next(self):
        self.next = self.__next3
        return 2

    def __next3(self):
        self.next = self.__next5
        return 3

    def __next5(self):
        self.__next_index += 1
        if self.__next_index &lt; len(PrimeGenerator.__primes_so_far):
            return PrimeGenerator.__primes_so_far[self.__next_index]
            
        candidate = PrimeGenerator.__primes_so_far[-1]

        while True:
            candidate += PrimeGenerator.__increment
            PrimeGenerator.__increment = 6 - PrimeGenerator.__increment
        
            if self.__is_prime(candidate):
                PrimeGenerator.__primes_so_far.append(candidate)
                return candidate

    def __iter__(self):
        return self
</pre></p>
<h3>My eyes!</h3>
<p>When I first went back to this code, I exclaimed, &#8220;What was I thinking?&#8221;. I can think of two things:</p>
<ol>
<li>The <code>is_prime</code> member was intended to help out for problems where I didn&#8217;t have to create too many primes, but just had to check a few number for primality. This doesn&#8217;t really belong here, and clutters the class. I&#8217;d be better off focusing on prime generation.</li>
<li>I was optimizing at least partly for the case where I&#8217;d want to get lists of primes a couple times&mdash;hence the indexing into an already-generated list of primes. If the generator were fast enough, this wouldn&#8217;t be necessary.</li>
</ol>
<p>Things I can&#8217;t understand, even today. I&#8217;ll have to blame them on then-ignorance, foolishness, and hasty modifications to the class:</p>
<ul>
<li>Why the mucking about with <code>__next3</code> and <code>__next5</code>? What did I have against <a href="http://docs.python.org/reference/simple_stmts.html#yield">yield</a>?</li>
<li>Why is <code>is_prime</code> fussing with a whole new <code>PrimeGenerator</code> and skipping 2 and 3? Why not just go straight for the saved list of primes starting with 5?</li>
</ul>
<p>In fact, just about the only defensible things (as we&#8217;ll see below) in the whole class are:</p>
<ul>
<li>ending the modulus checks once the candidate divisor is greater than the square root of the candidate number, and</li>
<li>the bit where the next<code>__increment</code> is formed by subtracting the current one from 6 &#8211; I was exploiting the fact that, past 3, for any prime <i>p</i>, p &equiv; 1 (mod 6) or p &equiv; 5 (mod 6).</li>
</ul>
<h3>How slow was it?</h3>
<p>The generator took <b>551.763 seconds</b> to generate primes less than <b>10<sup>7</sup></b>, as measured by the following:<br />
<pre class="brush: python;">
def run(f):
    global highest
    start = datetime.datetime.now()
    count = 1
    for p in f:
        count += 1
        if p &gt; highest: break
    end = datetime.datetime.now()
    elapsed = end-start
    return highest, count, elapsed.seconds + (elapsed.microseconds/1000000.0)
</pre><br />
Where <code>f</code> is an instance of <code>PrimeGenerator</code> passed into the <code>run</code> method, and <code>highest</code> is a global that&#8217;s been set to 10<sup>7</sup>. </p>
<h2>Moving forward</h2>
<p>Based on the extreme slowness and general horribleness of the code, I figured I&#8217;d be better off starting over. So, I chucked the generator and started afresh with the simplest generator I could write. I resolved to make incremental changes, ensuring that at each step, the code was:</p>
<ol>
<li>correct (otherwise, why bother)</li>
<li>faster than the previous version</li>
<li>simple enough for me to understand</li>
</ol>
<p>Let&#8217;s see what happened.</p>
<h2>Attempt 1: Trial Division</h2>
<p><a href="http://en.wikipedia.org/wiki/Trial_division">Trial division</a> is one of the simplest methods for generating primes&mdash;you start counting at 2, and if no smaller positive integers (other than 1) divide the current number, it&#8217;s prime. The <b>naive implementation</b> is very simple.<br />
<pre class="brush: python;">
def naive_trial():
    n = 2
    while True:
        may_be_prime = True
        for k in xrange(2, n):
            if n % k == 0:
                may_be_prime = False
                break
        if may_be_prime:
            yield n
        n += 1
</pre><br />
This method takes <b>113.804 seconds</b> to generate primes below <b>100000</b>&mdash;I couldn&#8217;t wait for the full 10<sup>7</sup> &#8211; it would probably be over 3 hours.</p>
<h3>Trial until root</h3>
<p>Fortunately, there are some pretty obvious optimizations one can make to the algorithm. The first comes from the observation that if there is a number k, 1 &lt; k &lt; n, that divides n, then there is a number j that divides n with 1 &lt; j &le; &radic;n, so we can stop our trial once we&#8217;ve hit that point.</p>
<p><pre class="brush: python; highlight: [5];">
def trial_until_root():
    n = 2
    while True:
        may_be_prime = True
        for k in xrange(2, int(n**0.5)+1):
            if n % k == 0:
                may_be_prime = False
                break
        if may_be_prime:
            yield n
        n += 1
</pre><br />
This method takes <b>468 seconds</b> to generate primes up to 10<sup>7</sup>. A definite improvement (and already faster my original generator), but there&#8217;s still room for more.</p>
<h3>Trial by primes</h3>
<p>Here&#8217;s another observation about divisors of n: if there&#8217;s a number k that divides n, then there&#8217;s a prime number p &le; k that divides n, since either k is prime or has prime factors. So if we keep a list of the primes found so far, we only need to check prime divisors that are less than &radic;n.</p>
<p><pre class="brush: python; highlight: [2,6,10,11,13];">
def trial_by_primes():
    primes_so_far = []
    n = 2
    while True:
        may_be_prime = True
        for p in primes_so_far:
            if n % p == 0:
                may_be_prime = False
                break
            if p * p &gt; n: # it's prime
                break
        if may_be_prime:
            primes_so_far.append(n)
            yield n
        n += 1
</pre></p>
<p>Now we&#8217;re down to <b>136 seconds</b> to generate primes below 10<sup>7</sup>. That was a worthwhile change, but we have to balance it against the fact that the generator now requires additional storage &#8211; the list of primes encountered so far. In this case, we&#8217;re storing over 660,000 prime numbers in a list. Even an older laptop can handle this burden, but it&#8217;s something to keep in mind.</p>
<h3>That&#8217;s odd</h3>
<p>And by &#8220;that&#8221;, I mean &#8220;all the prime numbers except for 2&#8243;. There&#8217;s no point checking the even numbers to see if they&#8217;re prime. Let&#8217;s see what happens when we skip them. The only tricky part (and it&#8217;s not that tricky) is to make sure we still return 2 as our first prime.</p>
<p><pre class="brush: python; highlight: [3,4,16];">
def odd_trial_by_primes():
    primes_so_far = []
    yield 2
    n = 3
    while True:
        may_be_prime = True
        for p in primes_so_far:
            if n % p == 0:
                may_be_prime = False
                break
            if p * p &gt; n: # it's prime
                break
        if may_be_prime:
            primes_so_far.append(n)
            yield n
        n += 2
</pre><br />
This method takes <b>127 seconds</b> to generate primes less than 10<sup>7</sup>. Not a huge improvement, but better than nothing, and it doesn&#8217;t really complicate the code that much.  I&#8217;ll keep it. The reason we don&#8217;t get a huge improvement here is that checking the even numbers for primeness doesn&#8217;t take that much effort &#8211; they were eliminated as soon as we modded them by the first prime in <code>primes_so_far</code>. Still, it&#8217;s a little quicker to jump right over them than to perform the division.</p>
<h3>What about 3?</h3>
<p>If skipping the numbers that are divisible by 2 paid off, will skipping those divisible by 3? As I noted above, every prime <i>p</i> greater than 3 satisfies <code>p &equiv; 1 (mod 6) or p &equiv; 5 (mod 6)</code>. Let&#8217;s use that. We&#8217;ll take advantage of these facts:</p>
<ul>
<li>if p &equiv; 1 (mod 6) , then p+4 &equiv; 5 (mod 6)</li>
<li>if p &equiv; 5 (mod 6) , then p+2 &equiv; 1 (mod 6)</li>
</ul>
<p>So we want to alternate our <code>step</code> between 2 and 4. Fortunately 6 &#8211; 4 = 2 and 6 &#8211; 2 = 4, so we can use 6 &#8211; step as our next step.<br />
<pre class="brush: python; highlight: [4,5,6,18,19];">
def sixish_trial_by_primes():
    primes_so_far = []
    yield 2
    yield 3
    step = 2
    n = 5
    while True:
        may_be_prime = True
        for p in primes_so_far:
            if n % p == 0:
                may_be_prime = False
                break
            if p * p &gt; n: # it's prime
                break
        if may_be_prime:
            primes_so_far.append(n)
            yield n
        n += step
        step = 6 - step
</pre><br />
Now the time drops to <b>123</b> seconds to generate primes less than 10<sup>7</sup>. Clearly we&#8217;ve hit diminishing returns &#8211; we&#8217;re saving two modulus operations on numbers that are divisible by 3 (but not 2), at the cost of a more complicated &#8220;step&#8221; calculation. We could continue on in this vein, but the gains are not likely to be large, and the complexity increases rapidly. Consider the next step: we&#8217;d make sure we don&#8217;t test numbers divisible by 2, 3, or 5. That means (after 5) we only consider numbers whose remainders when divided by 30 are one of 1, 7, 11, 13, 17, 19, 23, or 29. The steps between numbers are 6, 4, 2, 4, 2, 4, 6, and 2. Who has the energy?</p>
<h2>The problem with Trial Division</h2>
<p>Trial division has a few things going for it:</p>
<ul>
<li>it&#8217;s simple to understand</li>
<li>there are some obvious optimizations that can make its performance tolerable</li>
</ul>
<p>Ultimately, though, its downfall is that it takes a lot of work to verify that a large number is prime. Consider the largest prime number below 10<sup>7</sup>: 9999991. In order to verify that this is prime, we have to consider all prime factors less than &radic;9999991. There are 446 of these. That&#8217;s 446 divisions, just to verify that one number is prime. </p>
<p>We&#8217;re unlikely to radically improve performance by continuing to tinker with trial division. It&#8217;s time to throw the whole thing away again and try a new approach. Next time we&#8217;ll do just that.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/blairconrad.wordpress.com/914/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/blairconrad.wordpress.com/914/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/blairconrad.wordpress.com/914/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/blairconrad.wordpress.com/914/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/blairconrad.wordpress.com/914/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/blairconrad.wordpress.com/914/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/blairconrad.wordpress.com/914/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/blairconrad.wordpress.com/914/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/blairconrad.wordpress.com/914/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/blairconrad.wordpress.com/914/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/blairconrad.wordpress.com/914/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/blairconrad.wordpress.com/914/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/blairconrad.wordpress.com/914/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/blairconrad.wordpress.com/914/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blairconrad.wordpress.com&amp;blog=11276730&amp;post=914&amp;subd=blairconrad&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blairconrad.wordpress.com/2011/04/25/primes-part-1/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<georss:point>43.465187 -80.522372</georss:point>
		<geo:lat>43.465187</geo:lat>
		<geo:long>-80.522372</geo:long>
		<media:content url="http://1.gravatar.com/avatar/707860a1ae9745187b83023e2655e03c?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">blairconrad</media:title>
		</media:content>
	</item>
		<item>
		<title>How to completely disable Autofac components</title>
		<link>http://blairconrad.wordpress.com/2011/02/27/completely-disabling-autofac-components/</link>
		<comments>http://blairconrad.wordpress.com/2011/02/27/completely-disabling-autofac-components/#comments</comments>
		<pubDate>Sun, 27 Feb 2011 12:00:26 +0000</pubDate>
		<dc:creator>Blair Conrad</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[Autofac]]></category>

		<guid isPermaLink="false">http://blairconrad.wordpress.com/?p=945</guid>
		<description><![CDATA[This week I started working with the Autofac Inversion of Control container at the Day Job. The first project I tried to introduce Autofac to needed a plugin system. I figured this was a perfect use of Autofac&#8217;s implicit relationship handlers. Sure enough, a did the trick &#8211; I got a nice list of plugin [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blairconrad.wordpress.com&amp;blog=11276730&amp;post=945&amp;subd=blairconrad&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>This week I started working with the <a href="http://code.google.com/p/autofac/">Autofac</a> <a href="http://www.martinfowler.com/articles/injection.html">Inversion of Control container</a> at the Day Job. The first project I tried to introduce Autofac to needed a plugin system. I figured this was a perfect use of <a href="http://nblumhardt.com/2010/01/the-relationship-zoo/">Autofac&#8217;s implicit relationship handlers</a>. Sure enough, a<br />
<pre class="brush: csharp; light: true;">
container.Resolve&lt;IEnumerable&lt;IPlugin&gt;&gt;()
</pre><br />
did the trick &#8211; I got a nice list of plugin instances for the application to use.</p>
<p>This isn&#8217;t enough, though. We need to disable certain components via configuration. One option would be to remove the components from the configuration file, but I wanted to make it easy to restore the plugins (and their original configuration) should the need arise. After poring over the Autofac documentation, it seemed like adding an &#8220;Enabled&#8221; flag in the components&#8217; metadata would be the best way to handle toggling them between on and off. </p>
<p>Setting up the config file was straightforward,<br />
<pre class="brush: xml;">
&lt;autofac defaultAssembly=&quot;DisableComponents&quot;&gt;
  &lt;components&gt;
    &lt;component type=&quot;DisableComponents.Plugin1&quot; service=&quot;DisableComponents.IPlugin&quot;&gt;
      &lt;metadata&gt;
        &lt;item name=&quot;Enabled&quot; value=&quot;false&quot; type=&quot;System.Boolean&quot; /&gt;
      &lt;/metadata&gt;
    &lt;/component&gt;
    &lt;component type=&quot;DisableComponents.Plugin2&quot; service=&quot;DisableComponents.IPlugin&quot;&gt;
      &lt;metadata&gt;
        &lt;item name=&quot;Enabled&quot; value=&quot;true&quot; type=&quot;System.Boolean&quot; /&gt;
      &lt;/metadata&gt;
    &lt;/component&gt;
  &lt;/components&gt;
&lt;/autofac&gt;
</pre><br />
as was filtering the components list.<br />
<pre class="brush: csharp;">
var enabledComponents = container.Resolve&lt;IEnumerable&lt;Meta&lt;IPlugin&gt;&gt;&gt;()
    .Where(ComponentIsEnabled)
    .Select(c=&gt;c.Value);

...

private static bool ComponentIsEnabled&lt;T&gt;(Meta&lt;T&gt; component)
{
    const string enabled = &quot;Enabled&quot;;
    return !component.Metadata.ContainsKey(enabled) || (bool)component.Metadata[enabled];
}
</pre></p>
<h2>They&#8217;re still created, though</h2>
<p>This approach worked, but all all components are instantiated, including the disabled ones which are made just so we can throw them away. This seems a little wasteful. Worse, a particular installation may have a plugin disabled because it can&#8217;t (or doesn&#8217;t want to) support its creation. So I sought a way to prevent the instantiation of the unwanted plugins.</p>
<p>I tried to find a way to remove or disallow registration based on the metadata, or to intercept component creation, but came up short. The best I could come up with was a modification to the approach above:<br />
<pre class="brush: csharp;">
var enabledComponents = container.Resolve&lt;IEnumerable&lt;Meta&lt;Func&lt;IPlugin&gt;&gt;&gt;&gt;()
    .Where(ComponentIsEnabled)
    .Select(c=&gt;c.Value());
</pre></p>
<p>(I would have preferred to use a <a href="http://msdn.microsoft.com/en-us/library/dd642331.aspx">Lazy</a> over a <a href="http://msdn.microsoft.com/en-us/library/bb534960.aspx">Func</a>, but I&#8217;m working with .Net&nbsp;35.)</p>
<p>This works&mdash;the plugins are only created when they&#8217;re enabled&mdash;but it feels inelegant.<br />
I can&#8217;t help but think that my Autofac knowledge is too shallow to have discovered the &#8220;right&#8221; way to do this. Hopefully deeper understanding will come in time&hellip;</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/blairconrad.wordpress.com/945/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/blairconrad.wordpress.com/945/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/blairconrad.wordpress.com/945/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/blairconrad.wordpress.com/945/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/blairconrad.wordpress.com/945/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/blairconrad.wordpress.com/945/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/blairconrad.wordpress.com/945/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/blairconrad.wordpress.com/945/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/blairconrad.wordpress.com/945/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/blairconrad.wordpress.com/945/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/blairconrad.wordpress.com/945/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/blairconrad.wordpress.com/945/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/blairconrad.wordpress.com/945/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/blairconrad.wordpress.com/945/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blairconrad.wordpress.com&amp;blog=11276730&amp;post=945&amp;subd=blairconrad&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blairconrad.wordpress.com/2011/02/27/completely-disabling-autofac-components/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<georss:point>43.465187 -80.522372</georss:point>
		<geo:lat>43.465187</geo:lat>
		<geo:long>-80.522372</geo:long>
		<media:content url="http://1.gravatar.com/avatar/707860a1ae9745187b83023e2655e03c?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">blairconrad</media:title>
		</media:content>
	</item>
		<item>
		<title>Growing an MVVM Framework in 2003, part V – Reflections and Regrets</title>
		<link>http://blairconrad.wordpress.com/2011/02/15/growing-an-mvvm-framework-in-2003-part-v-%e2%80%93-reflections-and-regrets/</link>
		<comments>http://blairconrad.wordpress.com/2011/02/15/growing-an-mvvm-framework-in-2003-part-v-%e2%80%93-reflections-and-regrets/#comments</comments>
		<pubDate>Tue, 15 Feb 2011 12:21:17 +0000</pubDate>
		<dc:creator>Blair Conrad</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[Frameworks]]></category>
		<category><![CDATA[MVVM]]></category>

		<guid isPermaLink="false">http://blairconrad.wordpress.com/?p=888</guid>
		<description><![CDATA[This post is from a series on my experiences starting to grow an MVVM Framework in .NET 1.1. Part I &#8211; Event Handlers Part II &#8211; Properties Part III &#8211; Properties Redux Part IV &#8211; Unit Tests Part V &#8211; Reflections and Regrets Full source code can be found in my Google Code repository. I [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blairconrad.wordpress.com&amp;blog=11276730&amp;post=888&amp;subd=blairconrad&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<div style="padding-left:.5em;padding-right:.5em;margin-left:2em;margin-right:2em;border:1px solid #EEE;background-color:#F8F8F8;">
<p>This post is from a series on my experiences starting to grow an MVVM Framework in .NET 1.1.</p>
<ul>
<li><a href="../../../2010/10/29/growing-an-mvvm-framework-in-2003-part-i-event-handlers/">Part I &#8211; Event Handlers</a></li>
<li><a href="../../../2010/11/10/growing-an-mvvm-framework-in-2003-part-ii-properties/">Part II &#8211; Properties</a></li>
<li><a href="../../../2010/11/21/growing-an-mvvm-framework-in-2003-part-iii-properties-redux/">Part III &#8211; Properties Redux</a></li>
<li><a href="../../..//2010/11/30/growing-an-mvvm-framework-in-2003-part-iv-unit-tests/">Part IV &#8211; Unit Tests</a></li>
<li>Part V &#8211; Reflections and Regrets</li>
</ul>
<p>Full source code can be found in my <a href="http://code.google.com/p/blairconrad/source/browse/#svn/trunk/BlogExamples/2010-11-mvvm-.net1.1/BookFinder">Google Code repository</a>.</p>
</div>
<p>I haven&#8217;t added any articles to this series in a while. The main reason is that I&#8217;ve not done any more work on the framework. I was able to complete my application using the tools using the Framework So Far, and I&#8217;ve long since moved on to other projects.  I wanted, though, to take a quick look back and evaluate the project.</p>
<h2>I did it!</h2>
<p>Way back in part&nbsp;1, I said that I wanted to create an application that </p>
<ul>
<li>had testable logic, even in the GUI layer,</li>
<li>had no “codebehind” in the view, and</li>
<li>shunted the tedious wiring up of events and handlers into helpers (or a “framework”)</li>
</ul>
<p>I&#8217;m very pleased with how all this turned out. Taking things in reverse order:</p>
<ul>
<li>The little framework does an excellent job of handling the tedious event-wiring. Handling an View event requires nothing more than declaring a method with a convention-following name and the correct signature, such as <pre class="brush: csharp; light: true;">public void FindClick(object sender, EventArgs e)</pre><br />
Properties are wired up in a similar way, by declaring a public field with a convention-following name and an appropriate type (StringProperty, BoolProperty, or ListProperty).</li>
<li>Aside from setting some properties on View elements (for example, the Find button is initial disabled), there was no need to crack open the View&#8217;s .cs file &#8211; I never saw the inside of it.</li>
<li>The easily-invoked event handlers and the property bindings made writing unit test as easy as writing tests for a non-GUI component: set some initial properties, poke the ViewModel by invoking an event handler, and check the properties. Done! Injecting mock model components was the hardest thing, and that&#8217;s no different than in any other test.</li>
</ul>
<h2>If only I had</h2>
<p>There was one nagging problem that I left unresolved. My Model contains only synchronous operations, so the View doesn&#8217;t update while we&#8217;re accessing the data store. As it turns out, the operations are very quick, so the user is unlikely to notice. </p>
<p>I could have implemented asynchronous operations on the view, or used delgates or background threads to explicitly invoke the model in the background. I really would&#8217;ve liked to implement something that would be applicable to a larger problem set. Something like <a href="http://devlicio.us/blogs/rob_eisenberg/archive/2010/08/21/caliburn-micro-soup-to-nuts-part-5-iresult-and-coroutines.aspx">Caliburn.Micro&#8217;s IResult and Coroutines</a>:<br />
Returning an <code>IResult</code> or a collection of them to be executed on background threads by the framework, while the GUI updates and the ViewModel is none the wiser.</p>
<p>Ah well, time was running out, and there didn&#8217;t seem to be that much benefit. Maybe next time&#8230;</p>
<h2>I would have liked to</h2>
<p>There are a few other &#8220;features&#8221; that I would&#8217;ve liked to add to the framework, but there wasn&#8217;t time, nor did there seem to be an immediate need:</p>
<ul>
<li><b>a View binder</b> &mdash; After writing a class to bind the ViewModel to the fake storage properties, I realized that that was a nicer approach than having the binding code in the  ViewModelBase. I&#8217;d like create a &#8220;production binder&#8221; to hook up the ViewModel and View.</li>
<li><b>composable ViewModels</b> &mdash; BookFinder is very simple, with only a TextBox and a few ListBoxes and Buttons on its View, so a single View and ViewModel was sufficient. It would be useful to be able to build up a more complicated GUI by walking a tree of ViewModels and composing a GUI out of corresponding View components.</li>
<li><b>deregistering event handlers</b> &mdash; The framework registers event handlers between the ViewModel and View, with no provision for unregistering them when components are no longer neeed. In BookFinder, the single View/ViewModel pair hang around until the application is closed, but in a more complicated application there might be an opportunity to leak resources.</li>
</ul>
<h2>Summing up</h2>
<p>I&#8217;m happy with how the framework and tool turned out. I could probably have written the application more quickly if I hadn&#8217;t bothered trying to extract the framework, but it wouldn&#8217;t have been as testable (and therefore likely not as well tested). I think the extra effort was worthwhile both because it created a better application and because I learned more about WinForms programming and how I can leverage conventions to reduce programmer workload &#8211; if the framework were used for a second application, development would just fly. And the exercise was fun. Not only writing the framework, but using it &mdash; it&#8217;s extremely liberating having event handlers just work by creating a properly-named method, and having the handler be immediately testable is a joy. If I had any expectations that I&#8217;d be writing similar tools on .NET 1.1 again, I&#8217;d definitely continue extending the framework.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/blairconrad.wordpress.com/888/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/blairconrad.wordpress.com/888/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/blairconrad.wordpress.com/888/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/blairconrad.wordpress.com/888/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/blairconrad.wordpress.com/888/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/blairconrad.wordpress.com/888/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/blairconrad.wordpress.com/888/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/blairconrad.wordpress.com/888/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/blairconrad.wordpress.com/888/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/blairconrad.wordpress.com/888/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/blairconrad.wordpress.com/888/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/blairconrad.wordpress.com/888/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/blairconrad.wordpress.com/888/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/blairconrad.wordpress.com/888/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blairconrad.wordpress.com&amp;blog=11276730&amp;post=888&amp;subd=blairconrad&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blairconrad.wordpress.com/2011/02/15/growing-an-mvvm-framework-in-2003-part-v-%e2%80%93-reflections-and-regrets/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<georss:point>43.465187 -80.522372</georss:point>
		<geo:lat>43.465187</geo:lat>
		<geo:long>-80.522372</geo:long>
		<media:content url="http://1.gravatar.com/avatar/707860a1ae9745187b83023e2655e03c?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">blairconrad</media:title>
		</media:content>
	</item>
	</channel>
</rss>
