<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" gd:etag="W/&quot;DEYAQH8yeip7ImA9WxJXEk8.&quot;"><id>tag:blogger.com,1999:blog-9023944205100803414</id><updated>2009-06-05T11:22:21.192-07:00</updated><title>Bits in Motion</title><subtitle type="html">Much Ado About Code</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://blog.bits-in-motion.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://blog.bits-in-motion.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Jeff Brown</name><uri>http://www.blogger.com/profile/09075745057339916352</uri><email>noreply@blogger.com</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>131</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><link rel="self" href="http://feeds.feedburner.com/BitsInMotion" type="application/atom+xml" /><entry gd:etag="W/&quot;C0IDRnsyeip7ImA9WxJXEUQ.&quot;"><id>tag:blogger.com,1999:blog-9023944205100803414.post-5694751990382832716</id><published>2009-06-05T01:46:00.001-07:00</published><updated>2009-06-05T01:46:17.592-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-05T01:46:17.592-07:00</app:edited><title>Upcoming Events</title><content type="html">&lt;p&gt;I will be attending &lt;a href="http://altnetconfcanada.com/home/index.castle"&gt;ALT.Net Canada&lt;/a&gt; in Vancouver, BC from June 12th through 14th.&amp;#160; My plan is to follow that up with a week-long vacation and visiting friends and family in Ottawa, Toronto, Montreal or Kitchener-Waterloo.&lt;/p&gt;  &lt;p&gt;I rather desperately need a vacation...&lt;/p&gt;  &lt;p&gt;As for &lt;a href="http://www.gallio.org/"&gt;Gallio&lt;/a&gt;, I am currently investing most of my spare time into adding support for test files that are not .Net assemblies.&amp;#160; When I am finished, Gallio will be able to run tests written in other languages such as C++, Ruby, various XML-based DSLs or anything else that is represented as a file of a type for which a test framework plugin has been installed.&amp;#160; As a proof of concept Gallio v3.0.7 will include support for &lt;a href="http://rspec.info/"&gt;RSpec&lt;/a&gt; by way of the &lt;a href="http://www.codeplex.com/dlr"&gt;Dynamic Language Runtime&lt;/a&gt;.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023944205100803414-5694751990382832716?l=blog.bits-in-motion.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.bits-in-motion.com/feeds/5694751990382832716/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9023944205100803414&amp;postID=5694751990382832716" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/5694751990382832716?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/5694751990382832716?v=2" /><link rel="alternate" type="text/html" href="http://blog.bits-in-motion.com/2009/06/upcoming-events.html" title="Upcoming Events" /><author><name>Jeff Brown</name><uri>http://www.blogger.com/profile/09075745057339916352</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03263874364951229913" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total></entry><entry gd:etag="W/&quot;CkQEQ3o7fyp7ImA9WxJQFkk.&quot;"><id>tag:blogger.com,1999:blog-9023944205100803414.post-1502699045126541716</id><published>2009-05-29T16:21:00.000-07:00</published><updated>2009-05-29T16:38:22.407-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-29T16:38:22.407-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="gallio" /><category scheme="http://www.blogger.com/atom/ns#" term="release notes" /><category scheme="http://www.blogger.com/atom/ns#" term="mbunit" /><title>Announcing Gallio and MbUnit v3.0.6 Update 2.</title><content type="html">&lt;p&gt;Today we are releasing Gallio and MbUnit v3.0.6 Update 2.&amp;#160; This is mainly a bug fix release.&lt;/p&gt;  &lt;p&gt;Download here: &lt;a href="http://www.gallio.org/Downloads.aspx"&gt;http://www.gallio.org/Downloads.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Documentation here: &lt;a href="http://www.gallio.org/Docs.aspx"&gt;http://www.gallio.org/Docs.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Earlier release notes: &lt;a href="http://blog.bits-in-motion.com/2009/03/announcing-gallio-and-mbunit-v306.html"&gt;v3.0.6&lt;/a&gt;, &lt;a href="http://blog.bits-in-motion.com/2009/04/announcing-gallio-and-mbunit-v306.html"&gt;v3.0.6 update 1&lt;/a&gt;, &lt;a href="http://blog.bits-in-motion.com/search/label/release%20notes"&gt;all versions&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;Changes&lt;/h3&gt;  &lt;h5&gt;MbUnit:&lt;/h5&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;[New!]&lt;/strong&gt; Added &lt;em&gt;[Parallelizable(TestScope.All)] &lt;/em&gt;and &lt;em&gt;[Parallelizable(TestScope.Descendants)] &lt;/em&gt;to recursively mark tests as parallelizable such as all tests within a fixture or all fixtures in an assembly.&lt;/li&gt;    &lt;li&gt;Fixed &amp;quot;test was orphaned&amp;quot; errors involving Parallelizable tests. &lt;/li&gt; &lt;/ul&gt;  &lt;h5&gt;xUnit.net: &lt;/h5&gt;  &lt;ul&gt;   &lt;li&gt;Upgraded adpater to xUnit.net v1.1 RTM.&amp;#160; &lt;/li&gt; &lt;/ul&gt;  &lt;h5&gt;NCover:&lt;/h5&gt;  &lt;ul&gt;   &lt;li&gt;Added support for running NCover v1.5.8 as a 32-bit process on 64-bit machines. &lt;/li&gt; &lt;/ul&gt;  &lt;h5&gt;Echo:&lt;/h5&gt;  &lt;ul&gt;   &lt;li&gt;Fixed a regression that was causing test reports not to be generated when canceled. &lt;/li&gt; &lt;/ul&gt;  &lt;h5&gt;ReSharper:&lt;/h5&gt;  &lt;ul&gt;   &lt;li&gt;Fixed ClassCastExceptions in the ReSharper runner.&lt;/li&gt;    &lt;li&gt;Fixed missing hotfix lightbulbs in the ReSharper within test files.&lt;/li&gt;    &lt;li&gt;Fixed red strikethrough that would appear in the Unit Test Session window when running MbUnit tests declared in subclassed test fixtures.&lt;/li&gt; &lt;/ul&gt;  &lt;h5&gt;AutoCAD:&lt;/h5&gt;  &lt;ul&gt;   &lt;li&gt;Fixed a regression in the AutoCAD test driver.&lt;/li&gt; &lt;/ul&gt;  &lt;h5&gt;TeamCity:&lt;/h5&gt;  &lt;ul&gt;   &lt;li&gt;Improved the handling of parallel tests so that TeamCity test statistics make more sense.&lt;/li&gt; &lt;/ul&gt;  &lt;h5&gt;Miscellaneous:&lt;/h5&gt;  &lt;ul&gt;   &lt;li&gt;Improved the installer to support in-place upgrades.&lt;/li&gt;    &lt;li&gt;Fixed a regression that occasionally would prevent dynamic tests from running.&lt;/li&gt; &lt;/ul&gt;  &lt;div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:a01782fa-5773-433e-a526-b515aacb8056" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/gallio" rel="tag"&gt;gallio&lt;/a&gt;,&lt;a href="http://technorati.com/tags/mbunit" rel="tag"&gt;mbunit&lt;/a&gt;&lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023944205100803414-1502699045126541716?l=blog.bits-in-motion.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.bits-in-motion.com/feeds/1502699045126541716/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9023944205100803414&amp;postID=1502699045126541716" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/1502699045126541716?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/1502699045126541716?v=2" /><link rel="alternate" type="text/html" href="http://blog.bits-in-motion.com/2009/05/announcing-gallio-and-mbunit-v306.html" title="Announcing Gallio and MbUnit v3.0.6 Update 2." /><author><name>Jeff Brown</name><uri>http://www.blogger.com/profile/09075745057339916352</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03263874364951229913" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total></entry><entry gd:etag="W/&quot;DkEHRHw-fip7ImA9WxJQFUs.&quot;"><id>tag:blogger.com,1999:blog-9023944205100803414.post-5841217455972363181</id><published>2009-05-28T17:45:00.001-07:00</published><updated>2009-05-28T19:37:15.256-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-28T19:37:15.256-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="low-level" /><title>Registry Weirdness, UAC and the Vista Virtual Store</title><content type="html">&lt;p&gt;It appears that two different can see a different view of the registry content.&amp;#160; I seem to recall seeing mention about registry values potentially being seen differently by elevated and non-elevated applications when UAC is active.&lt;/p&gt;  &lt;p&gt;In this case, ProcessInvocation.exe sees the following value for a particular key:&amp;#160; (which is wrong!)&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;C:\Source\MbUnit\v3\src\Extensions\TDNet\Gallio.TDNetRunner\bin\Gallio.TDNetRunner.dll&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;But regedit.exe sees the following value:&amp;#160; (which is correct!)&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;C:\Program Files\Gallio\bin\TDNet\Gallio.TDNetRunner.dll&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The first value was used for local development of Gallio v3.0.6 but I deleted that value!&amp;#160; In fact I deleted it a week ago and I don't think I've recreated it since (because Gallio v3.0.7 uses different keys).&lt;/p&gt;  &lt;p&gt;The second value was set by the Gallio v3.0.6 installer (uses the old key).&amp;#160; This is the value I expect to see globally.&amp;#160; All interesting applications were closed at the the time of installation.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;So why are some applications seeing the first value and other applications seeing the second value?&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;No, this is not a simple question of refreshing or shutting down applications.&amp;#160; I have shut them both down and tried again and the weird view remains persistent!&lt;/p&gt;  &lt;p&gt;Next up, reboot.&amp;#160; Argh.&lt;/p&gt;  &lt;h4&gt;After the Reboot...&lt;/h4&gt;  &lt;p&gt;Same behavior.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Why?&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;Here's what I found when I searched the registry for the incorrect value:&amp;#160; (SID masked)&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;HKEY_USERS\S-1-5-21-xxxxxxxxxx-xxxxxxxxx-xxxxxxxxx-xxxx\Software\Classes\VirtualStore\MACHINE\SOFTWARE\MutantDesign\TestDriven.NET\TestRunners\Gallio_MbUnit&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Whoa.&amp;#160; So at least I'm not dreaming.&lt;/p&gt;  &lt;h4&gt;The UAC Virtual Store&lt;/h4&gt;  &lt;p&gt;On Vista, normal users are forbidden from writing to certain folders (like &lt;em&gt;%ProgramFiles%&lt;/em&gt; and &lt;em&gt;%SystemRoot%&lt;/em&gt;) and into the &lt;em&gt;HKEY_LOCAL_MACHINE&lt;/em&gt; part of the registry.&amp;#160; Even local administrator users are forbidden from writing into these folders, &lt;em&gt;unless elevated&lt;/em&gt;.&lt;/p&gt;  &lt;p&gt;Well, not quite.&amp;#160; As a compatibility feature, instead of generating an error, a write by a non-elevated application running as a local administrator may be redirected to a Virtual Store on the file system or in the registry as appropriate.&amp;#160; The Virtual Store functions as a shallow per-user overlay of protected parts of the file system and registry.&amp;#160; Each user has a separate Virtual Store from all other users so misbehaving old-style applications can keep pretending they have write access to places they don't but the impact remains local to the user.&lt;/p&gt;  &lt;p&gt;The file system Virtual Store is in &lt;em&gt;%LOCALAPPDATA%\VirtualStore.&lt;/em&gt;&amp;#160; Here are a few things that mine contains:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;_vimrc files&lt;/li&gt;    &lt;li&gt;*.pyc files created by GNU Solfege&lt;/li&gt;    &lt;li&gt;Reflector.cfg&lt;/li&gt;    &lt;li&gt;Trillian crash dumps and user data (this explains a few oddities I've seen!)&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The registry Virtual Store is in &lt;em&gt;HKEY_CURRENT_USER\Software\Classes\VirtualStore&lt;/em&gt;.&amp;#160; Here are a few things that mine contains:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Old obsolete registry keys I created for debugging that got me into this mess.&lt;/strong&gt;&lt;/li&gt;    &lt;li&gt;A EULA key for Acrobat Reader.&amp;#160; (Nowadays I use FoxIt Reader.)&lt;/li&gt;    &lt;li&gt;Configuration for a few audio codecs.&lt;/li&gt;    &lt;li&gt;An MRU list for DirectDraw (weird).&lt;/li&gt;    &lt;li&gt;A flag set by my 3G wireless software.&lt;/li&gt;    &lt;li&gt;Configuration for OpenVPN.&lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;What Actually Happened&lt;/h4&gt;  &lt;p&gt;Once upon a time, I ran a little script &lt;em&gt;without elevation&lt;/em&gt; to create some registry keys for local development.&amp;#160; Since the script was not elevated, the new registry keys were created within the &lt;em&gt;Virtual Store&lt;/em&gt;.&lt;/p&gt;  &lt;p&gt;Later on, I ran a script to delete these keys.&amp;#160; But in the interim I had changed the script to run with elevation.&amp;#160; Because it ran &lt;em&gt;with elevation&lt;/em&gt; it did not see the keys in the &lt;em&gt;Virtual Store &lt;/em&gt;so it left them there.&lt;/p&gt;  &lt;p&gt;Then I installed Gallio v3.0.6 which, being an installer, created some new registry keys &lt;em&gt;with elevation&lt;/em&gt; in the expected location.&lt;/p&gt;  &lt;p&gt;When I tried to run a test, the ProcessInvocation.exe component of TestDriven.Net enumerated these keys in the registry, but &lt;em&gt;without elevation&lt;/em&gt;.&amp;#160; Consequently it saw the old keys in the &lt;em&gt;Virtual Store&lt;/em&gt; and got extremely confused.&lt;/p&gt;  &lt;p&gt;Crash!&lt;/p&gt;  &lt;h4&gt;Moral&lt;/h4&gt;  &lt;p&gt;Normally the Virtual Store on Vista is not a problem.&amp;#160; Actually it's a pretty clever solution to a serious compatibility problem.&amp;#160; However, if you ever run into issues like mine you might just need to learn about it so that you can delete or repair the magic virtualized content if needed.&lt;/p&gt;  &lt;p&gt;More info: &lt;a href="http://support.microsoft.com/kb/927387"&gt;http://support.microsoft.com/kb/927387&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;   &lt;div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:17cce9e1-8eb2-4399-93a5-c5545cfb59bd" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/gallio" rel="tag"&gt;gallio&lt;/a&gt;&lt;/div&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023944205100803414-5841217455972363181?l=blog.bits-in-motion.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.bits-in-motion.com/feeds/5841217455972363181/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9023944205100803414&amp;postID=5841217455972363181" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/5841217455972363181?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/5841217455972363181?v=2" /><link rel="alternate" type="text/html" href="http://blog.bits-in-motion.com/2009/05/vista-registry-weirdness.html" title="Registry Weirdness, UAC and the Vista Virtual Store" /><author><name>Jeff Brown</name><uri>http://www.blogger.com/profile/09075745057339916352</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03263874364951229913" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;C0cNRnw7fip7ImA9WxJQFU0.&quot;"><id>tag:blogger.com,1999:blog-9023944205100803414.post-7515860118149049448</id><published>2009-05-28T01:57:00.001-07:00</published><updated>2009-05-28T01:58:17.206-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-28T01:58:17.206-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="gallio" /><title>Vista UAC and Dog Food</title><content type="html">&lt;p&gt;A few days ago I re-enabled Vista UAC on my development laptop.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Why?&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;I was developing a few features for Gallio that required being able to perform privilege elevations on Vista.&amp;#160; So unless I got my act together to play nice with UAC, those features were just not going to work!&lt;/p&gt;  &lt;p&gt;&lt;em&gt;With reluctance I re-enabled UAC.&amp;#160; Sometimes dog food, while nutritious, contains unpleasant additives.&lt;/em&gt;&lt;/p&gt;  &lt;h4&gt;Teaser&lt;/h4&gt;  &lt;p&gt;Here's one of the new features from Gallio v3.0.7 in trunk:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_X_hvY6E0egY/Sh5R6AJtMjI/AAAAAAAAAZA/dkAwqDjRq40/s1600-h/image%5B3%5D.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="473" alt="image" src="http://lh3.ggpht.com/_X_hvY6E0egY/Sh5R65Y1mLI/AAAAAAAAAZE/jjIwB2HpOIA/image_thumb%5B1%5D.png?imgmax=800" width="512" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;When certain settings are changed, we show shield buttons:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_X_hvY6E0egY/Sh5R7d5JoPI/AAAAAAAAAZI/Tlc__dg5Bd0/s1600-h/image%5B7%5D.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="33" alt="image" src="http://lh4.ggpht.com/_X_hvY6E0egY/Sh5R73ZKp4I/AAAAAAAAAZM/4ARUs9JzkvA/image_thumb%5B3%5D.png?imgmax=800" width="247" border="0" /&gt;&lt;/a&gt;&amp;#160; &lt;/p&gt;  &lt;p&gt;And of course when clicking on one of those buttons we'll get the standard UAC elevation dialog.&amp;#160; I can't show you that because by design UAC blocks out other applications including SnagIt.&lt;/p&gt;  &lt;h4&gt;How it works (very briefly)&lt;/h4&gt;  &lt;p&gt;To display shield buttons, set the Button's FlatStyle to System and then send the BCM_SETSHIELD message to the button using SendMessage.&amp;#160; (Or borrow my &lt;a href="http://code.google.com/p/mb-unit/source/browse/trunk/v3/src/Gallio/Gallio.UI/Controls/ShieldButton.cs"&gt;ShieldButton&lt;/a&gt; class.&amp;#160; Ignore the Mono bits.)&lt;/p&gt;  &lt;p&gt;Before performing privilege elevation, check whether it is even needed for the current user.&amp;#160; Here's one way.&amp;#160; A better way might be to examine the Win32 ProcessToken directly.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;public static bool CurrentUserHasElevatedPrivileges()     &lt;br /&gt;{      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; WindowsPrincipal principal = new WindowsPrincipal(WindowsIdentity.GetCurrent());      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; return principal.IsInRole(WindowsBuiltInRole.Administrator);      &lt;br /&gt;}&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;To perform privilege elevation, first split the code into two parts: non-privileged and privileged.&amp;#160; The privileged part will have to run in a separate process one way or another.&amp;#160; Then decide how to perform the elevation using one of these options.&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Use the COM elevation moniker as in the &lt;a href="http://msdn.microsoft.com/en-us/library/ms679687(VS.85).aspx"&gt;CoCreateInstanceAsAdmin&lt;/a&gt; example to instantiate a COM object within an elevated process provided by the system.&amp;#160; This method is convenient but it requires that you have registered your privileged code as a COMVisible managed class ahead of time.&amp;#160; Consequently, we do not use this method in Gallio which is expected to be xcopy deployable with no prior installation of components required (besides copying files).      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;Create a separate executable process that contains the privileged code.&amp;#160; Be sure to embed an appropriate &lt;a href="http://msdn.microsoft.com/en-us/library/aa374191.aspx"&gt;application manifest&lt;/a&gt; like the following either using the Visual Studio manifest build       &lt;p&gt;option or &lt;a href="http://msdn.microsoft.com/en-us/library/aa375649.aspx"&gt;mt.exe&lt;/a&gt;.        &lt;br /&gt;        &lt;br /&gt;Our incantation of mt.exe looks a bit like this: &amp;quot;mt.exe -nologo -manifest Elevated.manifest -managedassemblyname:Gallio.Host.Elevated.exe -nodependency -outputresource:Gallio.Host.Elevated.exe;#1&amp;quot;.&amp;#160; Keep in mind that if you use mt.exe on a signed assembly that the signature will be invalidated and the assembly will need to be re-signed with &amp;quot;sn.exe -R ...&amp;quot;.&amp;#160; You might consider delay-signing the assembly at first, then merging the manifest, then re-signing the assembly.&amp;#160; This way you can tell whether you're working with an assembly with a proper manifest because the original delay-signed copy will fail validation (normally) but the patched and re-signed copy will be good.        &lt;br /&gt;        &lt;br /&gt;Here is the Elevated.manifest file that we use for Gallio.Host.Elevated.exe:&lt;/p&gt;   &lt;/li&gt;    &lt;p&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;yes&amp;quot;?&amp;gt;     &lt;br /&gt;&amp;#160; &amp;lt;assembly xmlns=&amp;quot;urn:schemas-microsoft-com:asm.v1&amp;quot; manifestVersion=&amp;quot;1.0&amp;quot;&amp;gt;      &lt;br /&gt;&amp;#160; &amp;lt;description&amp;gt;Provides out of process hosting for Gallio components that require privilege elevation.&amp;lt;/description&amp;gt;      &lt;br /&gt;&amp;#160; &amp;lt;trustInfo xmlns=&amp;quot;urn:schemas-microsoft-com:asm.v2&amp;quot;&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;security&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;requestedPrivileges xmlns=&amp;quot;urn:schemas-microsoft-com:asm.v3&amp;quot;&amp;gt;      &lt;br /&gt;&lt;strong&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;requestedExecutionLevel level=&amp;quot;requireAdministrator&amp;quot; uiAccess=&amp;quot;false&amp;quot;/&amp;gt;       &lt;br /&gt;&lt;/strong&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/requestedPrivileges&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/security&amp;gt;      &lt;br /&gt;&amp;#160; &amp;lt;/trustInfo&amp;gt;      &lt;br /&gt;&amp;lt;/assembly&amp;gt;&lt;/p&gt;    &lt;p&gt;Launch the privileged process directly being sure to set a few extra properties:&lt;/p&gt;    &lt;p&gt;var processStartInfo = new ProcessStartInfo(&amp;quot;PrivilegedApp.exe&amp;quot;);     &lt;br /&gt;processStartInfo.Verb = &amp;quot;runas&amp;quot;;&amp;#160;&amp;#160; // optional if you embedded a manifest      &lt;br /&gt;processStartInfo.UseShellExecute = true;&amp;#160; // mandatory      &lt;br /&gt;processStartInfo.ErrorDialog = true;&amp;#160; // mandatory      &lt;br /&gt;processStartInfo.ErrorDialogOwnerHandle = ownerForm.Handle;&amp;#160; // recommended&lt;/p&gt; &lt;/ol&gt;  &lt;p&gt;Ok, I just glossed over a million little details...&lt;/p&gt;  &lt;p&gt;If you are ever in a position to have to perform privilege elevation in a managed application, I highly recommend reading the relevant MSDN articles three times over.&lt;/p&gt;  &lt;div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:b57311b2-1918-4106-9e19-506ec13597c5" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/gallio" rel="tag"&gt;gallio&lt;/a&gt;&lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023944205100803414-7515860118149049448?l=blog.bits-in-motion.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.bits-in-motion.com/feeds/7515860118149049448/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9023944205100803414&amp;postID=7515860118149049448" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/7515860118149049448?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/7515860118149049448?v=2" /><link rel="alternate" type="text/html" href="http://blog.bits-in-motion.com/2009/05/vista-uac-and-dog-food.html" title="Vista UAC and Dog Food" /><author><name>Jeff Brown</name><uri>http://www.blogger.com/profile/09075745057339916352</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03263874364951229913" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;DUcHSXs4fSp7ImA9WxJRF0Q.&quot;"><id>tag:blogger.com,1999:blog-9023944205100803414.post-663875646858312623</id><published>2009-05-19T22:23:00.001-07:00</published><updated>2009-05-19T22:23:58.535-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-19T22:23:58.535-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="gallio" /><category scheme="http://www.blogger.com/atom/ns#" term="mbunit" /><title>Gallio on Visual Studio 2010, Redux</title><content type="html">&lt;p&gt;After the Microsoft PDC of 2008, I released a variant of Gallio v3.0.5 with support for the Visual Studio 2010 pre-release bits.&lt;/p&gt;  &lt;p&gt;So today I have been working on getting Gallio v3.0.7 running on Visual Studio 2010 Beta 1.&lt;/p&gt;  &lt;p&gt;The migration has been pretty easy for the most part.&amp;#160; With the PDC bits, I had a hard time producing a build because I had to install all sorts of tools inside the PDC VM and deal with rather unstable bits.&amp;#160; With the Beta 1 release, the process is much smoother since I can just install the framework on the build server.&amp;#160; Visual Studio 2010 Beta 1 is working ok although I have filed a couple of bugs already.&lt;/p&gt;  &lt;p&gt;Unfortunately since not all contributors to Gallio will be running VS 2010 anytime soon I will have to maintain a parallel set of project files and solutions.&amp;#160; I guess I will be maintaining *.vs2008.csproj and *.vs2010.csproj files side-by-side for a little while.&amp;#160;&amp;#160; I wish Microsoft would invest some effort in providing a smooth backward-compatible upgrade path for projects to enable developers on newer tools to work with projects created using older tools without having to actually migrate them over.&amp;#160; (This is my 3rd Visual Studio upgrade and I'm getting really tired of this story.)&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;The first pre-release installer should be available later this week.&lt;/p&gt;  &lt;p&gt;Looks promising so far...&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_X_hvY6E0egY/ShOT4RtGWjI/AAAAAAAAAY4/Rd02N2r_nBc/s1600-h/image%5B3%5D.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="514" alt="image" src="http://lh4.ggpht.com/_X_hvY6E0egY/ShOT7MmwdkI/AAAAAAAAAY8/1gGipR3ihaY/image_thumb%5B1%5D.png?imgmax=800" width="644" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:36fd3eda-21a3-4e8b-9cec-be530114d939" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/gallio" rel="tag"&gt;gallio&lt;/a&gt;,&lt;a href="http://technorati.com/tags/mbunit" rel="tag"&gt;mbunit&lt;/a&gt;&lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023944205100803414-663875646858312623?l=blog.bits-in-motion.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.bits-in-motion.com/feeds/663875646858312623/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9023944205100803414&amp;postID=663875646858312623" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/663875646858312623?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/663875646858312623?v=2" /><link rel="alternate" type="text/html" href="http://blog.bits-in-motion.com/2009/05/gallio-on-visual-studio-2010-redux.html" title="Gallio on Visual Studio 2010, Redux" /><author><name>Jeff Brown</name><uri>http://www.blogger.com/profile/09075745057339916352</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03263874364951229913" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total></entry><entry gd:etag="W/&quot;D08FRXYzfCp7ImA9WxJXEk8.&quot;"><id>tag:blogger.com,1999:blog-9023944205100803414.post-5928896221209394034</id><published>2009-05-08T23:47:00.001-07:00</published><updated>2009-06-05T11:16:54.884-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-05T11:16:54.884-07:00</app:edited><title>NDepend v2.12 Rocks.</title><content type="html">&lt;p&gt;I have used NDepend on and off for the past couple of years.&amp;#160; It has never been an everyday thing, but whenever I have an itch to find out just how convoluted my code dependency graph has become, NDepend has been there for me.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Full disclosure: Patrick Smacchia sent me a free professional license of NDepend to play with some time ago.&amp;#160; To be honest, I didn't really need the license because I was already using the OSS edition of NDepend at the time.&amp;#160; I just think this is a cool tool.&amp;#160; :-)&lt;/em&gt;&lt;/p&gt;  &lt;h4&gt;Download and Installation&lt;/h4&gt;  &lt;p&gt;Installing NDepend is pretty easy.&amp;#160; Just visit the &lt;a href="http://www.ndepend.com/NDependDownload.aspx"&gt;NDepend download page&lt;/a&gt;, type in your email address for the OSS or trial version or your license code for the progressional addition, then download the NDepend ZIP file.&amp;#160; Extract the ZIP someplace useful (like C:\Program Files) then pin a shortcut to VisualNDepend.exe to your Quick Launch bar.&lt;/p&gt;  &lt;h5&gt;Tools Integration&lt;/h5&gt;  &lt;p&gt;Now launch VisualNDepend.&amp;#160; To enable Visual Studio and Reflector integration click on the button in the UI.&amp;#160; A couple more clicks and you're done.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_X_hvY6E0egY/SgUmjPt-47I/AAAAAAAAAXQ/1NJZtmRygMs/s1600-h/image7.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="95" alt="image" src="http://lh6.ggpht.com/_X_hvY6E0egY/SgUmj6Y5HqI/AAAAAAAAAXU/fgvOondNyr0/image_thumb3.png?imgmax=800" width="380" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_X_hvY6E0egY/SgUmkWQRrLI/AAAAAAAAAXY/m9HjlV_qPmg/s1600-h/image11.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="250" alt="image" src="http://lh4.ggpht.com/_X_hvY6E0egY/SgUmlSg5i6I/AAAAAAAAAXc/e4caFaU4maY/image_thumb5.png?imgmax=800" width="334" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;I have to say, unboxing NDepend is very slick!&amp;#160; There are a bunch of links to little screencast demos to explain how stuff works.&amp;#160; I have to admit I have tool envy here.&amp;#160; I wish my tools could help the user along like this.&lt;/p&gt;  &lt;p&gt;That said, I do wish NDepend (and Reflector also) had an MSI installer flavor.&amp;#160; It's harder to explain to others how to extract ZIPs and create shortcuts than to just ask them to run through a standard installer process.&lt;/p&gt;  &lt;h4&gt;Dissecting Gallio with NDepend&lt;/h4&gt;  &lt;p&gt;After installing the NDepend add-in for Visual Studio, I opened up the Gallio solution.&amp;#160; There's a lot of stuff in here, so for this exploration I'm going to start by looking at the dependencies within &lt;strong&gt;Gallio.dll&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_X_hvY6E0egY/SgUmmL4S8XI/AAAAAAAAAXg/w7yhivBZQIs/s1600-h/image15.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="104" alt="image" src="http://lh5.ggpht.com/_X_hvY6E0egY/SgUmm97w4dI/AAAAAAAAAXk/lwiUN3WDGYY/image_thumb7.png?imgmax=800" width="523" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;It's been a few months since I looked at this so I'm cringing here...&amp;#160; What will I discover?&lt;/p&gt;  &lt;p&gt;Up pops an instance of Visual NDepend with this dialog listing all of the assemblies in my solution.&amp;#160; Pretty slick.&amp;#160; I don't have to create a new NDepend project from scratch.&amp;#160; On the other hand, I'm only interested in Gallio.dll and I did right-click specifically on that project in Visual Studio so I will remove everything else.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_X_hvY6E0egY/SgUmpBGX7RI/AAAAAAAAAXo/NN38JB0ZQy0/s1600-h/image19.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="406" alt="image" src="http://lh6.ggpht.com/_X_hvY6E0egY/SgUmqFx048I/AAAAAAAAAXs/nX06DbiO2lc/image_thumb9.png?imgmax=800" width="716" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h5&gt;NDepend Report&lt;/h5&gt;  &lt;p&gt;The next thing that pops up is an NDepend report.&amp;#160; It shows up in my default web browser (FireFox).&amp;#160; I think it might be cooler if it appeared inside of the Visual NDepend application itself using an embedded web browser (eg. System.Windows.Forms.WebBrowser) but this report is pretty useful anyways.&lt;/p&gt;  &lt;p&gt;Bunch of metrics regarding both the source code and the compiled binaries.&amp;#160; Looks like Gallio.dll consists 66% of comments.&amp;#160; Heh.&amp;#160; There's all of the XML documentation!&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_X_hvY6E0egY/SgUmrIMsGQI/AAAAAAAAAXw/fhpeNTdAlUM/s1600-h/image24.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="77" alt="image" src="http://lh3.ggpht.com/_X_hvY6E0egY/SgUmsBbtC_I/AAAAAAAAAX0/U6Ck4Z_Rxvc/image_thumb12.png?imgmax=800" width="644" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;One thing to keep in mind when reading the report is that not all of the information is equally useful.&amp;#160; NDepend computes lots of different metrics to help you find hot spots.&amp;#160; Of course, if there's nothing really wrong then what it finds might not be very interesting.&amp;#160; You need to read the report intelligently.&lt;/p&gt;  &lt;h5&gt;Top 10 Methods to Refactor?&lt;/h5&gt;  &lt;p&gt;For example, here are the top 10 methods in Gallio.dll that I should refactor, according to NDepend.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_X_hvY6E0egY/SgUmtbsIk7I/AAAAAAAAAX4/RxaZb9FnL2Y/s1600-h/image28.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="269" alt="image" src="http://lh5.ggpht.com/_X_hvY6E0egY/SgUmuxskfAI/AAAAAAAAAX8/0PF_Uzsgdok/image_thumb14.png?imgmax=800" width="767" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Whoa, so the top 2 are compiler generated and most of the others are pretty simple methods.&amp;#160; Based on the criteria used (see CQL below).&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_X_hvY6E0egY/SgUmwP4oe1I/AAAAAAAAAYA/iQDgVoi3z-Q/s1600-h/image32.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="232" alt="image" src="http://lh4.ggpht.com/_X_hvY6E0egY/SgUmxQ5NzNI/AAAAAAAAAYE/_zbhVWAao5M/image_thumb16.png?imgmax=800" width="798" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The main thing I'm hitting up against is the IL nesting depth and number of variables.&amp;#160; None of these methods have a particularly troubling cyclomatic complexity except for CreateFilteredClosure which has a CC of 20 but can't really be improved much more given what it does.&lt;/p&gt;  &lt;p&gt;So in sum, I guess I'm doing ok!&amp;#160; Cool.&amp;#160; However I bet if I threw this at some production code of my employer, we'd find some interesting things to talk about.&lt;/p&gt;  &lt;p&gt;Let's keep digging.&lt;/p&gt;  &lt;h5&gt;Finding Large Methods&lt;/h5&gt;  &lt;p&gt;Out of the box, the NDepend report shows a summary of large methods.&amp;#160; This is worth paying close attention to.&lt;/p&gt;  &lt;p&gt;Here are the 10 biggest methods in Gallio.dll.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_X_hvY6E0egY/SgUmzanN3eI/AAAAAAAAAYI/MfrMrnM8LYk/s1600-h/image41.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="318" alt="image" src="http://lh5.ggpht.com/_X_hvY6E0egY/SgUm0gfJGAI/AAAAAAAAAYM/4nND9zb2q1o/image_thumb21.png?imgmax=800" width="1034" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;I'm amused that FindMiddleSnake made the list.&amp;#160; That is one monster method!&amp;#160; Unfortunately I can't really do much to improve it because of the nature of the &lt;a href="http://citeseer.ist.psu.edu/myers86ond.html"&gt;algorithm&lt;/a&gt;.&amp;#160; Calculating diffs is hard stuff!&amp;#160; The topological sort is in a similar category.&lt;/p&gt;  &lt;p&gt;However, the PluginCatalog.ApplyTo and DefaultRuntime.VerifyInstallation methods are long for no good reason.&amp;#160; So with a little help from &lt;a href="http://www.jetbrains.com/resharper/"&gt;ReSharper&lt;/a&gt;'s &lt;em&gt;Extract Method&lt;/em&gt; refactoring here's what ApplyTo now looks like:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_X_hvY6E0egY/SgUm14tJ99I/AAAAAAAAAYQ/Hs6w9b7U11Q/s1600-h/image45.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="199" alt="image" src="http://lh6.ggpht.com/_X_hvY6E0egY/SgUm25jhI1I/AAAAAAAAAYU/EOmsdnbmig8/image_thumb23.png?imgmax=800" width="571" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;h5&gt;Overlap with FxCop&lt;/h5&gt;  &lt;p&gt;Some of the metrics that NDepend computes out of the box produce similar results to those that could be obtained using &lt;a href="http://en.wikipedia.org/wiki/FxCop"&gt;FxCop&lt;/a&gt;.&amp;#160; This is rather interesting since NDepend's CQL language actually has the potential to be much more expressive and configurable than the FxCop verifications, if you like.&amp;#160; However there can be some quirks.&lt;/p&gt;  &lt;p&gt;Here are some methods and constructors that appear in abstract classes that were marked &amp;quot;public&amp;quot; but that NDepend thinks could be &amp;quot;protected&amp;quot;.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_X_hvY6E0egY/SgUm4CM-6AI/AAAAAAAAAYY/DxokOA36IG4/s1600-h/image49.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="212" alt="image" src="http://lh4.ggpht.com/_X_hvY6E0egY/SgUm5ELudeI/AAAAAAAAAYc/SeHR4euCTw0/image_thumb25.png?imgmax=800" width="736" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The &lt;em&gt;NativeCodeElementWrapper&lt;/em&gt;, &lt;em&gt;NativeMemberWrapper&lt;/em&gt; and &lt;em&gt;NativeFunctionWrapper&lt;/em&gt; constructors I understand (fixed!), the others not so much.&amp;#160; &lt;em&gt;TestTypePatternAttribute&lt;/em&gt; is a public attribute class whose constructor really does need to be public because it is public API although NDepend doesn't know that.&amp;#160; The &lt;em&gt;NativeCodeElementWrapper.Target &lt;/em&gt;property is only used internally in Gallio.dll so it could be made protected or internal if desired.&lt;/p&gt;  &lt;p&gt;What it comes down to is that you still have to use your head when you interpret the data.&amp;#160; It's worth the effort though!&lt;/p&gt;  &lt;h4&gt;Finding Inadvertent Coupling&lt;/h4&gt;  &lt;p&gt;Of all of the many metrics and views provided by NDepend, this one is by far my favorite.&amp;#160; It shows the afferent coupling (incoming dependencies) in blue, efferent coupling (outgoing dependencies) in green, and mutual coupling (both incoming and outgoing dependencies) in black.&amp;#160; The following chart is displaying coupling among namespaces.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_X_hvY6E0egY/SgUm57u2XuI/AAAAAAAAAYg/VVFnbF8_t2A/s1600-h/image53.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="303" alt="image" src="http://lh4.ggpht.com/_X_hvY6E0egY/SgUm6rZU_4I/AAAAAAAAAYk/ith-tHQOVAg/image_thumb27.png?imgmax=800" width="487" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Oh no!&amp;#160; There's some black in there.&amp;#160; The black means that some code in one namespace is using code in another namespace which also happens to use code in the former. &lt;/p&gt;  &lt;p&gt;Namespaces are frequently used to separate subsystems from one another.&amp;#160; Coupling among namespaces can indicate one of the following problems:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;One or more classes are in the wrong namespace and should be moved. &lt;/li&gt;    &lt;li&gt;One or more classes have dependencies on the wrong things and should be refactored to use dependency injection or use inversion of control to access foreign services. &lt;/li&gt;    &lt;li&gt;The namespaces are not very cohesive and the subsystems they represent should be restructured to be more tightly encapsulated or have fewer responsibilities. &lt;/li&gt;    &lt;li&gt;There are common services partially defined in both namespaces that should be extracted and moved elsewhere. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;To take a deeper look I just double-click on one of the black squares to drill down.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_X_hvY6E0egY/SgUm8Lgg5SI/AAAAAAAAAYo/9jykM43QqGA/s1600-h/image61.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="514" alt="image" src="http://lh5.ggpht.com/_X_hvY6E0egY/SgUm885wYRI/AAAAAAAAAYs/9zod1ryWbwA/image_thumb31.png?imgmax=800" width="527" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Ah ha!&amp;#160; It looks like the &lt;em&gt;Gallio.Model.Diagnostics.ExceptionData&lt;/em&gt; class is being used by several of the classes in the &lt;em&gt;Gallio.Runtime.Logging &lt;/em&gt;namespace&lt;em&gt;.&lt;/em&gt;&amp;#160; This is bad.&lt;/p&gt;  &lt;p&gt;The &lt;em&gt;Runtime&lt;/em&gt; subsystem is the lowest tier of Gallio and provides the core foundational services needed to get Gallio up and running.&amp;#160;&amp;#160; The &lt;em&gt;Model&lt;/em&gt; subsystem is one of the tiers above the &lt;em&gt;Runtime&lt;/em&gt; and its job is to define the test object model.&amp;#160; What we have here is a cyclic dependency that crosses tiers.&lt;/p&gt;  &lt;p&gt;In a tiered architecture, dependencies should always flow from one tier down to the ones below it and never the other way around.&amp;#160; If you let dependencies flow both ways then you may quickly find yourself enmeshed in a bowl of spaghetti!&lt;/p&gt;  &lt;p&gt;It looks like in order to fix this problem, I'm going to have to rearrange a few of these dependencies.&amp;#160; The upside is that the structure of the system will be cleaner when I am done.&lt;/p&gt;  &lt;h4&gt;CQL: A Recipe for Analysis&lt;/h4&gt;  &lt;p&gt;NDepend provides a code query language called CQL which enables all sorts of fancy analysis.&amp;#160; In addition to answering various questions interactively, you can incorporate NDepend CQL constraints into your build process such that the build will fail if a constraint is violated.&amp;#160; By using CQL as part of a continuous integration process you can validate system design conventions early and often.&amp;#160; For example, you can add a CQL constraint to detect when cyclic dependencies are accidentally created across tiers.&lt;/p&gt;  &lt;p&gt;To be honest, I have not delved into CQL very much myself.&amp;#160; Using it as part of the build process looks like it could be a very useful tool for managing large teams of developers.&amp;#160; (I just need to find more time to do architecture work...)&lt;/p&gt;  &lt;h4&gt;Summary&lt;/h4&gt;  &lt;p&gt;NDepend is a good tool that repays careful analysis.&amp;#160; It won't fix your system design defects for you but it will help you find the trouble spots.&lt;/p&gt;  &lt;p&gt;As a result of writing this post, I fixed a few big methods and performed a major refactoring of Gallio's primary namespaces guided mainly by NDepend's dependency matrix view.&amp;#160; This is not the first time I have used NDepend to improve Gallio.&amp;#160; Here is how that dependency matrix is looking now:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_X_hvY6E0egY/SgUm933-1EI/AAAAAAAAAYw/-YTMRYXIPp0/s1600-h/image%5B3%5D.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="228" alt="image" src="http://lh4.ggpht.com/_X_hvY6E0egY/SgUm_FUWKiI/AAAAAAAAAY0/3_7W3acgDLc/image_thumb%5B1%5D.png?imgmax=800" width="417" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;All in all, I feel much better now!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023944205100803414-5928896221209394034?l=blog.bits-in-motion.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.bits-in-motion.com/feeds/5928896221209394034/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9023944205100803414&amp;postID=5928896221209394034" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/5928896221209394034?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/5928896221209394034?v=2" /><link rel="alternate" type="text/html" href="http://blog.bits-in-motion.com/2009/05/ndepend-v212-rocks.html" title="NDepend v2.12 Rocks." /><author><name>Jeff Brown</name><uri>http://www.blogger.com/profile/09075745057339916352</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03263874364951229913" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total></entry><entry gd:etag="W/&quot;CUUDQnc4eSp7ImA9WxJTEks.&quot;"><id>tag:blogger.com,1999:blog-9023944205100803414.post-2749542810510903070</id><published>2009-04-20T14:33:00.001-07:00</published><updated>2009-04-20T14:34:33.931-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-20T14:34:33.931-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="software engineering" /><category scheme="http://www.blogger.com/atom/ns#" term="values" /><title>Underfoot</title><content type="html">&lt;p&gt;Every now and then we talk about the &amp;quot;overhead&amp;quot; associated with implementing better practices. &lt;/p&gt;  &lt;p&gt;For example, designing a stratified architecture requires some up-front planning to separate the tiers, identify roles, decide on the interfaces, establish conventions, and resolve cross-cutting concerns.&amp;#160; During implementation, there will almost certainly be additional code required to marshal messages across tiers, additional configuration required to glue them together and additional infrastructure required to host them.&amp;#160;&amp;#160; Quite probably the team will also need to learn new skills and adopt other ancillary design/implementation practices at the same time to make it all work out.&amp;#160; This effort all takes time, effort, and money. &lt;/p&gt;  &lt;p&gt;Likewise adopting TDD/BDD/DbE, using continuous integration, leveraging IoC, adopting one-way asynchronous message passing (instead of RPC), applying command-query separation, and &amp;quot;going SOLID&amp;quot; all have one-time and recurring costs... (and benefits of course.)&lt;/p&gt;  &lt;p&gt;I think &amp;quot;overhead&amp;quot; is a misleading label for these costs.&amp;#160; It presumes that the costs are excess terms that could be eliminated through greater efficiency.&amp;#160; However these costs in fact purchase greater efficiency.&amp;#160; They are an investment in laying a foundation for future.&amp;#160; They pad the space &lt;em&gt;under our feet&lt;/em&gt; not the space &lt;em&gt;over our heads&lt;/em&gt;.&amp;#160; They let us &lt;em&gt;reach greater heights&lt;/em&gt;!&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Let's try this paragraph with&lt;em&gt; underfoot&lt;/em&gt; instead of &lt;em&gt;overhead.&lt;/em&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Building this proposed multi-tier platform will have an initial &lt;em&gt;20% underfoot&lt;/em&gt; while we retool and lay the foundation.&amp;#160; Once that is done we will be &lt;em&gt;50%&lt;/em&gt; more efficient though we will have to spend an additional recurring &lt;em&gt;5% underfoot&lt;/em&gt; to keep the axles greased. &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Which do you prefer?&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023944205100803414-2749542810510903070?l=blog.bits-in-motion.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.bits-in-motion.com/feeds/2749542810510903070/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9023944205100803414&amp;postID=2749542810510903070" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/2749542810510903070?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/2749542810510903070?v=2" /><link rel="alternate" type="text/html" href="http://blog.bits-in-motion.com/2009/04/underfoot.html" title="Underfoot" /><author><name>Jeff Brown</name><uri>http://www.blogger.com/profile/09075745057339916352</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03263874364951229913" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">5</thr:total></entry><entry gd:etag="W/&quot;A04BQX47fip7ImA9WxJQFk4.&quot;"><id>tag:blogger.com,1999:blog-9023944205100803414.post-8193803244451151122</id><published>2009-04-02T02:00:00.000-07:00</published><updated>2009-05-29T16:32:30.006-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-29T16:32:30.006-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="gallio" /><category scheme="http://www.blogger.com/atom/ns#" term="release notes" /><category scheme="http://www.blogger.com/atom/ns#" term="mbunit" /><title>Announcing Gallio and MbUnit v3.0.6 Update 1.</title><content type="html">&lt;p&gt;Today we are releasing Gallio and MbUnit v3.0.6 Update 1.&amp;#160; This release fixes a regression in the ReSharper support and adds a couple of new features. &lt;/p&gt;  &lt;p&gt;&lt;em&gt;Highlights:&lt;/em&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;em&gt;Added support for TestDriven.Net category filters.&lt;/em&gt;&lt;/li&gt;    &lt;li&gt;&lt;em&gt;Added support for more powerful inclusion/exclusion test filter expressions.&lt;/em&gt;&lt;/li&gt;    &lt;li&gt;&lt;em&gt;Fixed ReSharper v3.1, v4.0 and v4.1 hangs.&lt;/em&gt;&lt;/li&gt;    &lt;li&gt;&lt;em&gt;Increased NCover v1.5.8 timeout.&lt;/em&gt;&lt;/li&gt;    &lt;li&gt;&lt;em&gt;Adopted new assembly version numbering scheme.&lt;/em&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Download here: &lt;a href="http://www.gallio.org/Downloads.aspx"&gt;http://www.gallio.org/Downloads.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Documentation here: &lt;a href="http://www.gallio.org/Docs.aspx"&gt;http://www.gallio.org/Docs.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Earlier release notes: &lt;a href="http://blog.bits-in-motion.com/2009/03/announcing-gallio-and-mbunit-v306.html"&gt;v3.0.6&lt;/a&gt;, &lt;a href="http://blog.bits-in-motion.com/search/label/release%20notes"&gt;all versions&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;Changes&lt;/h3&gt;  &lt;h4&gt;Inclusion / Exclusion Filters&lt;/h4&gt;  &lt;p&gt;Gallio provides a mechanism for filtering the set of tests to run.&amp;#160; This is typically used to select some subset, for example to run all tests &lt;strong&gt;except&lt;/strong&gt; for integration tests.&lt;/p&gt;  &lt;p&gt;However, the filter grammar used in previous versions could not correctly express an exclusion constraint.&amp;#160; Several people noted that filters like &lt;em&gt;&amp;quot;not Category: Integration&amp;quot;&lt;/em&gt; did not in fact work due to a logical error introduced by a change in how Gallio applies filters.&amp;#160; Oops.&lt;/p&gt;  &lt;p&gt;In this update we have added a more concrete concept of inclusion and exclusion filters by extending the filter syntax with &lt;strong&gt;include&lt;/strong&gt; and &lt;strong&gt;exclude&lt;/strong&gt; clauses.&lt;/p&gt;  &lt;p&gt;Here are a few examples using Gallio.Echo.&amp;#160; The same filter syntax is used universally throughout Gallio so you can use them with NAnt, MSBuild, and PowerShell as well.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Gallio.Echo.exe MyTestAssembly.dll &amp;quot;/f:&lt;strong&gt;exclude Category: Integration&lt;/strong&gt;&amp;quot;&lt;/li&gt;    &lt;li&gt;Gallio.Echo.exe MyTestAssembly.dll &amp;quot;/f:&lt;strong&gt;include Type: MyFixture&lt;/strong&gt;&amp;quot;      &lt;br /&gt;&lt;em&gt;(here the &amp;quot;include&amp;quot; is optional)&lt;/em&gt;&lt;/li&gt;    &lt;li&gt;Gallio.Echo.exe MyTestAssembly.dll &amp;quot;/f:&lt;strong&gt;AuthorName: Jeff and Category: SmokeTests exclude Type: BrokenFixture, AnotherBrokenFixture exclude Importance: NoOneReallyCaresAbout&lt;/strong&gt;&amp;quot;&lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;TestDriven.Net Category Filters&lt;/h4&gt;  &lt;p&gt;As of v2.17, TestDriven.Net has a Visual Studio preferences page that allows the user to configure a couple of different settings.&lt;/p&gt;  &lt;p&gt;In this update of Gallio we have added support for the TestDriven.Net category filter options.&amp;#160; This feature was absent in previous releases because we did not then have a way to express exclusion filters properly.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_X_hvY6E0egY/SdSAbMBM7gI/AAAAAAAAAXE/9dIwA3Exytw/s1600-h/image%5B3%5D.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="371" alt="image" src="http://lh6.ggpht.com/_X_hvY6E0egY/SdSAcEvJ1jI/AAAAAAAAAXI/RnZpL2LoSJw/image_thumb%5B1%5D.png?imgmax=800" width="644" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h4&gt;New Assembly Version Numbering Scheme&lt;/h4&gt;  &lt;p&gt;Plug-in authors rejoice!&amp;#160; I've changed how assembly version numbers are constructed in a subtle but important way.&lt;/p&gt;  &lt;p&gt;Previously the assembly version number would change after each build.&amp;#160; As a result, code linked to &lt;em&gt;Gallio&lt;/em&gt; &lt;em&gt;v3.0.6.&lt;strong&gt;749&lt;/strong&gt;&lt;/em&gt; wouldn't work with &lt;em&gt;Gallio&lt;/em&gt; &lt;em&gt;v3.0.6.&lt;strong&gt;762&lt;/strong&gt;&lt;/em&gt; despite there being no significant API changes between those versions.&lt;/p&gt;  &lt;p&gt;Now the last component of the assembly version number is always &lt;strong&gt;&lt;em&gt;0&lt;/em&gt;&lt;/strong&gt;.&amp;#160; This way there can be no assembly version conflicts within a given release branch.&amp;#160; However, we still need a way to distinguish different builds.&amp;#160; So the file version number contains the full version number.&lt;/p&gt;  &lt;p&gt;For example, in this release the version numbers are set as follows:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Assembly version: &lt;em&gt;v3.0.6.&lt;strong&gt;0&lt;/strong&gt;.&lt;/em&gt;&lt;/li&gt;    &lt;li&gt;File version: &lt;em&gt;v3.0.6.&lt;strong&gt;763&lt;/strong&gt;&lt;/em&gt;.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;As a result, you should no longer need to recompile your plug-ins except to make them work with a new release branch.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Aside: There is now a separate branch for Gallio and MbUnit v3.0.6 in case you want to check out the code and play with it.&amp;#160; This will also help us keep maintenance updates on track.&lt;/em&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023944205100803414-8193803244451151122?l=blog.bits-in-motion.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.bits-in-motion.com/feeds/8193803244451151122/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9023944205100803414&amp;postID=8193803244451151122" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/8193803244451151122?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/8193803244451151122?v=2" /><link rel="alternate" type="text/html" href="http://blog.bits-in-motion.com/2009/04/announcing-gallio-and-mbunit-v306.html" title="Announcing Gallio and MbUnit v3.0.6 Update 1." /><author><name>Jeff Brown</name><uri>http://www.blogger.com/profile/09075745057339916352</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03263874364951229913" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total></entry><entry gd:etag="W/&quot;DUQHR344eSp7ImA9WxVbFk4.&quot;"><id>tag:blogger.com,1999:blog-9023944205100803414.post-9048307995117079348</id><published>2009-04-01T18:55:00.001-07:00</published><updated>2009-04-01T18:55:36.031-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-01T18:55:36.031-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="gallio" /><category scheme="http://www.blogger.com/atom/ns#" term="mbunit" /><title>Gallio is not Alpha Anymore (And Has Not Been Since Last Year)</title><content type="html">&lt;p&gt;I sometimes receive questions from people about when Gallio and MbUnit v3 will be out of alpha.&lt;/p&gt;  &lt;p&gt;The answer is that they have been out of alpha officially since the v3.0.4 release last year.&amp;#160; The current releases should be considered stable and final.&amp;#160; Sure, there are still bugs to be fixed and enhancements yet to be made but we do consider these releases quite acceptable for use in production systems.&lt;/p&gt;  &lt;p&gt;So there you go.&amp;#160; :-)&lt;/p&gt;  &lt;div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:63b9a87b-e268-4d9c-9d2c-8eab8e18521f" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/gallio" rel="tag"&gt;gallio&lt;/a&gt;,&lt;a href="http://technorati.com/tags/mbunit" rel="tag"&gt;mbunit&lt;/a&gt;&lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023944205100803414-9048307995117079348?l=blog.bits-in-motion.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.bits-in-motion.com/feeds/9048307995117079348/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9023944205100803414&amp;postID=9048307995117079348" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/9048307995117079348?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/9048307995117079348?v=2" /><link rel="alternate" type="text/html" href="http://blog.bits-in-motion.com/2009/04/gallio-is-not-alpha-anymore-and-has-not.html" title="Gallio is not Alpha Anymore (And Has Not Been Since Last Year)" /><author><name>Jeff Brown</name><uri>http://www.blogger.com/profile/09075745057339916352</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03263874364951229913" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;DkMDQXs4cCp7ImA9WxVbFkw.&quot;"><id>tag:blogger.com,1999:blog-9023944205100803414.post-1996824163806403776</id><published>2009-04-01T12:30:00.001-07:00</published><updated>2009-04-01T12:34:30.538-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-01T12:34:30.538-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="gallio" /><category scheme="http://www.blogger.com/atom/ns#" term="mbunit" /><title>How to enable or disable Visual Studio Team Test integration</title><content type="html">&lt;p&gt;Gallio provides integration with Visual Studio Team Test so that you can run your tests using the built-in Visual Studio Test View and other tools.&lt;/p&gt;  &lt;p&gt;However to make this work, the project file must be configured with an extra &amp;quot;ProjectTypeGuid&amp;quot; that that informs Visual Studio that the project should be considered a Test Project.&amp;#160; By adding or removing this element you can enable or disable support for Visual Studio Team Test.&lt;/p&gt;  &lt;h4&gt;Caveats&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;We do not install the Visual Studio Team Test integration by default anymore beginning with v3.0.6 if you perform a &amp;quot;Typical&amp;quot; install.&amp;#160; You will need to perform a &amp;quot;Complete&amp;quot; installation or ensure that the &amp;quot;Visual Studio Team System Test Runner&amp;quot; component under &amp;quot;Test Runners&amp;quot; is installed as part of a &amp;quot;Custom&amp;quot; installation.&lt;/li&gt;    &lt;li&gt;The built-in MbUnit project templates already contain the appropriate ProjectTypeGuids, so if you create a new project that way then it should just work out of the box.&lt;/li&gt;    &lt;li&gt;Some editions of Visual Studio lack support for Test Projects and will &lt;em&gt;refuse&lt;/em&gt; to open up any project that contains the special guid!&amp;#160; In this case you may have to remove the offending guid so that you can work with your projects.&lt;/li&gt;    &lt;li&gt;The Visual Studio Team Test integration is very rough.&amp;#160; It has poor performance due to several issues including the fact that Visual Studio wants to populate its list of tests in the foreground after compiling a test project.&amp;#160; So the GUI may hang for some time after each build if the Test View is open and you have a big test project.&amp;#160; I really hope they fix this in Visual Studio 2010.&lt;/li&gt;    &lt;li&gt;At this time, the integration only works with MbUnit v2, MbUnit v3 and xUnit.net.&amp;#160; Unfotunately csUnit and NUnit do not support the use of an abstract reflection policy so they are not supported by this feature.&amp;#160; However, there does exist another Visual Studio Team Test add-in for NUnit.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;In all honesty, I would recommend using TestDriven.Net or ReSharper to run your tests inside Visual Studio instead of using the Test View.&lt;/p&gt;  &lt;h4&gt;Editing Project Files&lt;/h4&gt;  &lt;p&gt;Visual Studio uses a magic &amp;quot;ProjectTypeGuid&amp;quot; to determine whether it should consider a given project to be a Test Project.&amp;#160; Only Test Projects are considered when populating the Test View.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;And the magic guid is... {3AC096D0-A1C2-E12C-1390-A8335801FDAB}&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;Here's how to edit the files:&lt;/p&gt;  &lt;p&gt;1. Open up the *.csproj or *.vbproj file in a text editor.&amp;#160; It's just XML (actually an MSBuild build script).&lt;/p&gt;  &lt;p&gt;2. Within the &lt;strong&gt;first&lt;/strong&gt; &amp;lt;PropertyGroup&amp;gt; element at the top of the file, look for an existing &amp;lt;ProjectTypeGuids&amp;gt; element.&lt;/p&gt;  &lt;p&gt;2a. If you found the &amp;lt;ProjectTypeGuids&amp;gt; element, then add the aforementioned Guid to the list within if not already present.&amp;#160; Be sure to separate the guids with semicolons.&lt;/p&gt;  &lt;p&gt;2b. If you did not find a &amp;lt;ProjectTypeGuids&amp;gt; element, then copy and paste in the appropriate element below.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;     &lt;p&gt;&lt;strong&gt;C# Projects: *.csproj         &lt;br /&gt;          &lt;br /&gt;&lt;/strong&gt;&amp;lt;ProjectTypeGuids&amp;gt;{3AC096D0-A1C2-E12C-1390-A8335801FDAB};        &lt;br /&gt;{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}&amp;lt;/ProjectTypeGuids&amp;gt;&lt;/p&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;ul&gt;   &lt;li&gt;     &lt;p&gt;&lt;strong&gt;Visual Basic Projects: *.vbproj         &lt;br /&gt;          &lt;br /&gt;&lt;/strong&gt;&amp;lt;ProjectTypeGuids&amp;gt;{3AC096D0-A1C2-E12C-1390-A8335801FDAB};        &lt;br /&gt;{F184B08F-C81C-45F6-A57F-5ABD9991F28F}&amp;lt;/ProjectTypeGuids&amp;gt;&lt;/p&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;3. Save the project file.&lt;/p&gt;  &lt;p&gt;4. Reload the project in Visual Studio.&lt;/p&gt;  &lt;p&gt;5. Open up the Test View.&amp;#160; The tests in your project should now be populated.&lt;/p&gt;  &lt;h4&gt;It's Too Slow... How Do I Turn It Off?&lt;/h4&gt;  &lt;p&gt;If you read the caveats above, I warned you... :-)&lt;/p&gt;  &lt;p&gt;There are three ways to turn this off.&amp;#160; Any one of them will suffice.&lt;/p&gt;  &lt;p&gt;1. Remove the ProjectTypeGuid just added above then reload the project.&lt;/p&gt;  &lt;p&gt;2. Disable the Gallio add-in using the Visual Studio Add-In Manager.&amp;#160; Contrary to what some people expect, this will not in any way affect the ReSharper integration.&lt;/p&gt;  &lt;p&gt;3. Uninstall the &amp;quot;Visual Studio Team System Test Runner&amp;quot; component.&amp;#160; You don't need to uninstall all of Gallio for this.&amp;#160; Use the Add/Remove programs control panel to Change the set of installed features and look under the &amp;quot;Test Runners&amp;quot; part of the tree.&lt;/p&gt;  &lt;h4&gt;What The Future Holds...&lt;/h4&gt;  &lt;p&gt;I do have a hack in mind for improving performance by populating the Visual Studio test list asynchronously although it would run contrary to the stated API contracts.&amp;#160; So if the performance is a problem for you but you really really want to use the Visual Studio Team Test controls, please let me know and I'll raise the priority of this task.&amp;#160; Also I could use a volunteer to help make the integration more compelling overall.&lt;/p&gt;  &lt;p&gt;Also, some time ago I started working on a different native Visual Studio add-in for Gallio called Sail.&amp;#160; It's not ready yet but something I've been thinking about again lately...&amp;#160; If you'd like to help, let me know.&lt;/p&gt;  &lt;div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:e747cb72-528d-4696-b8c7-2654c803434d" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/gallio" rel="tag"&gt;gallio&lt;/a&gt;,&lt;a href="http://technorati.com/tags/mbunit" rel="tag"&gt;mbunit&lt;/a&gt;&lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023944205100803414-1996824163806403776?l=blog.bits-in-motion.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.bits-in-motion.com/feeds/1996824163806403776/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9023944205100803414&amp;postID=1996824163806403776" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/1996824163806403776?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/1996824163806403776?v=2" /><link rel="alternate" type="text/html" href="http://blog.bits-in-motion.com/2009/04/how-to-enable-or-disable-visual-studio.html" title="How to enable or disable Visual Studio Team Test integration" /><author><name>Jeff Brown</name><uri>http://www.blogger.com/profile/09075745057339916352</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03263874364951229913" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;C0EMQ30zeCp7ImA9WxVbFkw.&quot;"><id>tag:blogger.com,1999:blog-9023944205100803414.post-5852431595910994957</id><published>2009-04-01T11:48:00.001-07:00</published><updated>2009-04-01T11:48:02.380-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-01T11:48:02.380-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="gallio" /><category scheme="http://www.blogger.com/atom/ns#" term="mbunit" /><title>Debugging Tests with Gallio</title><content type="html">&lt;p&gt;Here's the rundown of how to debug.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Icarus:&lt;/strong&gt; Click the new &amp;quot;Debug&amp;quot; button in v3.0.6.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Visual Studio Team Test:&lt;/strong&gt; Select the tests in the Test View and click Debug.&amp;#160; (This assumes that your test project has the appropriate ProjectTypeGuid to be recognized by Visual Studio as a Test Project.&amp;#160; See next post.)&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;TestDriven.Net:&lt;/strong&gt; Right-click on a test or fixture and select &amp;quot;Test With... Debugger&amp;quot;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;ReSharper:&lt;/strong&gt; Select a test in the editor or test session view and use the Debug drop-down or toolbar button as appropriate.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Echo from command-line:&lt;/strong&gt; Run tests with /debug argument. This will automatically attach to Visual Studio (or launch it if it is not running).&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;PowerShell:&lt;/strong&gt; Use the &amp;quot;/DebugTests&amp;quot; switch for similar behavior to Echo.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;NAnt:&lt;/strong&gt; Add the debug=&amp;quot;true&amp;quot; attribute for similar behavior to Echo.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;MSBuild:&lt;/strong&gt; Add the Debug=&amp;quot;true&amp;quot; attribute for similar behavior to Echo.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;It is no longer necessary to set the test runner type to IsolatedAppDomain if you use any of the above methods to run tests with the debugger.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;On the other hand if you are attempting to attach to an existing test run of Gallio that was not started using any of the debugging mechanisms described above and the test runner type is IsolatedProcess (the default) be sure to attach to the Gallio.Host.exe or Gallio.Host.x86.exe process instead of Gallio.Icarus.exe or whatever.&lt;/em&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023944205100803414-5852431595910994957?l=blog.bits-in-motion.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.bits-in-motion.com/feeds/5852431595910994957/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9023944205100803414&amp;postID=5852431595910994957" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/5852431595910994957?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/5852431595910994957?v=2" /><link rel="alternate" type="text/html" href="http://blog.bits-in-motion.com/2009/04/debugging-tests-with-gallio.html" title="Debugging Tests with Gallio" /><author><name>Jeff Brown</name><uri>http://www.blogger.com/profile/09075745057339916352</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03263874364951229913" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;D04FQ3w_fCp7ImA9WxVbFkg.&quot;"><id>tag:blogger.com,1999:blog-9023944205100803414.post-7549239158555911592</id><published>2009-03-22T17:13:00.001-07:00</published><updated>2009-04-02T00:05:12.244-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-02T00:05:12.244-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="gallio" /><category scheme="http://www.blogger.com/atom/ns#" term="release notes" /><category scheme="http://www.blogger.com/atom/ns#" term="mbunit" /><title>Announcing Gallio and MbUnit v3.0.6</title><content type="html">&lt;p&gt;Today we are releasing Gallio and MbUnit v3.0.6.&amp;#160; Lots of new stuff, including new features and performance enhancements.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Highlights:&lt;/em&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;em&gt;Parallelizable tests.&lt;/em&gt; &lt;/li&gt;    &lt;li&gt;&lt;em&gt;One-click test debugging from Icarus.&lt;/em&gt; &lt;/li&gt;    &lt;li&gt;&lt;em&gt;Auto-reload and auto-run tests from Icarus after each build.&lt;/em&gt; &lt;/li&gt;    &lt;li&gt;&lt;em&gt;ReSharper 4.5 beta support with improved performance.&lt;/em&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Download here: &lt;a href="http://www.gallio.org/Downloads.aspx"&gt;http://www.gallio.org/Downloads.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Documentation here: &lt;a href="http://www.gallio.org/Docs.aspx"&gt;http://www.gallio.org/Docs.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Release notes: &lt;a href="http://blog.bits-in-motion.com/search/label/release%20notes"&gt;All release notes from all versions&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Remark (added 3/27):&lt;/strong&gt; We strongly recommend upgrading to ReSharper v4.5 beta and TestDriven.Net v2.18+ before installing this release since there have been significant performance improvements.&amp;#160; Also it appears there may be a regression in the Gallio support for older ReSharper versions that can result in deadlock during test exploration.&amp;#160; (If for some reason you cannot upgrade at this time and you are experiencing this problem, you may try a recent nightly build instead.)&lt;/p&gt;  &lt;h3&gt;Acknowledgements&lt;/h3&gt;  &lt;p&gt;In this release I would like to especially acknowledge Graham Hay for his work enhancing Icarus with new features such as running tests with the debugger and also Yann Tr&amp;#233;vin for his work designing and building the MbUnit v3 contract verifiers.&amp;#160; Eddy Young also helped add support for running MSTest 2005 tests (previously we only supported MSTest 2008).&lt;/p&gt;  &lt;p&gt;I would also like to thank all of the other members of the community who contributed valuable feedback, patches and support during this release cycle.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Thanks!&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Edit: Fixed Eddy Young's name in the acknowledgements.&amp;#160; Thanks Eddy!&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;h3&gt;MbUnit&lt;/h3&gt;  &lt;h4&gt;Parallelizable&lt;/h4&gt;  &lt;p&gt;With v3.0.6, MbUnit helps you get the most out of your multi-core CPU.&amp;#160; Mark any test [Parallelizable] and it will be permitted to run in parallel with other parallelizable tests in the same fixture.&lt;/p&gt;  &lt;p&gt;Fixtures can also be marked parallelizable to enable them to be run in parallel with other parallelizable fixtures.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_X_hvY6E0egY/ScsWP-yEbXI/AAAAAAAAAVo/JAJ5eCW3ZFQ/s1600-h/image%5B11%5D.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="402" alt="image" src="http://lh6.ggpht.com/_X_hvY6E0egY/ScsWRBgeILI/AAAAAAAAAVs/2KG882awvHo/image_thumb%5B5%5D.png?imgmax=800" width="720" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Please note that if you want all tests within a fixture to be considered parallelizable then you still need to add [Parallelizable] to each of them.&amp;#160; (We might add a feature to set this at the fixture or assembly level later based on user feedback.)&lt;/p&gt;  &lt;p&gt;Also note that just because a test or fixture is marked parallelizable does not mean it will run in parallel with other tests in particular.&amp;#160; For the sake of efficiency, we limit the number of active tests threads based on the configured degree of parallelism.&amp;#160; If you want a specific number of instances of a test to run in parallel with each other, consider using [ThreadedRepeat].&lt;/p&gt;  &lt;h4&gt;DegreeOfParallelism&lt;/h4&gt;  &lt;p&gt;The degree of parallelism setting controls the maximum number of tests that MbUnit will attempt to run in parallel with one another.&amp;#160; By default, the degree of parallelism equals the number of CPUs you have, or 2 at a minimum.&lt;/p&gt;  &lt;p&gt;If you don't like the default then you can override the degree of parallelism at the assembly-level like this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_X_hvY6E0egY/ScsWRl816_I/AAAAAAAAAVw/-1QwSSBvMCo/s1600-h/image%5B10%5D.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="39" alt="image" src="http://lh4.ggpht.com/_X_hvY6E0egY/ScsWSZzjjjI/AAAAAAAAAV4/KzyvWIDHStA/image_thumb%5B4%5D.png?imgmax=800" width="535" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;h4&gt;DefaultTestCaseTimeout (Breaking Change!)&lt;/h4&gt;  &lt;p&gt;In MbUnit v2 and earlier versions of MbUnit v3, there was a non-configurable default timeout of 10 minutes per test fixture.&amp;#160; Now we have a configurable default timeout of 10 minutes per test case.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Old behaviour:&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;10 minute timeout &lt;strong&gt;per fixture&lt;/strong&gt; &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;non-configurable&lt;/strong&gt; &lt;/li&gt;    &lt;li&gt;override by setting [Timeout] attribute &lt;strong&gt;on the fixture&lt;/strong&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;New behaviour:&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;10 minute timeout &lt;strong&gt;per test case&lt;/strong&gt; &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;configurable&lt;/strong&gt; with [DefaultTestCaseTimeout] on the assembly &lt;/li&gt;    &lt;li&gt;override by setting [Timeout] attribute &lt;strong&gt;on the test&lt;/strong&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;We have a default timeout in place because it's useful for the sake of robustness.&amp;#160; Otherwise tests could just run forever if left unattended.&amp;#160; This is different from NUnit which has no timeout by default (even if you use Gallio to run your NUnit tests).&lt;/p&gt;  &lt;p&gt;If you absolutely hate timeouts... here's what you need to do:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_X_hvY6E0egY/ScsWS1L8zwI/AAAAAAAAAV8/1XG3ZHb8970/s1600-h/image%5B15%5D.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="86" alt="image" src="http://lh4.ggpht.com/_X_hvY6E0egY/ScsWTr2alMI/AAAAAAAAAWA/UpwUiftD8F4/image_thumb%5B7%5D.png?imgmax=800" width="348" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;h4&gt;Contact Verifiers Redux (Breaking Change!)&lt;/h4&gt;  &lt;p&gt;Contract verifiers simplify the process of testing that an implementation of a common contract is correct.&amp;#160; For example, they can help you test your custom Exception class, verify that your datatype's Equals &amp;amp; GetHashCode are consistent, and check IList&amp;lt;T&amp;gt; invariants.&lt;/p&gt;  &lt;p&gt;We originally introduced this feature in MbUnit v3.0.4, updated it in v3.0.5 and Yann Tr&amp;#233;vin has been busy making it better for v3.0.6!&lt;/p&gt;  &lt;p&gt;Instead of using custom attributes to use a contract verifier, we now use a read-only field in the test fixture.&amp;#160; This change makes the syntax much more expressive, but you will have to update any tests written in the old style.&lt;/p&gt;  &lt;p&gt;More documentation here: &lt;a href="http://www.gallio.org/book/XHtml/ch10.html"&gt;Contract Verifiers Chapter in Gallio Book&lt;/a&gt;&amp;#160;&lt;em&gt;(url subject to change)&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;In this example, we are testing whether the &lt;strong&gt;Parity&lt;/strong&gt; class implements the Equatable contract correctly.&amp;#160; The contract verifier ensures that all members of the equivalence classes are considered equal to each other (and have the same hashcode); that all members of different equivalence classes are considered unequal; ensures that null values are handled correctly and that both Equals(object) and Equals(Parity) behave the same way.&amp;#160; It could also check operator overloads, if we implemented them.&lt;/p&gt;  &lt;h5&gt;The subject under test...&lt;/h5&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_X_hvY6E0egY/ScsWU-aSrRI/AAAAAAAAAWE/gFO9KiYfZxw/s1600-h/image%5B19%5D.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="489" alt="image" src="http://lh6.ggpht.com/_X_hvY6E0egY/ScsWWDRCbFI/AAAAAAAAAWI/LZIk_PvSf4k/image_thumb%5B9%5D.png?imgmax=800" width="592" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;h5&gt;The test...&lt;/h5&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_X_hvY6E0egY/ScsWW6XOBAI/AAAAAAAAAWM/8hfvSua-ChU/s1600-h/image%5B23%5D.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="214" alt="image" src="http://lh3.ggpht.com/_X_hvY6E0egY/ScsWYFvr-dI/AAAAAAAAAWQ/5gtNrEp68zQ/image_thumb%5B11%5D.png?imgmax=800" width="622" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;h4&gt;Xml Data Source&lt;/h4&gt;  &lt;p&gt;The CSV data source has been very popular.&amp;#160; Did you know you can associate metadata with CSV data rows, like expected exceptions?&amp;#160; Just add a column with a header like &amp;quot;[ExpectedException]&amp;quot;, &amp;quot;[Description]&amp;quot;, or some other metadata.&lt;/p&gt;  &lt;p&gt;In v3.0.6, we now have an XML data source too.&lt;/p&gt;  &lt;h5&gt;Some data, including a little custom metadata...&lt;/h5&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_X_hvY6E0egY/ScsWZLO-PVI/AAAAAAAAAWU/ZqaDoKvrbCc/s1600-h/image%5B27%5D.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="323" alt="image" src="http://lh4.ggpht.com/_X_hvY6E0egY/ScsWZ7-B1aI/AAAAAAAAAWY/M8K2dNnMTkk/image_thumb%5B13%5D.png?imgmax=800" width="386" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;h5&gt;The test...&lt;/h5&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_X_hvY6E0egY/ScsWaivu22I/AAAAAAAAAWc/DAXDDa4eDxo/s1600-h/image%5B31%5D.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="142" alt="image" src="http://lh6.ggpht.com/_X_hvY6E0egY/ScsWcK2iHQI/AAAAAAAAAWg/gUkBueZ5sg0/image_thumb%5B15%5D.png?imgmax=800" width="379" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;h5&gt;The output in the report, notice the metadata...&lt;/h5&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_X_hvY6E0egY/ScsWc_dX9fI/AAAAAAAAAWk/zL_8ok5fvks/s1600-h/image%5B35%5D.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="244" alt="image" src="http://lh3.ggpht.com/_X_hvY6E0egY/ScsWeMknKMI/AAAAAAAAAWo/hLO5PpVhjiM/image_thumb%5B17%5D.png?imgmax=800" width="425" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Next up, does anyone want a SQL data source?&lt;/p&gt;  &lt;h4&gt;Serialization Asserts&lt;/h4&gt;  &lt;p&gt;This release includes a couple of new Assertions to help with testing serialization.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;.Net serialization protocol asserts:&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Assert.IsSerializableType&lt;/strong&gt;: Asserts that a type supports .Net serialization by way of the [Serializable] attribute.&amp;#160; Also ensures that type has a deserialization constructor if it also implements ISerializable. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Assert.Serialize&lt;/strong&gt;: Serializes a value using a .Net serialization formatter.&amp;#160; Asserts that serialization succeeded and returns resulting serialized value as a stream. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Assert.Deserialize&lt;/strong&gt;: Deserializes a value using a .Net serialization formatter.&amp;#160; Asserts that deserialization succeeded and returns the resulting deserialized value. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Assert.SerializeThenDeserialize&lt;/strong&gt;: Serializes then deserializes a value using a .Net serialization formatter.&amp;#160; Asserts that both serialization and deserialization succeeded and returns the resulting deserialized value after the round-trip. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Assert.BinarySerialize&lt;/strong&gt;: Shortcut for Assert.Serialize using a BinaryFormatter. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Assert.BinaryDeserialize&lt;/strong&gt;: Shortcut for Assert.Deserialize using a BinaryFormatter. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Assert.BinarySerializeThenDeserialize&lt;/strong&gt;: Shortcut for Assert.SerializeThenDeserialize using a BinaryFormatter. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;Xml serialization protocol asserts:&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Assert.IsXmlSerializableType&lt;/strong&gt;: Asserts that an XmlSerializer can be constructed for a given type without error. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Assert.XmlSerialize&lt;/strong&gt;: Serializes a value using an XmlSerializer.&amp;#160; Asserts that serialization succeeded and returns the resulting Xml as a string. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Assert.XmlDeserialize&lt;/strong&gt;: Deserializes a value using an XmlSerializer.&amp;#160; Asserts that deserialization succeeded and returns the resulting deserialized value. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Assert.XmlSerializeThenDeserialize&lt;/strong&gt;: Serializes then deserialized a value using an XmlSerializer.&amp;#160; Asserts that both serialization and deserialization succeeded and returns the resulting deserialized value after the round-trip. &lt;/li&gt; &lt;/ul&gt;  &lt;h5&gt;Typical usage...&lt;/h5&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_X_hvY6E0egY/ScsWezLv6uI/AAAAAAAAAWs/6-iJ-TVqa5g/s1600-h/image%5B39%5D.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="441" alt="image" src="http://lh3.ggpht.com/_X_hvY6E0egY/ScsWf86sr4I/AAAAAAAAAWw/3QwFihHoo6w/image_thumb%5B19%5D.png?imgmax=800" width="543" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;h4&gt;Terminating Tests with Specific Outcomes&lt;/h4&gt;  &lt;p&gt;MbUnit v3 includes several methods for controlling the outcome of a test, including a couple of new ones introduced in v3.0.6.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Assert.Fail&lt;/strong&gt;: Raises an assertion failure by throwing an AssertionFailedException, resulting in a &lt;em&gt;failed&lt;/em&gt; outcome.&amp;#160; If executed within an Assert.Multiple block or in a test with [MultipleAsserts] then the failure is logged but the exception is deferred until the end of the block or of the test. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Assert.Inconclusive&lt;/strong&gt;: Terminates a test by throwing a TestInconclusiveException, resulting in an &lt;em&gt;inconclusive &lt;/em&gt;outcome. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;[new!]&amp;#160; Assert.Terminate&lt;/strong&gt;: Terminates a test by throwing a TestTerminatedException, resulting in a user-specified outcome. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;[new!]&amp;#160; Assert.TerminateSilently&lt;/strong&gt;: Terminates a test by throwing a SilentTestException, resulting in a user-specified outcome.&amp;#160; Unlike Assert.Terminate, does not log a stack trace at the point of termination. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;[new!]&amp;#160; Assert.IsFailurePending&lt;/strong&gt;: Indicates whether an assertion failure has been raised but the AssertionFailedException has not yet been thrown.&amp;#160; This is used in conjunction with Assert.Multiple to determine whether any failures have already been observed within the block. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;Reminder:&amp;#160; &lt;/strong&gt;There are two mechanisms in MbUnit to enable a test with multiple assertions to keep running even if some of them fail.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Assert.Multiple&lt;/strong&gt;: Runs a block of code that may contain multiple assertions.&amp;#160; If any assertions fail then the test will be terminated&amp;#160; with a &lt;em&gt;failed&lt;/em&gt; outcome when the block finishes. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;[MultipleAsserts]&lt;/strong&gt;: You may add the MultipleAsserts attribute to a test to effectively run the whole test within an Assert.Multiple block. &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;Diagnostic Log&lt;/h4&gt;  &lt;p&gt;A few people have asked how to print progress messages from tests.&amp;#160; They try TestLog, Debug.WriteLine and Console.WriteLine, and sure enough, nothing gets printed to the console, by design.&amp;#160; We capture all of this information and write it to the test report.&lt;/p&gt;  &lt;p&gt;Now you can use &lt;strong&gt;DiagnosticLog.WriteLine &lt;/strong&gt;to&amp;#160; write progress messages to the TestDriven.Net output window, the Icarus Runtime Log view or the console when running Echo, NAnt, MSBuild or PowerShell.&lt;/p&gt;  &lt;h3&gt;Icarus&lt;/h3&gt;  &lt;h4&gt;One-Click Debugging&lt;/h4&gt;  &lt;p&gt;Icarus can now run tests under the debugger with just one click of the &amp;quot;Debug&amp;quot; button.&amp;#160; It will attach (or launch) the Visual Studio debugger to the test process and start the tests.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;There is no longer any need to change the test runner type or to manually attach to the Icarus process.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_X_hvY6E0egY/ScsWgpt2I_I/AAAAAAAAAW0/W9D5UIBw9D8/s1600-h/image%5B43%5D.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="245" alt="image" src="http://lh3.ggpht.com/_X_hvY6E0egY/ScsWhcIaObI/AAAAAAAAAW4/d2BEIcLiFnM/image_thumb%5B21%5D.png?imgmax=800" width="570" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;h4&gt;Auto-Reload and Auto-Run&lt;/h4&gt;  &lt;p&gt;Icarus now supports automatically reloading and running all loaded tests whenever they are recompiled.&lt;/p&gt;  &lt;p&gt;In v3.0.6, these features are controlled by a Preference.&amp;#160; In future releases we will probably make them available from the toolbar so that it is easier to switch modes on demand.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_X_hvY6E0egY/ScsWioHfT9I/AAAAAAAAAW8/pqsOqDcK1h0/s1600-h/image%5B47%5D.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="472" alt="image" src="http://lh3.ggpht.com/_X_hvY6E0egY/ScsWjpY1qPI/AAAAAAAAAXA/VhDrZSWQMV4/image_thumb%5B23%5D.png?imgmax=800" width="647" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;h3&gt;Additional Test Runner Enhancements&lt;/h3&gt;  &lt;h4&gt;Passing Additional Arguments to NCover&lt;/h4&gt;  &lt;p&gt;Gallio includes support for launching tests with NCover already attached.&amp;#160; By default, the coverage report is written out to &amp;quot;Coverage.xml&amp;quot; in the current directory of the test run.&lt;/p&gt;  &lt;p&gt;In v3.0.6 we have added the ability to change the location of the coverage file and to pass additional arguments to NCover.&amp;#160; Typically you will want to pass additional arguments to inform NCover to exclude certain assemblies from code coverage.&lt;/p&gt;  &lt;p&gt;Here is an example using Gallio.Echo to run the tests from the command-line.&amp;#160; If you are using NAnt, MSBuild or Powershell then the process is similar.&amp;#160; Refer to the &lt;a href="http://www.gallio.org/Docs.aspx"&gt;Documentation&lt;/a&gt; for details of how to pass the &lt;strong&gt;NCoverCoverageFile&lt;/strong&gt; and &lt;strong&gt;NCoverArguments&lt;/strong&gt; &amp;quot;runner properties&amp;quot; in each case.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Gallio.Echo.exe Widget.Tests.dll /runner:&lt;strong&gt;NCover&lt;/strong&gt; /runner-property:&lt;strong&gt;NCoverCoverageFile&lt;/strong&gt;='C:\Temp\WidgetCoverage.xml' /runner-property:&lt;strong&gt;NCoverArguments&lt;/strong&gt;='//eas .*.Tests;Gallio;MbUnit;OtherIgnoredAssembly'&lt;/p&gt; &lt;/blockquote&gt;  &lt;h4&gt;Echo Support for Test Projects&lt;/h4&gt;  &lt;p&gt;Echo now supports running test projects such as are created by Icarus.&amp;#160; Just pass it in on the command-line.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Gallio.Echo.exe &lt;strong&gt;WidgetTests.gallio&lt;/strong&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;h4&gt;Launch Tests With Debugger Attached&lt;/h4&gt;  &lt;p&gt;It is now possible to launch tests with the debugger attached from Echo, NAnt, MSBuild or PowerShell by adding the &amp;quot;debug&amp;quot; argument.&lt;/p&gt;  &lt;p&gt;Here is an example for Echo.&amp;#160; The other runners are similar.&amp;#160; Refer to the &lt;a href="http://www.gallio.org/Docs.aspx"&gt;Documentation&lt;/a&gt; for details of how to pass the &lt;strong&gt;Debug &lt;/strong&gt;option in each case.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Gallio.Echo.exe Widget.Tests.dll &lt;strong&gt;/debug&lt;/strong&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;h5&gt;Total Run-Time Limit&lt;/h5&gt;  &lt;p&gt;To limit the total amount of&amp;#160; time that the tests are allowed to run, specify the total run-time limit.&amp;#160; This is a good idea when incorporating tests into a Continuous Integration build to ensure that runaway tests don't get to run for &lt;em&gt;too&lt;/em&gt; long.&lt;/p&gt;  &lt;p&gt;Here is an example for Echo.&amp;#160; The other runners are similar.&amp;#160; Refer to the &lt;a href="http://www.gallio.org/Docs.aspx"&gt;Documentation&lt;/a&gt; for details of how to pass the &lt;strong&gt;RunTimeLimit &lt;/strong&gt;option in each case.&amp;#160; The time span is specified in seconds.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Gallio.Echo.exe Widget.Tests.dll &lt;strong&gt;/run-time-limit:600&lt;/strong&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;h3&gt;External Tools Compatibility&lt;/h3&gt;  &lt;p&gt;We've updated integration with a variety of external tools.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;CCNet v1.0.4 &lt;/li&gt;    &lt;li&gt;CSUnit v2.0.5 &lt;/li&gt;    &lt;li&gt;NUnit v2.4.8 &lt;/li&gt;    &lt;li&gt;Pex v0.9 Academic &lt;/li&gt;    &lt;li&gt;TypeMock v5.1 &lt;/li&gt;    &lt;li&gt;TestDriven.Net v2.19 &lt;/li&gt;    &lt;li&gt;NCover v1.5.8, v2, v3. &lt;/li&gt;    &lt;li&gt;ReSharper v3.1, v4.0, v4.1 , v4.5 Beta &lt;/li&gt;    &lt;li&gt;TeamCity v4.0 &lt;/li&gt;    &lt;li&gt;xUnit.Net v1.0.3 &lt;/li&gt;    &lt;li&gt;Visual Studio 2005, 2008 (for VS 2010 support, use Gallio v3.0.5 for now)&lt;em&gt;&amp;#160;&lt;/em&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;Change Summary&lt;/h3&gt;  &lt;h4&gt;Gallio Core&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;Redesigned test lifecycle to significantly improve performance when running tests in multiple test assemblies as a batch. &lt;/li&gt;    &lt;li&gt;Added a debugging API, use to provide new debugging features in test runners. &lt;/li&gt;    &lt;li&gt;Fixed an issue with significant whitespace being unintentionally dropped from the report due to XML whitespace handling. &lt;/li&gt;    &lt;li&gt;Added an XSD file for Gallio reports. &lt;/li&gt;    &lt;li&gt;Dropped dependency on ISymWrapper.&amp;#160; There should be no more Exception Assistant dialogs about COMExceptions popping up in Visual Studio while launching the tests. &lt;/li&gt;    &lt;li&gt;Removed a stray UTF8 Byte Order Mark that appeared in HTML formatted reports. &lt;/li&gt;    &lt;li&gt;Gallio registers its TestDriven.Net extensions even if TestDriven.Net is not yet installed. &lt;/li&gt;    &lt;li&gt;Added support for passing custom properties to test hosts and report formatters. &lt;/li&gt;    &lt;li&gt;Improved diagnostics when running tests out of process. &lt;/li&gt;    &lt;li&gt;Various API changes and refactoring. &lt;/li&gt;    &lt;li&gt;Added support for jumping to the source code of a test from the report. &lt;/li&gt;    &lt;li&gt;Added support for capturing diagnostic log messages during test execution. &lt;/li&gt;    &lt;li&gt;Improved the Navigator feature (jump to source from a report) to automatically launch Visual Studio if needed. &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;MbUnit v3&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;Added [Parallelizable], [DegreeOfParallelism], [DefaultTestCaseTimeout] and [XmlData]. &lt;/li&gt;    &lt;li&gt;Added assertions and helpers: Terminate, TerminateSilently, IsFailurePending, IsBinarySerializable, IsXmlSerializable. &lt;/li&gt;    &lt;li&gt;Added DiagnosticLog class for writing to the log. &lt;/li&gt;    &lt;li&gt;Fixed [Factory] data sources defined on generic types. &lt;/li&gt;    &lt;li&gt;Fixed dynamic test outcome reporting. &lt;/li&gt;    &lt;li&gt;Fixed project templates for VB.Net. &lt;/li&gt;    &lt;li&gt;Fixed Assert.EndsWith failure message. &lt;/li&gt;    &lt;li&gt;Added generic variations of Assert.Is[Not]InstanceOfType and Assert.Is[Not]AssignableFrom. &lt;/li&gt;    &lt;li&gt;Fixed a faulty assertion in the Exception contract verifier regarding the setting of the Exception's Message property. &lt;/li&gt;    &lt;li&gt;Fixed an issue enumerating tests in nested types that inherit from one of their own containing types. &lt;/li&gt;    &lt;li&gt;Modified [Rollback] to enter a COM+ transaction context like MbUnit v2's original rollback attribute.&amp;#160; This should fix compatibility issues others have noted. &lt;/li&gt;    &lt;li&gt;Fixed inheritance of [Row] attribute (and others) on test methods in derived classes. &lt;/li&gt;    &lt;li&gt;Added TestStep.RunStepAndVerifyOutcome. &lt;/li&gt;    &lt;li&gt;Fixed an issue with [MultipleAssert] affecting nested test steps. &lt;/li&gt;    &lt;li&gt;Renamed MetadataKeys.CategoryName to MetadataKeys.Category. &lt;/li&gt;    &lt;li&gt;Modified [StaticTestFactory] to run tests in the exact order specified. &lt;/li&gt;    &lt;li&gt;Now tolerates missing metadata columns in CSV files. &lt;/li&gt;    &lt;li&gt;Applied neoeinstein's patch providing IComparer&amp;lt;T&amp;gt; based overloads for relational asserts such as Assert.IsLessThan. &lt;/li&gt;    &lt;li&gt;Added DiagnosticLog class to enable users to write messages to the console during test execution. &lt;/li&gt;    &lt;li&gt;Eliminated a deep recursion issue in BaseTest.IsLocalIdUniqueAmongSiblings that caused a StackOverflowException. &lt;/li&gt;    &lt;li&gt;Changed timeout policy to apply per-test case not per fixture. &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;MbUnit v2 Adapter&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;Fixed MbUnit v2 adapter top-level assembly outcome reporting. &lt;/li&gt;    &lt;li&gt;Ported old MbUnit v2 XmlAsserts over to MbUnit.Compatibility.dll. &lt;/li&gt;    &lt;li&gt;Fixed a problem where the CCNet integration documentation was not being installed. &lt;/li&gt;    &lt;li&gt;Fixed a problem displaying attachments in CCNet. &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;MSTest Adapter&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;Auto-detect the version of the MSTest framework referenced by tests.&amp;#160; MSTest 2005 not currently supported.&amp;#160; (volunteer needed) &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;Icarus&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;Added &amp;quot;Debug&amp;quot; command to run tests with the debugger! &lt;/li&gt;    &lt;li&gt;Fixed Icarus filter inconclusive. &lt;/li&gt;    &lt;li&gt;Improved Icarus view source from the test tree. &lt;/li&gt;    &lt;li&gt;Check to ensure assemblies exist before reloading. &lt;/li&gt;    &lt;li&gt;Icarus now remembers its position and size between executions. &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;Echo&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;Added support for running Icarus projects. &lt;/li&gt;    &lt;li&gt;Added /debug switch to run tests with the debugger. &lt;/li&gt;    &lt;li&gt;Added /runtimelimit switch to set a time limit on test execution. &lt;/li&gt;    &lt;li&gt;Added /runner-property option to pass custom options to the test runner. &lt;/li&gt;    &lt;li&gt;Added /report-formatter-property option to pass custom options to the report formatter. &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;NAnt&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;Added debug attribute to run tests with the debugger. &lt;/li&gt;    &lt;li&gt;Added run-time-limit attribute to set a time limit on test execution. &lt;/li&gt;    &lt;li&gt;Added runner-property element to pass custom options to the test runner. &lt;/li&gt;    &lt;li&gt;Added report-formatter-property element to pass custom options to the report formatter. &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;MSBuild&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;Added Debug attribute to run tests with the debugger. &lt;/li&gt;    &lt;li&gt;Added RunTimeLimit attribute to set a time limit on test execution. &lt;/li&gt;    &lt;li&gt;Added RunnerProperties element to pass custom options to the test runner. &lt;/li&gt;    &lt;li&gt;Added ReportFormatterProperties element to pass custom options to the report formatter. &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;PowerShell&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;Added -DebugTests switch to run tests with the debugger. &lt;/li&gt;    &lt;li&gt;Added -RunTimeLimit switch to set a time limit on test execution. &lt;/li&gt;    &lt;li&gt;Added -RunnerProperties option to pass custom options to the test runner. &lt;/li&gt;    &lt;li&gt;Added -ReportFormatterProperties option to pass custom options to the report formatter. &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;ReSharper&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;Added support for ReSharper v4.5 beta. &lt;/li&gt;    &lt;li&gt;Added memoization to the reflection API to improve performance. &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;Visual Studio Team Test&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;Now runs tests in a background thread to provide better feedback during execution. &lt;/li&gt;    &lt;li&gt;Added memoization to the reflection API to improve performance. &lt;/li&gt;    &lt;li&gt;The MSTest adapter now support MSTest 2005 in addition to 2008. &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;NCover&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;Added support for NCover v3. &lt;/li&gt;    &lt;li&gt;Added &amp;quot;NCoverCoverageFile&amp;quot; and &amp;quot;NCoverArguments&amp;quot; properties to tweak the command-line. &lt;/li&gt;    &lt;li&gt;Fixed several issues that caused long-running coverage runs to fail. &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;TypeMock&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;Updated to TypeMock v5.1 integration assembly. &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;Pex&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;Upgraded Pex support for v0.9 Academic. &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;AutoCAD&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;Read Gallio's process id more robustly. &lt;/li&gt; &lt;/ul&gt;  &lt;div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:5a9d1ac1-b0eb-44ba-b803-02deb97c41fb" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/gallio" rel="tag"&gt;gallio&lt;/a&gt;,&lt;a href="http://technorati.com/tags/mbunit" rel="tag"&gt;mbunit&lt;/a&gt;&lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023944205100803414-7549239158555911592?l=blog.bits-in-motion.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.bits-in-motion.com/feeds/7549239158555911592/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9023944205100803414&amp;postID=7549239158555911592" title="10 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/7549239158555911592?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/7549239158555911592?v=2" /><link rel="alternate" type="text/html" href="http://blog.bits-in-motion.com/2009/03/announcing-gallio-and-mbunit-v306.html" title="Announcing Gallio and MbUnit v3.0.6" /><author><name>Jeff Brown</name><uri>http://www.blogger.com/profile/09075745057339916352</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03263874364951229913" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">10</thr:total></entry><entry gd:etag="W/&quot;CEQGRn09fip7ImA9WxVUEko.&quot;"><id>tag:blogger.com,1999:blog-9023944205100803414.post-1305985146573413889</id><published>2009-03-16T23:44:00.001-07:00</published><updated>2009-03-16T23:45:27.366-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-16T23:45:27.366-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="gallio" /><title>Gallio v3.1 may use a message bus.</title><content type="html">&lt;p&gt;After hanging out at QCon San Francisco last fall with the likes of Dave Laribee, Greg Young, Dru Sellers and Chris Patterson, I got to thinking about some problems I've been having with Gallio's communication patterns.&lt;/p&gt;  &lt;h4&gt;Why Use a Message Bus?&lt;/h4&gt;  &lt;p&gt;1. One-way asynchronous message passing is useful for publishing incremental status updates, notifications and interruption requests during the execution of long-running processes.&amp;#160;&amp;#160; Doing this with remote procedure calls requires callback interfaces, bi-directional channels, and possibly a background notification queue, ugh.&lt;/p&gt;  &lt;p&gt;2. Message passing is explicit about connectivity.&amp;#160; This is a good thing because communication faults should be handled differently from other application-level faults.&lt;/p&gt;  &lt;p&gt;3. Assuming the messaging protocol is non-proprietary then we can open up participation to non-.Net agents.&lt;/p&gt;  &lt;p&gt;4. Multiple subscribers can listen for messages published to a common message bus.&amp;#160; Multiple publishers can publish to the same message bus.&amp;#160; More importantly: they don't need central coordination.&lt;/p&gt;  &lt;p&gt;5. A subscriber's lifetime is decoupled from that of the publisher and vice-versa.&amp;#160; New subscribers and publishers can join the bus at any time which opens up all kinds of possibilities for auditing, reporting, parallel execution, passive monitoring, and maintaining a test grid.&lt;/p&gt;  &lt;p&gt;6. Cross-Process communication becomes completely straightforward.&lt;/p&gt;  &lt;p&gt;7. The API can evolve dramatically in very useful ways.&amp;#160; In particular, testing can become an open-ended activity rather than a single long-running process.&amp;#160; If you like, you could have testing processes running on a grid all day publishing results from their latest exhaustive trials.&lt;/p&gt;  &lt;h4&gt;Which Message Bus?&lt;/h4&gt;  &lt;p&gt;I don't know.&lt;/p&gt;  &lt;h4&gt;Help me choose.&lt;/h4&gt;  &lt;p&gt;Here are a few criteria:&lt;/p&gt;  &lt;p&gt;1. Should run cross-platform, at least under CLR and Mono.&lt;/p&gt;  &lt;p&gt;2. Should not depend on proprietary / non-free infrastructure components.&lt;/p&gt;  &lt;p&gt;3. Should not be tightly coupled to .Net protocols such as object serialization.&lt;/p&gt;  &lt;p&gt;4. Should be possible (and easy) to implement clients in different languages and runtime environments.&lt;/p&gt;  &lt;p&gt;5. Should use well-known and straightforward standard message formats like XML or JSON with as little extra noise in the envelope as possible.&lt;/p&gt;  &lt;p&gt;6. Should not require any up-front installation or configuration.&amp;#160; Each endpoint can be self-managed if desired.&amp;#160; The whole bus might be considered transient, something to be set up and torn down as needed.&amp;#160; In fact, we probably don't need a full-blown bus.&amp;#160; We just need some kind of efficient inter-process asynchronous messaging fabric.&amp;#160; (peer to peer?)&lt;/p&gt;  &lt;p&gt;7. Should support auto-discovery of services among a group of related processes.&lt;/p&gt;  &lt;p&gt;8. Should be able to inform a client of communication faults but does not required durable messaging.&lt;/p&gt;  &lt;div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:2c204fb9-68d1-4136-afe5-622ee6d44616" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/gallio" rel="tag"&gt;gallio&lt;/a&gt;&lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023944205100803414-1305985146573413889?l=blog.bits-in-motion.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.bits-in-motion.com/feeds/1305985146573413889/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9023944205100803414&amp;postID=1305985146573413889" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/1305985146573413889?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/1305985146573413889?v=2" /><link rel="alternate" type="text/html" href="http://blog.bits-in-motion.com/2009/03/gallio-v31-may-use-message-bus.html" title="Gallio v3.1 may use a message bus." /><author><name>Jeff Brown</name><uri>http://www.blogger.com/profile/09075745057339916352</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03263874364951229913" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">4</thr:total></entry><entry gd:etag="W/&quot;CUUDSHw_fSp7ImA9WxVVE0U.&quot;"><id>tag:blogger.com,1999:blog-9023944205100803414.post-4926540113730954963</id><published>2009-03-06T15:46:00.001-08:00</published><updated>2009-03-06T15:47:59.245-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-06T15:47:59.245-08:00</app:edited><title>Kudos to NCover for Excellent Support</title><content type="html">&lt;p&gt;I want to mention here that Stephen Ward over at &lt;a href="http://www.ncover.com/"&gt;NCover&lt;/a&gt; went above and beyond the call of duty to diagnose a problem I was having with NCover spontaneously aborting on the Gallio build server during a coverage run.&amp;#160; He checked out the code, figured out how it worked, tried running it locally and when that didn't reproduce the problem he logged into the build server and fixed it there.&lt;/p&gt;  &lt;p&gt;It turns out that the problem was even my fault!&amp;#160; A 2-minute timeout during host process termination that I had forgotten about.&amp;#160; Unfortunately we're talking about a massive NCover coverage log here on a severely underpowered build server, so it needs a bit more time to write it out.&lt;/p&gt;  &lt;p&gt;Lessons learned:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The NCover team is really cool.&lt;/li&gt;    &lt;li&gt;If I'm going to abnormally terminate a process after a timeout, I should at least write a message to the log when I do it.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Thanks!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023944205100803414-4926540113730954963?l=blog.bits-in-motion.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.bits-in-motion.com/feeds/4926540113730954963/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9023944205100803414&amp;postID=4926540113730954963" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/4926540113730954963?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/4926540113730954963?v=2" /><link rel="alternate" type="text/html" href="http://blog.bits-in-motion.com/2009/03/kudos-to-ncover-for-excellent-support.html" title="Kudos to NCover for Excellent Support" /><author><name>Jeff Brown</name><uri>http://www.blogger.com/profile/09075745057339916352</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03263874364951229913" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;DEMDQnY9fCp7ImA9WxVXGUQ.&quot;"><id>tag:blogger.com,1999:blog-9023944205100803414.post-1035692625782303808</id><published>2009-02-18T14:24:00.001-08:00</published><updated>2009-02-18T14:34:33.864-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-02-18T14:34:33.864-08:00</app:edited><title>NCover v3 Magic...</title><content type="html">&lt;p&gt;I just upgraded the Gallio NCover integration to support NCover v3.&amp;#160; It all looked okay except that I could not get the integration test to pass!&lt;/p&gt;  &lt;p&gt;No matter what I did, NCover would exclude coverage of any Gallio code at all including my test assembly!&amp;#160; However it would include coverage information about Castle assemblies.&lt;/p&gt;  &lt;p&gt;On a whim, I ran &lt;strong&gt;grep Gallio * &lt;/strong&gt;over the NCover program files folder, and here's what I found in a file called &lt;strong&gt;NCover.Console.exe.config&lt;/strong&gt;:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;     &lt;br /&gt;&amp;lt;configuration&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;configSections&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;section name=&amp;quot;ncover.systemAssemblies&amp;quot; type=&amp;quot;NCover.Framework.SystemAssemblySectionHandler, NCover.Framework&amp;quot;/&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/configSections&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;startup&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/startup&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;ncover.systemAssemblies&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;assembly&amp;gt;msvc[mrp].*&amp;lt;/assembly&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;assembly&amp;gt;mscorcfg&amp;lt;/assembly&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;assembly&amp;gt;mscorlib&amp;lt;/assembly&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;assembly&amp;gt;sysglobl&amp;lt;/assembly&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;assembly&amp;gt;CppCodeProvider&amp;lt;/assembly&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;assembly&amp;gt;Microsoft.*&amp;lt;/assembly&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;assembly&amp;gt;PresentationBuildTasks&amp;lt;/assembly&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;assembly&amp;gt;PresentationCore&amp;lt;/assembly&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;assembly&amp;gt;PresentationFramework.*&amp;lt;/assembly&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;assembly&amp;gt;ReachFramework&amp;lt;/assembly&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;assembly&amp;gt;System.*&amp;lt;/assembly&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;assembly&amp;gt;VSLangProj.*&amp;lt;/assembly&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;assembly&amp;gt;VSWebSite\.Interop&amp;lt;/assembly&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;assembly&amp;gt;VSWebSite\.Interop90&amp;lt;/assembly&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;assembly&amp;gt;SMDiagnostics&amp;lt;/assembly&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;assembly&amp;gt;UIAutomationClient&amp;lt;/assembly&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;assembly&amp;gt;UIAutomationClientsideProviders&amp;lt;/assembly&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;assembly&amp;gt;UIAutomationProvider&amp;lt;/assembly&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;assembly&amp;gt;UIAutomationTypes&amp;lt;/assembly&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;assembly&amp;gt;WindowsBase&amp;lt;/assembly&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;assembly&amp;gt;WindowsFormsIntegration&amp;lt;/assembly&amp;gt; &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;assembly&amp;gt;nunit\..*&amp;lt;/assembly&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;assembly&amp;gt;nunit-.*&amp;lt;/assembly&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;assembly&amp;gt;xunit.*&amp;lt;/assembly&amp;gt;      &lt;br /&gt;&lt;strong&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;assembly&amp;gt;MbUnit.*&amp;lt;/assembly&amp;gt;       &lt;br /&gt;&lt;/strong&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;assembly&amp;gt;MSTest.*&amp;lt;/assembly&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;assembly&amp;gt;log4net&amp;lt;/assembly&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;assembly&amp;gt;QuickGraph.*&amp;lt;/assembly&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;assembly&amp;gt;WiseOwl.Obfuscation&amp;lt;/assembly&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;assembly&amp;gt;Rhino.Mocks&amp;lt;/assembly&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;strong&gt; &amp;lt;assembly&amp;gt;Gallio.*&amp;lt;/assembly&amp;gt;       &lt;br /&gt;&lt;/strong&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;assembly&amp;gt;mbunit.console&amp;lt;/assembly&amp;gt;      &lt;br /&gt;&lt;strong&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;assembly&amp;gt;Gallio.Echo&amp;lt;/assembly&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;assembly&amp;gt;Gallio.Icarus&amp;lt;/assembly&amp;gt;        &lt;br /&gt;&lt;/strong&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/ncover.systemAssemblies&amp;gt;      &lt;br /&gt;&amp;lt;/configuration&amp;gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;em&gt;Aside: This list seems to contain some redundant or incorrect entries.&amp;#160; For example, the old MbUnit v2 console application is called MbUnit.Cons, not MbUnit.Console.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;Whoo!&lt;/p&gt;  &lt;p&gt;Ok, so out of the box NCover will exclude from coverage analysis anything related to several popular testing packages.&amp;#160; In principle, it's not a bad idea since excluding these assemblies is a common support request from users... but in practice this worries me because it can become overbroad and lead to user confusion (as it did for me).&amp;#160; Gallio in particular is in a good position to take care of specifying its own necessary exclusions automatically (while taking plug-ins into account also).&lt;/p&gt;  &lt;p&gt;To work around this issue, it suffices to edit the file.&amp;#160; The list of system assemblies seems to override anything specified in the list of assembly inclusion arguments.&lt;/p&gt;  &lt;p&gt;I will send the author a proposal to add a new switch to disable some of this behavior...&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023944205100803414-1035692625782303808?l=blog.bits-in-motion.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.bits-in-motion.com/feeds/1035692625782303808/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9023944205100803414&amp;postID=1035692625782303808" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/1035692625782303808?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/1035692625782303808?v=2" /><link rel="alternate" type="text/html" href="http://blog.bits-in-motion.com/2009/02/ncover-v3-magic.html" title="NCover v3 Magic..." /><author><name>Jeff Brown</name><uri>http://www.blogger.com/profile/09075745057339916352</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03263874364951229913" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">4</thr:total></entry><entry gd:etag="W/&quot;DUYNR3w_eip7ImA9WxVXF04.&quot;"><id>tag:blogger.com,1999:blog-9023944205100803414.post-3111653000909114518</id><published>2009-02-15T14:32:00.001-08:00</published><updated>2009-02-15T14:33:16.242-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-02-15T14:33:16.242-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="values" /><title>A Duty to Learn</title><content type="html">&lt;p&gt;I was called to write this post after reading Jeff Atwood's &lt;a href="http://www.codinghorror.com/blog/archives/001225.html"&gt;The Ferengi Programmer&lt;/a&gt; and Rob Connery's apt response &lt;a href="http://codebetter.com/blogs/rob.conery/archive/2009/02/11/patterns-purists-and-sinkholes.aspx"&gt;Patterns, Purists and Sinkholes&lt;/a&gt;.&amp;#160; Their central argument is about whether the software development process can be codified.&lt;/p&gt;  &lt;p&gt;Could there ever be a sufficiently precise set of rules to successfully build software by the book?&amp;#160; Possibly.&lt;/p&gt;  &lt;p&gt;Would it stifle the art?&amp;#160; Certainly.&lt;/p&gt;  &lt;p&gt;Are &amp;quot;principles and practices&amp;quot; useful?&amp;#160; Yes!&amp;#160; They provide scaffolding for reasoned analysis and discussion.&lt;/p&gt;  &lt;p&gt;Are they universally good and complete?&amp;#160; No.&amp;#160; They are changeable embodiments of ideals.&lt;/p&gt;  &lt;p&gt;Is it still worth learning and sharing principles and practices written down by others?&amp;#160; Absolutely!&lt;/p&gt;  &lt;h4&gt;A Duty to Teach&lt;/h4&gt;  &lt;p&gt;What is a &lt;strong&gt;&amp;quot;best practice&amp;quot;&lt;/strong&gt;&lt;em&gt;?&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;First, let's start with the name.&amp;#160; &amp;quot;Best&amp;quot; suggests that in some objective sense, these practices alone were judged to be absolutely superior to all others.&amp;#160; Not merely are they good, they are superlative!&lt;/p&gt;  &lt;p&gt;Second, the term is often applied to particular mechanisms used to achieve a particular policy.&amp;#160; For example, &amp;quot;Thou shalt write application log files using protocol XYZ.&amp;quot;&amp;#160; There's more to learn about best practice than particular interfaces.&lt;/p&gt;  &lt;p&gt;Let's call these things what they are instead: &lt;strong&gt;&amp;quot;standard practice&amp;quot;&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;Standard practice is a compromise by an organization to achieve a mutually agreeable implementation of an ideal principle.&amp;#160; It is a tool to promote uniformity and consensus but it is no substitute for education.&amp;#160; Standard practice should never be used to enforce unquestioned conformity and to stifle further debate.&lt;/p&gt;  &lt;p&gt;Merely stating a standard practice does not free the speaker from the &lt;strong&gt;duty to teach&lt;/strong&gt;!&lt;/p&gt;  &lt;h4&gt;An Unquestioning Mind Remains Unhired&lt;/h4&gt;  &lt;p&gt;Every professional software practitioner has a &lt;strong&gt;duty to learn&lt;/strong&gt;.&amp;#160; Those who shirk this duty eventually land in the pool of the millions of unemployed programmers who bang at the door of the software industry every day.&amp;#160; They boast about their services yet fail time and again to invest their &lt;strong&gt;hearts and minds&lt;/strong&gt; as barter for the money and recognition they feel is their due.&lt;/p&gt;  &lt;p&gt;Let me share a secret...&lt;/p&gt;  &lt;p&gt;If you say any of the following statements during an interview, I will probably not hire you.&amp;#160; I don't care what your level of ability or experience is.&amp;#160; These statements tell me you are on the path of eventual stagnation:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&amp;quot;I don't know anything about &lt;em&gt;X &lt;/em&gt;but it's too complicated and I believe everything should be kept as simple as possible.&amp;quot;      &lt;br /&gt;      &lt;br /&gt;Translation: I am unwilling to learn on my own and I am unwilling to admit it might help my career.      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;em&gt;&amp;quot;X &lt;/em&gt;is obviously better than &lt;em&gt;Y&lt;/em&gt;.&amp;quot;&amp;#160; (I can't explain it but it is.)      &lt;br /&gt;      &lt;br /&gt;Translation: I am unwilling to learn on my own and I cannot tell the difference.      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&amp;quot;In all of the &lt;em&gt;X&lt;/em&gt; years of my experience I have never had to do &lt;em&gt;Y.&amp;quot;&lt;/em&gt;&amp;#160; (So you must be wrong about thinking it might be important.)&lt;em&gt;       &lt;br /&gt;        &lt;br /&gt;&lt;/em&gt;Translation: I am unwilling to learn on my own and I will drag everyone who disagrees with my dogma into the pit of irrelevance.      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&amp;quot;I did &lt;em&gt;X&lt;/em&gt; at all of my other jobs.&amp;#160; &lt;em&gt;X&lt;/em&gt; is the solution to all of your problems.&amp;quot;&amp;#160; (It slices, it dices.)      &lt;br /&gt;      &lt;br /&gt;Translation: I am unwilling to learn on my own and I will not let go of my sledgehammer.      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&amp;quot;All of my work conforms to industry best practices &lt;em&gt;X, Y and Z&lt;/em&gt;.&amp;quot;&amp;#160; (But I can't explain them.)      &lt;br /&gt;      &lt;br /&gt;Translation: I am unwilling to learn on my own and I like to impress people with buzzwords.      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&amp;quot;I really want to work here but in two years do you think I can graduate to department &lt;em&gt;X&lt;/em&gt;?&amp;quot;&amp;#160; (&lt;em&gt;X&lt;/em&gt; is so much cooler than &lt;em&gt;Y&lt;/em&gt; even though I don't know &lt;em&gt;X or Y&lt;/em&gt; very well, like development vs. testing.)      &lt;br /&gt;      &lt;br /&gt;Translation: I am unwilling to learn on my own and I think what you do is beneath my status.&lt;/li&gt; &lt;/ul&gt;  &lt;ul&gt;   &lt;li&gt;&amp;quot;I learned everything on my own.&amp;#160; It's so easy and obvious.&amp;#160; Schools and books are for losers.&amp;quot;     &lt;br /&gt;      &lt;br /&gt;Translation: I am unwilling to accept that others might still have things to teach me and I am stunting my own growth.      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&amp;quot;I can learn any &lt;em&gt;X&lt;/em&gt;.&amp;#160; They're all the same.&amp;quot;&amp;#160; (Programming languages)      &lt;br /&gt;      &lt;br /&gt;Translation: I am unwilling to accept that others might still have things to teach me and that there there are many ways of doing things; some vastly different from what I know.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I would rather endorse and train a candidate fresh out of school full of passion and vitality than a highly experienced person in denial of a closed mind.&lt;/p&gt;  &lt;h4&gt;A Broken Heart&lt;/h4&gt;  &lt;p&gt;A friend of mine recently told me this: &amp;quot;I am not sure whether I want to stay in software development much longer.&amp;#160; I always have to learn new things each year and I feel I will never catch up.&amp;#160; I think I should go into management or business intelligence since those fields stay the same all of the time and never change.&amp;quot;&lt;/p&gt;  &lt;p&gt;It broke my heart.&lt;/p&gt;  &lt;p&gt;First, that he was planning to embark on a path of stagnation.&amp;#160;&amp;#160; Second, that he unfairly judged those in other disciplines as being somehow less sophisticated.&amp;#160; Third, that he seemed to be making unhealthy decisions by default.&lt;/p&gt;  &lt;p&gt;We talked for a long while after that.&lt;/p&gt;  &lt;p&gt;Ultimately, I don't mind if he leaves software development (although I will be sad).&amp;#160; I just hope he goes where his passion leads him.&amp;#160; I will support him either way.&amp;#160; Still, for me it was a worthwhile reminder that not everyone values their careers the same way...&lt;/p&gt;  &lt;p&gt;Do want you want, but do it with all your heart and mind engaged.&amp;#160; Learn and grow and change...&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023944205100803414-3111653000909114518?l=blog.bits-in-motion.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.bits-in-motion.com/feeds/3111653000909114518/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9023944205100803414&amp;postID=3111653000909114518" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/3111653000909114518?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/3111653000909114518?v=2" /><link rel="alternate" type="text/html" href="http://blog.bits-in-motion.com/2009/02/duty-to-learn.html" title="A Duty to Learn" /><author><name>Jeff Brown</name><uri>http://www.blogger.com/profile/09075745057339916352</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03263874364951229913" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total></entry><entry gd:etag="W/&quot;D0cCRns_eSp7ImA9WxVQGUs.&quot;"><id>tag:blogger.com,1999:blog-9023944205100803414.post-6930629740817610903</id><published>2009-02-06T16:04:00.001-08:00</published><updated>2009-02-06T16:04:27.541-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-02-06T16:04:27.541-08:00</app:edited><title>Edge Cases</title><content type="html">&lt;p&gt;It's nice to pretend edge cases don't exist or aren't important, but they do and they are...&amp;#160; Try as you might, someone will stumble upon it and the world will collapse under the weight of invalidated assumptions.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Here is one that I've been dealing with lately:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;public class Container&amp;lt;T&amp;gt;     &lt;br /&gt;{      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public class Outer      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; public class Inner : Outer      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }      &lt;br /&gt;} &lt;/p&gt; &lt;/blockquote&gt;  &lt;h4&gt;Quiz&lt;/h4&gt;  &lt;p&gt;1. What does &lt;strong&gt;typeof(Inner).GetGenericArguments().Length &lt;/strong&gt;return?&lt;/p&gt;  &lt;p&gt;2a. What does &lt;strong&gt;typeof(Inner).GetGenericArguments()[0].ToString() &lt;/strong&gt;return?&lt;/p&gt;  &lt;p&gt;2b. How about &lt;strong&gt;typeof(Inner).GetGenericArguments()[0].FullName&lt;/strong&gt;?&lt;/p&gt;  &lt;p&gt;3. What does &lt;strong&gt;typeof(Inner).GetGenericArguments()[0].DeclaringType.ToString() &lt;/strong&gt;return?&lt;/p&gt;  &lt;p&gt;3b. How about &lt;strong&gt;typeof(Inner).GetGenericArguments()[0].DeclaringType.FullName&lt;/strong&gt;?&lt;/p&gt;  &lt;p&gt;4a. What does &lt;strong&gt;typeof(Inner).BaseType.GetGenericArguments()[0].DeclaringType.ToString()&lt;/strong&gt; return?&lt;/p&gt;  &lt;p&gt;4b. How about &lt;strong&gt;typeof(Inner).BaseType.GetGenericArguments()[0].DeclaringType.FullName&lt;/strong&gt;?&lt;/p&gt;  &lt;p&gt;5a. What does &lt;strong&gt;typeof(Inner).BaseType.ToString()&lt;/strong&gt; return?&lt;/p&gt;  &lt;p&gt;5b. How about &lt;strong&gt;typeof(Inner).BaseType.FullName&lt;/strong&gt;?&lt;/p&gt;  &lt;h4&gt;Answers&lt;/h4&gt;  &lt;p&gt;(Select text to reveal.)&lt;/p&gt;  &lt;p&gt;&lt;font color="#ffffff"&gt;1. 1&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#ffffff"&gt;2a. &amp;quot;T&amp;quot;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#ffffff"&gt;2b. null&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#ffffff"&gt;3a. &amp;quot;Container`1+Outer+Inner[T]&amp;quot;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#ffffff"&gt;3b. &amp;quot;Container`1+Outer+Inner&amp;quot;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#ffffff"&gt;4a. &amp;quot;Container`1+Outer+Inner[T]&amp;quot;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#ffffff"&gt;4b. &amp;quot;Container`1+Outer+Inner&amp;quot;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#ffffff"&gt;5a. &amp;quot;Container`1+Outer[T]&amp;quot;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#ffffff"&gt;5b. null&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#ffffff"&gt;Surprise!&lt;/font&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023944205100803414-6930629740817610903?l=blog.bits-in-motion.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.bits-in-motion.com/feeds/6930629740817610903/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9023944205100803414&amp;postID=6930629740817610903" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/6930629740817610903?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/6930629740817610903?v=2" /><link rel="alternate" type="text/html" href="http://blog.bits-in-motion.com/2009/02/edge-cases.html" title="Edge Cases" /><author><name>Jeff Brown</name><uri>http://www.blogger.com/profile/09075745057339916352</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03263874364951229913" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;CEIASX8yeCp7ImA9WxVQE0o.&quot;"><id>tag:blogger.com,1999:blog-9023944205100803414.post-128041422490435393</id><published>2009-01-30T19:29:00.001-08:00</published><updated>2009-01-30T19:29:08.190-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-01-30T19:29:08.190-08:00</app:edited><title>Gallio Update</title><content type="html">&lt;p&gt;Work on Gallio v3.0.6 is progressing along after a brief holiday hiatus.&amp;#160; Yes, I actually put the computers away for a couple of weeks to spend some quality time with friends, family and books (not to mention on other projects at work).&lt;/p&gt;  &lt;p&gt;The plan is to ship v3.0.6 within the next couple of weeks.&lt;/p&gt;  &lt;p&gt;Current primary objectives are:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Performance: improve start-up time, ReSharper integration, Visual Studio integration.&lt;/li&gt;    &lt;li&gt;Extensibility: new plug-in model.&lt;/li&gt;    &lt;li&gt;New features: XmlData, parallel tests, new contract verifiers, mixins (may be deferred).&lt;/li&gt;    &lt;li&gt;UI affordances: simplify debugging, improve documentation.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;And here's roughly where we're at:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Added [Parallelizable] attribute to run tests in parallel.&lt;/li&gt;    &lt;li&gt;Added [XmlData] attribute to specify Xml data sources.&lt;/li&gt;    &lt;li&gt;Global test execution timeout setting in Echo, MSBuild, NAnt and PowerShell.&lt;/li&gt;    &lt;li&gt;Significant improvements to Contract Verifier syntax and functionality.&lt;/li&gt;    &lt;li&gt;New developer content in the book.&lt;/li&gt;    &lt;li&gt;Upgraded to Pex v0.9 Academic License.&lt;/li&gt;    &lt;li&gt;Preliminary support for ReSharper 4.5 EAP.&lt;/li&gt;    &lt;li&gt;Links to test source location from report.&lt;/li&gt;    &lt;li&gt;Icarus can start tests with the debugger.&lt;/li&gt;    &lt;li&gt;Icarus contains link to online documentation.&lt;/li&gt;    &lt;li&gt;Started work to support MSTest 2005.&lt;/li&gt;    &lt;li&gt;Added a report XSD file to assist contributors who wish to build report processors.&lt;/li&gt;    &lt;li&gt;Started optimizing the reflection wrappers.&amp;#160; Should improve ReSharper plugin performance slightly.&lt;/li&gt;    &lt;li&gt;Added generic versions of Assert.Is[Not]AssignableFrom and Assert.Is[Not]InstanceOfType.&lt;/li&gt;    &lt;li&gt;Started working on new plugin model.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Bug fixes:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Fixed MbUnit v2 adapter test outcome reporting and tear down glitches.&lt;/li&gt;    &lt;li&gt;Fixed VB.Net project templates.&lt;/li&gt;    &lt;li&gt;Fixed missing sample files.&lt;/li&gt;    &lt;li&gt;Fixed XML encoding issues with actual / expected outcomes that caused whitespace differences to be hidden.&lt;/li&gt;    &lt;li&gt;Fixed use of [Factory] data source with open generic types.&lt;/li&gt;    &lt;li&gt;Fixed missing CCNet add-in documentation in the installer.&lt;/li&gt;    &lt;li&gt;Fixed regression downloading report attachments in CCNet.&lt;/li&gt;    &lt;li&gt;Fixed issue with Icarus go to source command invoked on non-UI thread.&lt;/li&gt;    &lt;li&gt;Fixed inconsistent failure message for Assert.EndsWith.&lt;/li&gt;    &lt;li&gt;No more spurious COMExceptions during startup when reading symbols from PDB files.&lt;/li&gt; &lt;/ul&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023944205100803414-128041422490435393?l=blog.bits-in-motion.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.bits-in-motion.com/feeds/128041422490435393/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9023944205100803414&amp;postID=128041422490435393" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/128041422490435393?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/128041422490435393?v=2" /><link rel="alternate" type="text/html" href="http://blog.bits-in-motion.com/2009/01/gallio-update.html" title="Gallio Update" /><author><name>Jeff Brown</name><uri>http://www.blogger.com/profile/09075745057339916352</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03263874364951229913" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total></entry><entry gd:etag="W/&quot;DkECQXgzfCp7ImA9WxRUEE0.&quot;"><id>tag:blogger.com,1999:blog-9023944205100803414.post-2544607392421254735</id><published>2008-11-18T02:37:00.001-08:00</published><updated>2008-11-18T02:37:40.684-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-11-18T02:37:40.684-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="gallio" /><category scheme="http://www.blogger.com/atom/ns#" term="release notes" /><category scheme="http://www.blogger.com/atom/ns#" term="mbunit" /><title>Announcing Gallio and MbUnit v3.0.5</title><content type="html">&lt;p&gt;Today we are releasing Gallio and MbUnit v3.0.5.&amp;#160; This is primarily a bug fix release but we are introducing a few new features.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Assert.AreApproximatelyEqual, test factories, structural object formatting, AutoCAD integration, x86 tests on x64, Visual Studio CTP 2010.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;Download here: &lt;a href="http://www.gallio.org/Downloads.aspx"&gt;http://www.gallio.org/Downloads.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Documentation here: &lt;a href="http://www.gallio.org/Docs.aspx"&gt;http://www.gallio.org/Docs.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Release notes: &lt;a href="http://blog.bits-in-motion.com/search/label/release%20notes"&gt;All release notes from all versions&lt;/a&gt;.&lt;/p&gt;  &lt;h3&gt;MbUnit&lt;/h3&gt;  &lt;h5&gt;Assert.AreApproximatelyEqual&lt;/h5&gt;  &lt;p&gt;We have added &lt;em&gt;Assert.AreApproximatelyEqual&lt;/em&gt; to express an assertion about equality within some delta (aka. tolerance).&amp;#160; Likewise there is &lt;em&gt;Assert.AreNotApproximatelyEqual&lt;/em&gt;.&lt;/p&gt;  &lt;p&gt;Examples:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Assert.AreApproximatelyEqual(/*expectedValue*/ 2.0, /*actualValue*/ 2.2, /*delta*/ 0.3);     &lt;br /&gt;-&amp;gt; Success: 2.2 is in the range 2.0 +/- 0.3.&lt;/p&gt;    &lt;p&gt;Assert.AreApproximatelyEqual(/*expectedValue*/ 2.0, /*actualValue*/ 2.2, /*delta*/ 0.1);     &lt;br /&gt;-&amp;gt; Failure: 2.2 is not in the range 2.0 +/- 0.1.&lt;/p&gt;    &lt;p&gt;Assert.Are&lt;strong&gt;Not&lt;/strong&gt;ApproximatelyEqual(/*expectedValue*/ 2.0, /*actualValue*/ 2.2, /*delta*/ 0.1);      &lt;br /&gt;-&amp;gt; Success: 2.2 is not in the range 2.0 +/- 0.1.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The implementation supports any comparable type that defines a subtraction operator, and for which the result of subtraction is also comparable.&lt;/p&gt;  &lt;p&gt;Examples:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Assert.AreApproximatelyEqual(-5, 2, 10);     &lt;br /&gt;-&amp;gt; Success: 2 is in the range -5 +/- 10.&lt;/p&gt;    &lt;p&gt;Assert.AreApproximatelyEqual(new DateTime(2008, 11, 17), new DateTime(2008, 11, 18), TimeSpan.FromDays(2));     &lt;br /&gt;-&amp;gt; Success: 2008/11/18 is in the range 2008/11/17 +/- 1 day.&lt;/p&gt; &lt;/blockquote&gt;  &lt;h4&gt;Static and Dynamic Test Factories (aka. Test Suites)&lt;/h4&gt;  &lt;p&gt;Some people were wondering where the MbUnit v2 [TestSuite] mechanism went.&amp;#160; Now it's back with a few interesting twists.&lt;/p&gt;  &lt;p&gt;A &lt;strong&gt;test factory&lt;/strong&gt; in MbUnit v3 is a method that generates a &lt;strong&gt;test suite &lt;/strong&gt;programmatically.&amp;#160; They are typically used when the structure of a test is derived from custom metadata.&amp;#160; For example, a test factory might produce a test suite generated from some information stored in the database.&lt;/p&gt;  &lt;p&gt;A test suite produced by a test factory differs from a standard &lt;strong&gt;data-driven test&lt;/strong&gt; (such as a Row-test) in that the tester has more control over the generated structure of the test suite.&amp;#160; Instead of plugging in values to a parameterized test, whole new tests can be created arbitrarily.&lt;/p&gt;  &lt;p&gt;There are two kinds of test factories.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;A &lt;strong&gt;static test factory &lt;/strong&gt;adds new tests to the static test tree.&amp;#160; This makes the generated test suite part of the static test model that UI-based test runners such as Icarus use to present tests to the user.      &lt;br /&gt;      &lt;br /&gt;&lt;em&gt;Pros: &lt;/em&gt;The structure of the test suite is determined before tests actually run.      &lt;br /&gt;      &lt;br /&gt;&lt;em&gt;Cons: &lt;/em&gt;The structure of the test suite is fixed at test exploration time.&amp;#160; Moreover, any data that was needed to produce the tests will be loaded all at once up front regardless of whether the test suite will actually be executed.&amp;#160; Also, for this mechanism to work at all, the code that defines the factory must be &lt;strong&gt;executable&lt;/strong&gt; at test exploration time.&amp;#160; This is not the case in ReSharper or Visual Studio Test Tools so static test suites will not appear there, alas.&amp;#160; (At least not as things are written today...)      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;A &lt;strong&gt;dynamic test factory &lt;/strong&gt;adds new tests to the dynamic test tree, aka. the test step tree.&amp;#160; The tests are not included in the static test model which makes it impossible for the user to pick a subset of the dynamic tests to run (basically they are all-or-nothing).      &lt;br /&gt;      &lt;br /&gt;&lt;em&gt;Pros: &lt;/em&gt;The structure of the test suite is determined when the fixture that contains it runs so it can vary based on input data determined at runtime.&amp;#160;&amp;#160; The test factory can be parameterized so it can produce multiple test suites with different input data.&amp;#160; Likewise, a dynamic test factory can emit an unbounded number of tests.&amp;#160; It can keep on producing tests to run for as long as it likes.      &lt;br /&gt;      &lt;br /&gt;&lt;em&gt;Cons:&lt;/em&gt; The dynamic tests are not visible to the user until test execution time.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;It might help to think of a &lt;strong&gt;static test factory &lt;/strong&gt;as working something like a &lt;strong&gt;[TestFixture]&lt;/strong&gt; or &lt;strong&gt;[Test] &lt;/strong&gt;where the test suite is constructed ahead of time using an algorithm of your choice.&amp;#160; On the other hand, a &lt;strong&gt;dynamic test factory &lt;/strong&gt;is more like &lt;strong&gt;TestStep.Run&lt;/strong&gt; which is used to create dynamic test steps within a running test or like parameterized tests which pull contents from a data source at runtime.&lt;/p&gt;  &lt;p&gt;Clear as mud huh?&amp;#160; How about some examples.&lt;/p&gt;  &lt;h6&gt;Static Test Factory Example&lt;/h6&gt;  &lt;p&gt;In this example, we create a few silly tests statically in the &lt;strong&gt;CreateTests&lt;/strong&gt; static method.&amp;#160; Notice that it returns an enumeration of &lt;strong&gt;Test&lt;/strong&gt; objects.&amp;#160; It is also &lt;strong&gt;static&lt;/strong&gt; because no instance of the fixture exists at the time this method is called.&amp;#160; It follows that we cannot define a static test factory as a member of a generic test fixture because we won't know what values are intended to be plugged into the fixture's type parameters.&lt;/p&gt;  &lt;p&gt;There are currently 3 kinds of built-in &lt;strong&gt;Test&lt;/strong&gt; subclasses (you can make your own too):&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;A &lt;strong&gt;TestCase&lt;/strong&gt; is a kind of &lt;strong&gt;Test&lt;/strong&gt; that contains executable code to run.&amp;#160; It can have a name, description and other custom metadata.&lt;/li&gt;    &lt;li&gt;A &lt;strong&gt;TestSuite&lt;/strong&gt; is another kind of &lt;strong&gt;Test&lt;/strong&gt; that composes a list of other &lt;strong&gt;Tests&lt;/strong&gt; (including other suites) to run.&amp;#160; It can also have a name, description, and other custom metadata.&amp;#160; In addition to its children, it can also include &lt;strong&gt;SetUp&lt;/strong&gt;, &lt;strong&gt;TearDown&lt;/strong&gt;, &lt;strong&gt;SuiteSetUp&lt;/strong&gt;, and &lt;strong&gt;SuiteTearDown&lt;/strong&gt; functions.&lt;/li&gt;    &lt;li&gt;A &lt;strong&gt;TestFixtureReference &lt;/strong&gt;is yet another kind of &lt;strong&gt;Test&lt;/strong&gt;.&amp;#160; We do not show it here but basically it allows you to create test suites that reference .&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_X_hvY6E0egY/SSKa0Y3XrBI/AAAAAAAAAPo/nKgHPHO_I_I/s1600-h/image%5B11%5D.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="575" alt="image" src="http://lh3.ggpht.com/_X_hvY6E0egY/SSKa1bAP1TI/AAAAAAAAAPs/jU_bXmVsO58/image_thumb%5B5%5D.png?imgmax=800" width="639" border="0" /&gt;&lt;/a&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;When we run the test fixture, it will include a test called &amp;quot;Sample Test&amp;quot; as well as a suite called &amp;quot;Sample Suite&amp;quot; with two silly test cases within.&lt;/p&gt;  &lt;h6&gt;Dynamic Test Factory Example&lt;/h6&gt;  &lt;p&gt;A dynamic test factory is quite similar to a static test factory.&amp;#160; It just runs at runtime instead.&lt;/p&gt;  &lt;p&gt;The first thing you will notice is that this dynamic test factory is not declared static.&amp;#160; It can be if you like, but that's optional.&amp;#160; The second thing is that this test factory can actually be parameterized!&lt;/p&gt;  &lt;p&gt;Here we create 3 groups of dynamically generated test cases using different input data each time.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_X_hvY6E0egY/SSKa2COujfI/AAAAAAAAAPw/LFDfZxH-sjI/s1600-h/image%5B19%5D.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="197" alt="image" src="http://lh3.ggpht.com/_X_hvY6E0egY/SSKa23g9duI/AAAAAAAAAP0/4WcB02dodA4/image_thumb%5B9%5D.png?imgmax=800" width="392" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;When we run the test fixture, it will produce 1 test case when n = 1, 4 test cases when n = 2 and 9 test cases when n = 3.&lt;/p&gt;  &lt;p&gt;Of course this example is silly.&amp;#160; I suppose next time I could write up something like a miniature file-based DSL integrated using test factories.&lt;/p&gt;  &lt;h4&gt;Structural Object Formatting&lt;/h4&gt;  &lt;p&gt;How often has this happened to you?&lt;/p&gt;  &lt;p&gt;So you write this test...&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_X_hvY6E0egY/SSKa3DXnoEI/AAAAAAAAAP4/aZUNxZXOWGM/s1600-h/image%5B31%5D.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="135" alt="image" src="http://lh3.ggpht.com/_X_hvY6E0egY/SSKa35M1P_I/AAAAAAAAAP8/KiXDRzF9B1E/image_thumb%5B15%5D.png?imgmax=800" width="359" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;And then it fails...&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_X_hvY6E0egY/SSKa4o5EOKI/AAAAAAAAAQA/52l1xKG0QcA/s1600-h/image%5B27%5D.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="236" alt="image" src="http://lh5.ggpht.com/_X_hvY6E0egY/SSKa5WpJXmI/AAAAAAAAAQE/-R_phE7jry4/image_thumb%5B13%5D.png?imgmax=800" width="555" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Ok, now actually it's pretty cool that it tells you that both values look the same when printed but are actually distinct instances, but that's not really good enough.&lt;/p&gt;  &lt;p&gt;The problem is that the &lt;strong&gt;Data&lt;/strong&gt; object does not provide a custom &lt;strong&gt;ToString() &lt;/strong&gt;override.&amp;#160; We could add one to that class, but maybe we can't or we don't want to.&lt;/p&gt;  &lt;p&gt;Gallio provides a pluggable object formatter that MbUnit and other frameworks can use.&amp;#160; It provides built-in support for primitives, arrays, lists, and many other common types.&lt;/p&gt;  &lt;p&gt;Now we also provide a built-in structural formatter for objects.&amp;#160; In the absence of a better formatting rule or a custom &lt;strong&gt;ToString()&lt;/strong&gt; override, it uses reflection over the public properties and fields of an object to try to display its component parts.&amp;#160; So we don't need to define useless &lt;strong&gt;ToString()&lt;/strong&gt; methods for test diagnostics anymore.&lt;/p&gt;  &lt;p&gt;Here is the result... can you tell what the problem is?&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_X_hvY6E0egY/SSKa6If9O-I/AAAAAAAAAQI/HSc3ef3rYEg/s1600-h/image%5B38%5D.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="217" alt="image" src="http://lh4.ggpht.com/_X_hvY6E0egY/SSKa7JWB6_I/AAAAAAAAAQM/En0JE77i4xM/image_thumb%5B18%5D.png?imgmax=800" width="556" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;h3&gt;AutoCAD Integration&lt;/h3&gt;  &lt;p&gt;Mike Sandberg has added support for testing AutoCAD plugins.&lt;/p&gt;  &lt;p&gt;It turns out that AutoCAD has a managed extensibility model so you can create your own plugins using .Net and the ObjectARX toolkit.&amp;#160; Unfortunately it is somewhat difficult to write unit tests for plugins becuase they must run within the main UI thread of AutoCAD.&lt;/p&gt;  &lt;p&gt;The AutoCAD integration for Gallio works by loading a shim into the AutoCAD application from which it can launch tests.&amp;#160; To enable this integration, specify the &amp;quot;AutoCAD&amp;quot; runner type to the Echo, Icarus, MSBuild, NAnt or PowerShell runners.&lt;/p&gt;  &lt;p&gt;For example:&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; Gallio.Echo.exe MyTestAssembly.dll /r:AutoCAD [other options...]&lt;/p&gt;  &lt;p&gt;AutoCAD integration is not yet available from within the IDE.&amp;#160; We will be working to improve this use case in the future.&lt;/p&gt;  &lt;h3&gt;Running x86 tests as 32-bit on x64&lt;/h3&gt;  &lt;p&gt;We now support running x86 tests within a 32-bit process on x64.&amp;#160; This is necessary when the subject under test is linked to native 32-bit components since the 32-bit and 64-bit Application Binary Interfaces are incompatible.&lt;/p&gt;  &lt;p&gt;To ensure that tests run in an x86 process, simply compile them for the x86 platform.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_X_hvY6E0egY/SSKa77nU6oI/AAAAAAAAAQQ/pAii5tBvuGE/s1600-h/image%5B42%5D.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="222" alt="image" src="http://lh4.ggpht.com/_X_hvY6E0egY/SSKa8mA_OlI/AAAAAAAAAQU/akgFi0c3alc/image_thumb%5B20%5D.png?imgmax=800" width="644" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The only caveat is that this support might not work in embedded test runners such as TestDriven.Net, ReSharper or Visual Studio Test Tools because Gallio does not control process creation there.&lt;/p&gt;  &lt;p&gt;However, it will work from the Icarus GUI, the build tasks and other tools as long as the tests are configured to run out of process (which is the default).&lt;/p&gt;  &lt;h3&gt;Visual Studio 2010 CTP Support&lt;/h3&gt;  &lt;p&gt;As &lt;a href="http://blog.bits-in-motion.com/2008/11/gallio-and-mbunit-v3-for-visual-studio.html"&gt;mentioned previously&lt;/a&gt;, we are also shipping a preview of Gallio and MbUnit with support for .Net Framework 4.0 and Visual Studio 2010 CTP.&lt;/p&gt;  &lt;p&gt;This is currently distributed as a separate download.&amp;#160; It has only been lightly tested so please provide feedback.&lt;/p&gt;  &lt;h3&gt;External Tools Compatibility&lt;/h3&gt;  &lt;p&gt;We've updated integration with a variety of external tools.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;CCNet v1.0.4 &lt;/li&gt;    &lt;li&gt;CSUnit v2.0.5 &lt;/li&gt;    &lt;li&gt;NUnit v2.4.8 &lt;/li&gt;    &lt;li&gt;Pex v0.8 &lt;/li&gt;    &lt;li&gt;ReSharper v3.1, v4.0, v4.1 &lt;/li&gt;    &lt;li&gt;TeamCity v4.0 EAP &lt;/li&gt;    &lt;li&gt;xUnit.Net v1.0.3 &lt;/li&gt;    &lt;li&gt;Visual Studio 2005, 2008, &lt;strong&gt;2010&lt;/strong&gt; &lt;em&gt;(separate installer req'd for 2010) &lt;/em&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;Other Improvements and Bug Fixes&lt;/h3&gt;  &lt;ul&gt;   &lt;li&gt;Improved the robustness of ReSharper, TestDriven.Net and Visual Studio Test Tools integration by loading Gallio in its own isolated AppDomain to prevent test assemblies from interfering with Gallio's runtime. &lt;/li&gt;    &lt;li&gt;Added a &amp;quot;resident&amp;quot; test runner for TestDriven.Net to improve start-up performance.&amp;#160; Use TestDriven.Net v2.17 or newer for this feature. &lt;/li&gt;    &lt;li&gt;Fixed some issues relates to the setting of the application base directory and working directory.&amp;#160; We were inadvertently attempting to create files within the Gallio installation folder at runtime which should not have been happening. &lt;/li&gt;    &lt;li&gt;Cleaned up the documentation of MbUnit assertions and attributes.&amp;#160; Repaired a few minor API inconsistencies along the way. &lt;/li&gt;    &lt;li&gt;Added support for the ReSharper shadow copy and application base directory options. &lt;/li&gt;    &lt;li&gt;Fixed a minor re-entrance issue when the Gallio MSBuild task was launched from within Visual Studio while other Gallio plug-ins for Visual Studio were already active. &lt;/li&gt;    &lt;li&gt;Icarus tweaks for performance and robustness.&lt;/li&gt;    &lt;li&gt;Added code to the isolated process hosting to interpret stack overflow related exit codes and log them.&lt;/li&gt;    &lt;li&gt;Fixed a couple of bugs related logging the result of an asynchronous ThreadTask or ProcessTask spawned by a test using the Tasks abstraction.&lt;/li&gt;    &lt;li&gt;Enhanced [ThreadedRepeat] and [Repeat] attributes to work on fixtures and to ensure that the setup/teardown runs.&lt;/li&gt;    &lt;li&gt;Improved the reporting of xUnit.Net theories.&lt;/li&gt;    &lt;li&gt;Fixed a bug that would sometimes prevent MbUnit v3 generic tests from running.&lt;/li&gt;    &lt;li&gt;Fixed TeamCity reporting to ensure that it includes data-driven tests.&lt;/li&gt;    &lt;li&gt;Fixed a bug in Assert.Throws that caused a StackOverflowException.&lt;/li&gt;    &lt;li&gt;Fixed a bug printing the inner exceptions of MbUnit v2 tests.&lt;/li&gt; &lt;/ul&gt;  &lt;div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:5a9d1ac1-b0eb-44ba-b803-02deb97c41fb" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/gallio" rel="tag"&gt;gallio&lt;/a&gt;,&lt;a href="http://technorati.com/tags/mbunit" rel="tag"&gt;mbunit&lt;/a&gt;&lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023944205100803414-2544607392421254735?l=blog.bits-in-motion.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.bits-in-motion.com/feeds/2544607392421254735/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9023944205100803414&amp;postID=2544607392421254735" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/2544607392421254735?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/2544607392421254735?v=2" /><link rel="alternate" type="text/html" href="http://blog.bits-in-motion.com/2008/11/announcing-gallio-and-mbunit-v305.html" title="Announcing Gallio and MbUnit v3.0.5" /><author><name>Jeff Brown</name><uri>http://www.blogger.com/profile/09075745057339916352</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03263874364951229913" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total></entry><entry gd:etag="W/&quot;CkYMQnk_fyp7ImA9WxRUEE0.&quot;"><id>tag:blogger.com,1999:blog-9023944205100803414.post-7556517721251636499</id><published>2008-11-18T01:23:00.001-08:00</published><updated>2008-11-18T01:23:03.747-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-11-18T01:23:03.747-08:00</app:edited><title>Don't change semantics of well-known types!</title><content type="html">&lt;p&gt;I was writing a little quick and dirty PowerShell script to compare items in Visual Studio 2008 and Visual Studio 2010 project files side-by-side to ensure they are kept in sync.&lt;/p&gt;  &lt;p&gt;Now I will admit that I am a total PowerShell newbie but I was not prepared to deal with this oddity:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;$xml = New-Object System.Xml.XmlDocument     &lt;br /&gt;$xml.Load($path)      &lt;br /&gt;$nsmgr = New-Object System.Xml.XmlNamespaceManager $xml.&lt;strong&gt;psbase&lt;/strong&gt;.NameTable&lt;/p&gt;    &lt;p&gt;&lt;em&gt;(...crash... cannot resolve the constructor for XmlNamespaceManager...)&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;See that little &lt;strong&gt;psbase&lt;/strong&gt;?&amp;#160; Well, because without it, PowerShell will apply some kind of &lt;a href="http://www.eggheadcafe.com/software/aspnet/31145791/xmldocument-selectsinglen.aspx"&gt;built-in adapter semantics&lt;/a&gt;.&amp;#160; Instead of giving back the NameTable, it will actually try to look for an element or attribute called &amp;quot;NameTable&amp;quot; and return that.&amp;#160; Of course, since it doesn't find one, it returns Null instead!&lt;/p&gt;  &lt;p&gt;Now I'm sure PowerShell provides some cool Xml slinging features I don't know about right now.&amp;#160; However it's also a .Net language bound to the .Net framework.&amp;#160; It just diverged pretty dramatically from my mental model of some pretty fundamental .Net framework types.&amp;#160; It takes time to figure that out and recover...&lt;/p&gt;  &lt;p&gt;This isn't like adding a fairly innocuous Ruby-ish &lt;strong&gt;to_s() &lt;/strong&gt;method to types as an alias for &lt;strong&gt;ToString()&lt;/strong&gt;.&amp;#160; This is instead rather intrusive behavior that changes what member selection means for all XmlDocument objects.&amp;#160; I think it would be better if PowerShell introduced its own Xml type instead.&amp;#160; Then it could play with the semantics all it wanted while still preserving the expected behavior of the member selection operator.&lt;/p&gt;  &lt;p&gt;Are there any other landmines I should beware of?&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023944205100803414-7556517721251636499?l=blog.bits-in-motion.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.bits-in-motion.com/feeds/7556517721251636499/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9023944205100803414&amp;postID=7556517721251636499" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/7556517721251636499?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/7556517721251636499?v=2" /><link rel="alternate" type="text/html" href="http://blog.bits-in-motion.com/2008/11/don-change-semantics-of-well-known.html" title="Don&amp;#39;t change semantics of well-known types!" /><author><name>Jeff Brown</name><uri>http://www.blogger.com/profile/09075745057339916352</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03263874364951229913" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total></entry><entry gd:etag="W/&quot;AkEMQ3o5fip7ImA9WxRVGU4.&quot;"><id>tag:blogger.com,1999:blog-9023944205100803414.post-2629655813308260462</id><published>2008-11-17T08:18:00.001-08:00</published><updated>2008-11-17T08:18:02.426-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-11-17T08:18:02.426-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="gallio" /><category scheme="http://www.blogger.com/atom/ns#" term="mbunit" /><title>Speaking at QCon on Thursday</title><content type="html">&lt;p&gt;This week I'll be at &lt;a href="http://qconsf.com/sf2008/conference/" target="_blank"&gt;QCon&lt;/a&gt; speaking about &lt;a href="http://www.gallio.org/" target="_blank"&gt;Gallio&lt;/a&gt; and &lt;a href="http://www.mbunit.com/" target="_blank"&gt;MbUnit&lt;/a&gt; in the ALT.Net track.&lt;/p&gt;  &lt;p&gt;I've been looking forward to this for months!&amp;#160; ;-)&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_X_hvY6E0egY/SSGZNu5UGYI/AAAAAAAAAPg/XLXARZs8ocQ/s1600-h/Speaking_SF_link3.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="80" alt="Blogging_SF" src="http://lh3.ggpht.com/_X_hvY6E0egY/SSGZOFFRz3I/AAAAAAAAAPk/_LM4UohZhIY/Speaking_SF_link3_thumb.jpg?imgmax=800" width="204" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023944205100803414-2629655813308260462?l=blog.bits-in-motion.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.bits-in-motion.com/feeds/2629655813308260462/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9023944205100803414&amp;postID=2629655813308260462" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/2629655813308260462?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/2629655813308260462?v=2" /><link rel="alternate" type="text/html" href="http://blog.bits-in-motion.com/2008/11/speaking-at-qcon-on-thursday.html" title="Speaking at QCon on Thursday" /><author><name>Jeff Brown</name><uri>http://www.blogger.com/profile/09075745057339916352</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03263874364951229913" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;CkYBSXo7fip7ImA9WxRVEE4.&quot;"><id>tag:blogger.com,1999:blog-9023944205100803414.post-4925301318220852586</id><published>2008-11-06T19:55:00.001-08:00</published><updated>2008-11-06T19:55:58.406-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-11-06T19:55:58.406-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="languages" /><title>C# Signatures</title><content type="html">&lt;p&gt;On a &lt;a href="http://social.msdn.microsoft.com/Forums/en-US/vs2010ctpvbcs/thread/1c3560ee-ca67-40c0-9d94-fa4c547a23d3/"&gt;thread&lt;/a&gt; in the Visual Studio 2010 C# and VB Feedback forum, DMeglio posted a question about whether C# 4.0 could be extended to support extended generic constraints.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;I'm just curious, is the feature set for C# 4.0 locked? There is one thing that I feel is a glaring omission, and really hurts C#. The fact that generics do not support operator constraints. This is a huge issue for many of us. Why can't we do:     &lt;br /&gt;      &lt;br /&gt;&lt;strong&gt;public class List&amp;lt;K&amp;gt; where operator+       &lt;br /&gt;&lt;/strong&gt;      &lt;br /&gt;I know this would make my life easier, I guess I'm just wondering if it's definitely been tabled or if it's still a possibility for 4.0&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;So I thought about this for a bit and proposed something similar to the &lt;a href="http://docs.freebsd.org/info/gcc/gcc.info.C++_Signatures.html"&gt;C++ signature abstraction&lt;/a&gt; or a &lt;a href="http://www.haskell.org/tutorial/classes.html"&gt;Haskell Type Class&lt;/a&gt;.&lt;/p&gt;  &lt;h4&gt;Nominative vs. Structural Typing&lt;/h4&gt;  &lt;p&gt;Consider the following types.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;public class Cat     &lt;br /&gt;{      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; void Speak() { Console.WriteLine(&amp;quot;Meow!&amp;quot;); }      &lt;br /&gt;}&lt;/p&gt;    &lt;p&gt;public class Dog     &lt;br /&gt;{      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; void Speak() { Console.WriteLine(&amp;quot;Woof!&amp;quot;); }      &lt;br /&gt;}&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Well, they both have a &lt;strong&gt;Speak()&lt;/strong&gt; method but they do not implement any common interfaces or inherit from a common type (besides &lt;strong&gt;Object&lt;/strong&gt;).&amp;#160; If we want to call &lt;strong&gt;Speak()&lt;/strong&gt; polymorphically on &lt;strong&gt;Cat&lt;/strong&gt; and &lt;strong&gt;Dog&lt;/strong&gt; then we could modify them to implement an &lt;strong&gt;ISpeakable&lt;/strong&gt; interface or &lt;strong&gt;Animal&lt;/strong&gt; abstract base class.&lt;/p&gt;  &lt;p&gt;That's because the CLR uses &lt;a href="http://c2.com/cgi/wiki/Wiki?NominativeAndStructuralTyping"&gt;Nominative Typing&lt;/a&gt;.&amp;#160; Two types are related only in the ways they explicitly declare as part of their definition.&amp;#160; We take this for granted every day, but it's not the only way to do things.&amp;#160; There's also &lt;a href="http://c2.com/cgi/wiki/Wiki?NominativeAndStructuralTyping"&gt;Structural Typing&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;The &lt;strong&gt;Cat&lt;/strong&gt; and &lt;strong&gt;Dog&lt;/strong&gt; classes obviously share structural similarities even if they don't declare them.&amp;#160; They both have &lt;strong&gt;Speak&lt;/strong&gt; methods...&lt;/p&gt;  &lt;h4&gt;C# Signature Proposal&lt;/h4&gt;  &lt;p&gt;Consider the following pseudo-code.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;public signature Numeric&amp;lt;T&amp;gt;     &lt;br /&gt;{      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; static T operator+(T left, T right);      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; static T Zero { get; }      &lt;br /&gt;}&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Any type can be said to satisfy this signature if it has the specified members.&amp;#160; &lt;em&gt;It need not actually declare that is satisfies the signature.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;Assuming this notation, we can define methods like the following:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;public static class Math     &lt;br /&gt;{      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public static T Sum(IEnumerable&amp;lt;T&amp;gt; values)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; where T : Numeric&amp;lt;T&amp;gt; &lt;em&gt;// signifying conformance to a signature, NOT inheritance&lt;/em&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; T total = T.Zero; &lt;em&gt;// the type must have a Zero property, per the signature&lt;/em&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; foreach (T value in values)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; total += value; &lt;em&gt;// valid because the type has an operator+, per the signature       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/em&gt;return total;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }      &lt;br /&gt;}&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Intuitively, the Sum method can be used on any type that supports all of the Numeric&amp;lt;T&amp;gt; operations.&lt;/p&gt;  &lt;p&gt;Ok, but &lt;em&gt;Int32&lt;/em&gt; does not actually have operator+, or Zero defined on it.&amp;#160; So those methods must come from somewhere else!&amp;#160; Some of them could be defined as a default implementation provided by the signature but that's not enough.&lt;/p&gt;  &lt;h4&gt;C# Extension Properties and Static Methods&lt;/h4&gt;  &lt;p&gt;In C# 3.0, we got some fancy compiler syntax for extension methods.&amp;#160; They are defined like this:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;public static class EnumerableExtensions     &lt;br /&gt;{      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public static int Count&amp;lt;T&amp;gt;(&lt;strong&gt;this&lt;/strong&gt; IEnumerable&amp;lt;T&amp;gt; values)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; int count = 0;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; foreach (T value in values)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; count += 1;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return count;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }      &lt;br /&gt;}&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This is all well and good but there is no syntax for &lt;em&gt;extension properties&lt;/em&gt; and &lt;em&gt;extension events&lt;/em&gt;, or for &lt;em&gt;&lt;strong&gt;static&lt;/strong&gt; extension methods&lt;/em&gt;, et. al.&lt;/p&gt;  &lt;p&gt;It turns out that the current syntax for extension methods is very awkward to extend.&amp;#160; Where will you insert&lt;strong&gt; this&lt;/strong&gt; in those extension property and event declarations?&lt;/p&gt;  &lt;h4&gt;C# Signature Extension Proposal&lt;/h4&gt;  &lt;p&gt;Ah!&amp;#160; But what if we allow signatures to extend one another or to extend existing types?&lt;/p&gt;  &lt;p&gt;Then we can define new behaviors on those signatures that will apply to any types that satisfy the signature.&amp;#160; If the signature extends another signature then it incorporates all parts of that other signature.&amp;#160; Likewise if it extends a type then it takes on all aspects of that type.&lt;/p&gt;  &lt;p&gt;But the compiler could also suppose that if a type conforms to a signature that is in scope, then all members of that signature can be used implicitly as if they were members of that type.&amp;#160; &lt;em&gt;Just like extension methods.&lt;/em&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;public signature Int32Extensions : Int32, Numeric&amp;lt;Int32&amp;gt;     &lt;br /&gt;{      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public static Int32 Zero      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; get { return 0; }      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }      &lt;br /&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public static Int32 operator+ (Int32 a, Int32 b)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return a + b;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }      &lt;br /&gt;}&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Voila!&amp;#160; Static extension methods and properties.&lt;/p&gt;  &lt;p&gt;How about non-static extension methods and properties?&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;public signature Int32Extensions : Int32     &lt;br /&gt;{      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; // I'm an extension property of Int32!      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public bool IsZero      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return this == 0;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }      &lt;br /&gt;}&lt;/p&gt; &lt;/blockquote&gt;  &lt;h4&gt;Simplifications&lt;/h4&gt;  &lt;p&gt;If all we want is support for things like extension properties then it's clear that we can simplify the proposal greatly.&amp;#160; Instead of defining something new like a &lt;strong&gt;signature&lt;/strong&gt; we could define something like an &lt;strong&gt;extension class&lt;/strong&gt;.&amp;#160; However I feel that the structural typing ideas are quite useful on their own.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023944205100803414-4925301318220852586?l=blog.bits-in-motion.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.bits-in-motion.com/feeds/4925301318220852586/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9023944205100803414&amp;postID=4925301318220852586" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/4925301318220852586?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/4925301318220852586?v=2" /><link rel="alternate" type="text/html" href="http://blog.bits-in-motion.com/2008/11/c-signatures.html" title="C# Signatures" /><author><name>Jeff Brown</name><uri>http://www.blogger.com/profile/09075745057339916352</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03263874364951229913" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total></entry><entry gd:etag="W/&quot;C0UCQ346fip7ImA9WxRWGU4.&quot;"><id>tag:blogger.com,1999:blog-9023944205100803414.post-2374371622395860243</id><published>2008-11-05T16:27:00.001-08:00</published><updated>2008-11-05T16:27:42.016-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-11-05T16:27:42.016-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="gallio" /><category scheme="http://www.blogger.com/atom/ns#" term="mbunit" /><title>Gallio Store on Zazzle!</title><content type="html">&lt;p&gt;Thanks to Mark Haley, our fantastic graphics designer, we are now offering a selection of &lt;a href="http://www.gallio.org/" target="_blank"&gt;Gallio&lt;/a&gt; branded products on &lt;a href="http://www.zazzle.com/gallio" target="_blank"&gt;Zazzle&lt;/a&gt;.&amp;#160; Expect &lt;a href="http://www.mbunit.com/" target="_blank"&gt;MbUnit&lt;/a&gt; branded products to arrive soon.&lt;/p&gt;  &lt;p&gt;Proceeds from the store will be used to offset our hosting costs.&lt;/p&gt;  &lt;h4&gt;Full Text of the Announcement&lt;/h4&gt;  &lt;p&gt;You can now show your support for Gallio with merchandise bearing the Gallio Logo from a store we have set up on Zazzle. &lt;/p&gt;  &lt;p&gt;At present there is a selection of T-Shirts, Polos, Hooded Sweatshirts, Hats, Mugs and Bumper Stickers available.&amp;#160; This first run has one particular style, but other styles may follow.&amp;#160; We intend to add MbUnit branded items in the future as well, so stay tuned! &lt;/p&gt;  &lt;p&gt;A new menu item has been added to the &lt;a href="http://www.gallio.org/" target="_blank"&gt;gallio.org&lt;/a&gt; website that will direct you to the &lt;a href="http://www.zazzle.com/" target="_blank"&gt;Zazzle&lt;/a&gt; site, or the direct link is here:    &lt;br /&gt;&lt;a href="http://www.zazzle.com/gallio"&gt;http://www.zazzle.com/gallio&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Please note:&amp;#160; most items can be customised extensively on the product page.&amp;#160; For example, shirt colors or even style may be adjusted from the default style shown, so don't be afraid to experiment to get it just how you like it.&lt;/p&gt;  &lt;div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:3713c82d-bed8-4017-b1dd-f7bfbcd83426" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/gallio" rel="tag"&gt;gallio&lt;/a&gt;,&lt;a href="http://technorati.com/tags/mbunit" rel="tag"&gt;mbunit&lt;/a&gt;&lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023944205100803414-2374371622395860243?l=blog.bits-in-motion.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.bits-in-motion.com/feeds/2374371622395860243/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9023944205100803414&amp;postID=2374371622395860243" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/2374371622395860243?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/2374371622395860243?v=2" /><link rel="alternate" type="text/html" href="http://blog.bits-in-motion.com/2008/11/gallio-store-on-zazzle.html" title="Gallio Store on Zazzle!" /><author><name>Jeff Brown</name><uri>http://www.blogger.com/profile/09075745057339916352</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03263874364951229913" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;CkEBR3w_cCp7ImA9WxRVGUk.&quot;"><id>tag:blogger.com,1999:blog-9023944205100803414.post-6018631994452432221</id><published>2008-11-05T04:07:00.001-08:00</published><updated>2008-11-17T08:50:56.248-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-11-17T08:50:56.248-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="gallio" /><category scheme="http://www.blogger.com/atom/ns#" term="release notes" /><category scheme="http://www.blogger.com/atom/ns#" term="mbunit" /><title>Gallio and MbUnit v3 for Visual Studio 2010 CTP</title><content type="html">&lt;p&gt;I suppose by now you have all downloaded the &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=922B4655-93D0-4476-BDA4-94CF5F8D4814&amp;amp;displaylang=en" target="_blank"&gt;Visual Studio 2010 CTP&lt;/a&gt;.&amp;#160; &lt;em&gt;(Well, maybe not.)&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;But if you have and you are looking for a great unit testing framework for your first experiments with .Net Framework 4.0, I have published an early preview of &lt;a href="http://www.gallio.org/" target="_blank"&gt;Gallio&lt;/a&gt; and &lt;a href="http://www.mbunit.com/" target="_blank"&gt;MbUnit&lt;/a&gt; v3 designed to work with the CTP.&lt;/p&gt;  &lt;p&gt;Out of the box, it supports the VSTS test runner so you can run your tests using the Visual Studio Test View.&amp;#160; Just be sure to create a new test project using the &lt;strong&gt;MbUnit v3 Test Project&lt;/strong&gt; template.&lt;/p&gt;  &lt;p&gt;Try it out!&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Download: &lt;/strong&gt;&lt;strong&gt;&lt;a href="http://ccnet.gallio.org/Distributables/VSTS%202010%20Alpha/GallioBundle-0.0.0.0-Setup-x86.msi" target="_blank"&gt;Gallio and MbUnit v3 for Visual Studio 2010 CTP&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;h4&gt;Screenshot&lt;/h4&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_X_hvY6E0egY/SRGMcz5G5MI/AAAAAAAAAPY/X3zp9C02-7Y/s1600-h/image%5B4%5D.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="515" alt="image" src="http://lh5.ggpht.com/_X_hvY6E0egY/SRGMdzfkySI/AAAAAAAAAPc/8_mvEGxj_So/image_thumb%5B2%5D.png?imgmax=800" width="644" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:c805b6aa-22fa-436b-b270-8adbbc244415" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/mbunit" rel="tag"&gt;mbunit&lt;/a&gt;,&lt;a href="http://technorati.com/tags/gallio" rel="tag"&gt;gallio&lt;/a&gt;&lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023944205100803414-6018631994452432221?l=blog.bits-in-motion.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.bits-in-motion.com/feeds/6018631994452432221/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9023944205100803414&amp;postID=6018631994452432221" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/6018631994452432221?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/6018631994452432221?v=2" /><link rel="alternate" type="text/html" href="http://blog.bits-in-motion.com/2008/11/gallio-and-mbunit-v3-for-visual-studio.html" title="Gallio and MbUnit v3 for Visual Studio 2010 CTP" /><author><name>Jeff Brown</name><uri>http://www.blogger.com/profile/09075745057339916352</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03263874364951229913" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;C0IFSXkzeCp7ImA9WxRXGU8.&quot;"><id>tag:blogger.com,1999:blog-9023944205100803414.post-1426633206278198113</id><published>2008-10-25T00:58:00.001-07:00</published><updated>2008-10-25T00:58:38.780-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-10-25T00:58:38.780-07:00</app:edited><title>See you at Microsoft PDC</title><content type="html">&lt;p&gt;I will be at the &lt;a href="http://www.microsoftpdc.com/"&gt;Microsoft PDC&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;If you're there then find me walking around wearing a &lt;a href="http://www.utilikilts.com/"&gt;kilt&lt;/a&gt;, as usual.&amp;#160; I will also be a member of a lunchtime panel on the Future of Unit Testing, probably on Wednesday.&lt;/p&gt;  &lt;p&gt;See you there!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023944205100803414-1426633206278198113?l=blog.bits-in-motion.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.bits-in-motion.com/feeds/1426633206278198113/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9023944205100803414&amp;postID=1426633206278198113" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/1426633206278198113?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9023944205100803414/posts/default/1426633206278198113?v=2" /><link rel="alternate" type="text/html" href="http://blog.bits-in-motion.com/2008/10/see-you-at-microsoft-pdc.html" title="See you at Microsoft PDC" /><author><name>Jeff Brown</name><uri>http://www.blogger.com/profile/09075745057339916352</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03263874364951229913" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry></feed>
