<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1641812635873375394</id><updated>2012-01-19T01:32:03.816-08:00</updated><category term='LTAF'/><category term='Development'/><category term='Tips and Tricks'/><category term='Announcements'/><category term='Testing'/><category term='Random Tales'/><title type='text'>Federico Silva Armas</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://www.federicosilva.net/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>61</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-1329864575566413133</id><published>2012-01-19T01:28:00.001-08:00</published><updated>2012-01-19T01:32:04.169-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Development'/><category scheme='http://www.blogger.com/atom/ns#' term='Tips and Tricks'/><title type='text'>Did you know? – NuGetGallery Build (part 6)</title><content type='html'>&lt;p&gt;Last post left off where NuGet.exe was used to download all packages before compiling the project. Let’s talk a little bit about conditions. If you remember from &lt;a href="https://github.com/NuGet/NuGetGallery/blob/master/.nuget/NuGet.targets"&gt;NuGet.targets&lt;/a&gt;, here is the target that restores the packages:&lt;/p&gt;&lt;pre class="brush: xml;"&gt;&amp;lt;Target Name="RestorePackages" DependsOnTargets="CheckPrerequisites"&amp;gt;&lt;br /&gt;    &amp;lt;Exec Command="$(RestoreCommand)"&lt;br /&gt;          LogStandardErrorAsError="true"&lt;br /&gt;          Condition="Exists('$(PackagesConfig)')" /&amp;gt;&lt;br /&gt;&amp;lt;/Target&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;I skipped over its DependsOnTargets=”&lt;strong&gt;CheckPrerequisites&lt;/strong&gt;” attribute, this target is defined on the companion &lt;a href="https://github.com/NuGet/NuGetGallery/blob/master/.nuget/NuGet.settings.targets"&gt;NuGet.settings.targets&lt;/a&gt; (in retrospect, I don’t know why there are two .target files where it seems that one would have sufficed):&lt;/p&gt;&lt;pre class="brush: xml;"&gt;&amp;lt;Target Name="CheckPrerequisites"&amp;gt;&lt;br /&gt;    &amp;lt;!-- Raise an error if we're unable to locate nuget.exe  --&amp;gt;&lt;br /&gt;    &amp;lt;Error Condition="!Exists('$(NuGetExePath)')" Text="Unable to locate '$(NuGetExePath)'" /&amp;gt;&lt;br /&gt;&amp;lt;/Target&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;This is self explanatory, it will error if Nuget.exe was not found. Furthermore, the “RestorePackages” target will error if the &lt;a href="https://github.com/NuGet/NuGetGallery/blob/master/Website/packages.config"&gt;packages.config&lt;/a&gt; file is not found.&lt;br&gt;&lt;br&gt;PS: I did left off one piece of the puzzle: precompiling the razor files before building. This is defined in the &lt;a title="https://github.com/NuGet/NuGetGallery/blob/master/3rdParty/RazorGenerator/RazorGenerator.targets" href="https://github.com/NuGet/NuGetGallery/blob/master/3rdParty/RazorGenerator/RazorGenerator.targets"&gt;RazorGenerator.targets&lt;/a&gt; which is also imported by &lt;a title="https://github.com/NuGet/NuGetGallery/blob/master/Website/Website.csproj" href="https://github.com/NuGet/NuGetGallery/blob/master/Website/Website.csproj"&gt;Website.csproj&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/1641812635873375394-1329864575566413133?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/1329864575566413133/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2012/01/did-you-know-nugetgallery-build-part-6.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/1329864575566413133'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/1329864575566413133'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2012/01/did-you-know-nugetgallery-build-part-6.html' title='Did you know? – NuGetGallery Build (part 6)'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-5874288148215436540</id><published>2012-01-18T03:12:00.001-08:00</published><updated>2012-01-18T03:14:27.287-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Development'/><category scheme='http://www.blogger.com/atom/ns#' term='Tips and Tricks'/><title type='text'>Did you know? – NuGetGallery Build (part 5)</title><content type='html'>&lt;p&gt;In the previous post we left off trying to figure out how NuGetGallery downloads its required packages during the build process. We arrived at the file that contains the targets to do this &lt;a href="https://github.com/NuGet/NuGetGallery/blob/master/.nuget/NuGet.targets"&gt;NuGet.targets&lt;/a&gt; (simplified):&lt;/p&gt;&lt;pre class="brush: xml;"&gt;&amp;lt;Project ToolsVersion="4.0"&amp;gt;&lt;br /&gt;    &amp;lt;Import Project="NuGet.settings.targets"/&amp;gt;&lt;br /&gt;    &amp;lt;Target Name="RestorePackages" DependsOnTargets="CheckPrerequisites"&amp;gt;&lt;br /&gt;        &amp;lt;Exec Command="$(RestoreCommand)"&lt;br /&gt;              LogStandardErrorAsError="true"&lt;br /&gt;              Condition="Exists('$(PackagesConfig)')" /&amp;gt;&lt;br /&gt;    &amp;lt;/Target&amp;gt;&lt;br /&gt;&amp;lt;/Project&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Excellent, there’s the definition of a “RestorePackages” target that runs an Exec task which presumably will take care of downloading the packages. The “RestoreCommand” is defined in yet another targets file which is imported at the beginning, &lt;a href="https://github.com/NuGet/NuGetGallery/blob/master/.nuget/NuGet.settings.targets"&gt;NuGet.settings.targets&lt;/a&gt; (simplified): &lt;/p&gt;&lt;pre class="brush: xml;"&gt;&amp;lt;Project ToolsVersion="4.0"&amp;gt;&lt;br /&gt;    &amp;lt;PropertyGroup&amp;gt;&lt;br /&gt;        &amp;lt;NuGetToolsPath&amp;gt;$(SolutionDir).nuget&amp;lt;/NuGetToolsPath&amp;gt;&lt;br /&gt;        &amp;lt;NuGetExePath&amp;gt;$(NuGetToolsPath)\nuget.exe&amp;lt;/NuGetExePath&amp;gt;&lt;br /&gt;        &amp;lt;PackagesConfig&amp;gt;$(ProjectDir)packages.config&amp;lt;/PackagesConfig&amp;gt;&lt;br /&gt;        &amp;lt;PackagesDir&amp;gt;$(SolutionDir)packages&amp;lt;/PackagesDir&amp;gt;&lt;br /&gt;&lt;br /&gt;        &amp;lt;!-- Commands --&amp;gt;&lt;br /&gt;        &amp;lt;RestoreCommand&amp;gt;"$(NuGetExePath)" install "$(PackagesConfig)" -o "$(PackagesDir)"&amp;lt;/RestoreCommand&amp;gt;&lt;br /&gt;&lt;br /&gt;        &amp;lt;!-- Make the build depend on restore packages --&amp;gt;&lt;br /&gt;        &amp;lt;BuildDependsOn Condition="$(RestorePackages) == 'true'"&amp;gt;&lt;br /&gt;            RestorePackages;&lt;br /&gt;            $(BuildDependsOn);&lt;br /&gt;        &amp;lt;/BuildDependsOn&amp;gt;&lt;br /&gt;    &amp;lt;/PropertyGroup&amp;gt;   &lt;br /&gt; &amp;lt;/Project&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;A lot of things happening here:&lt;br&gt;- There is a property definition to the location of NuGet.exe (which is included in the source)&lt;br&gt;- There is a property definition to a &lt;a href="https://github.com/NuGet/NuGetGallery/blob/master/Website/packages.config"&gt;packages.config&lt;/a&gt;, which contains the list of packages that it needs to download.&lt;br&gt;- There is a property definition to a directory where the packages will be downloaded into.&lt;br&gt;- Then there is a property definition for the actual restore command, which is a call to Nuget.exe with the “install” parameter.&lt;br&gt;&lt;br&gt;The next line is probably the most important one, it’s where the target defined previously is glued into the build process. “BuildDependsOn” is a special MSBuild property used to override the sequence of steps during build. In this case it adds the “RestorePackages” target at the beginning.&lt;br&gt;&lt;br&gt;Don’t get tripped up by the condition included in the “BuildDependsOn” which uses a property with the same name as the target “RestorePackages” (this confused me for a while). Basically we are only going to download the references if the “RestorePackages” property is set to true, which if you remember it was set at the beginning of &lt;a href="https://github.com/NuGet/NuGetGallery/blob/master/Website/Website.csproj"&gt;Website.csproj&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/1641812635873375394-5874288148215436540?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/5874288148215436540/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2012/01/did-you-know-nugetgallery-build-part-5.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/5874288148215436540'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/5874288148215436540'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2012/01/did-you-know-nugetgallery-build-part-5.html' title='Did you know? – NuGetGallery Build (part 5)'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-588388413357366167</id><published>2012-01-16T23:37:00.001-08:00</published><updated>2012-01-16T23:42:04.720-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Development'/><category scheme='http://www.blogger.com/atom/ns#' term='Tips and Tricks'/><title type='text'>Did you know? – NuGetGallery Build (part 4)</title><content type='html'>&lt;p&gt;In the last post we left at the point where all previous build output from all projects was deleted. Let’s continue with the build from &lt;a href="https://github.com/NuGet/NuGetGallery/blob/master/Scripts/NuGetGallery.msbuild"&gt;NuGetGallery.msbuild&lt;/a&gt;:&lt;/p&gt;&lt;pre class="brush: xml;"&gt;&amp;lt;Target Name="Build" DependsOnTargets="Clean"&amp;gt;&lt;br /&gt;    &amp;lt;MSBuild Projects="..\NuGetGallery.sln" Targets="Build" Properties="Configuration=$(Configuration);CodeAnalysis=true;" /&amp;gt;&lt;br /&gt;  &amp;lt;/Target&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;The msbuild task is invoked again, to run the Build target on the &lt;a href="https://github.com/NuGet/NuGetGallery/blob/master/NuGetGallery.sln"&gt;NuGetGallery.sln&lt;/a&gt;. This file references the “&lt;a href="https://github.com/NuGet/NuGetGallery/blob/master/Website/Website.csproj"&gt;Website\Website.csproj&lt;/a&gt;”, MSBuild runs the Build target on this project.&lt;br&gt;&lt;br&gt;Now, before it can compile anything it needs to download all the dependencies. Notice that NuGetGallery includes very few assemblies as part of the source, take a look at the “&lt;a href="https://github.com/NuGet/NuGetGallery/tree/master/3rdParty"&gt;3rd Party&lt;/a&gt;” folder to see an unimpressive list of references. The trick is that it uses NuGet.exe to download all the extra references before the build. So how does it accomplish this magic? Let’s take a look at WebSite.csproj (simplified):&lt;/p&gt;&lt;pre class="brush: xml;"&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&lt;br /&gt;&amp;lt;Project ToolsVersion="4.0" DefaultTargets="Build"&amp;gt;&lt;br /&gt;  &amp;lt;PropertyGroup&amp;gt;&lt;br /&gt;    &amp;lt;RestorePackages&amp;gt;true&amp;lt;/RestorePackages&amp;gt;&lt;br /&gt;  &amp;lt;/PropertyGroup&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;Import Project="$(SolutionDir)\.nuget\NuGet.targets" /&amp;gt;&lt;br /&gt;&amp;lt;/Project&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Mh, there’s a property called “RestorePackages” that sounds like it’s used to, I don’t know, restoring nuget packages? Remember this one. And at the bottom there is an import of &lt;a href="https://github.com/NuGet/NuGetGallery/blob/master/.nuget/NuGet.targets"&gt;NuGet.targets&lt;/a&gt;. That’s where the answers must be! &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-588388413357366167?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/588388413357366167/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2012/01/did-you-know-nugetgallery-build-part-4.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/588388413357366167'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/588388413357366167'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2012/01/did-you-know-nugetgallery-build-part-4.html' title='Did you know? – NuGetGallery Build (part 4)'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-1018456522705595587</id><published>2012-01-14T23:11:00.001-08:00</published><updated>2012-01-14T23:15:42.131-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Development'/><category scheme='http://www.blogger.com/atom/ns#' term='Tips and Tricks'/><title type='text'>Did you know? – NuGetGallery Build (part 3)</title><content type='html'>&lt;p&gt;In the previous posts we saw how the NuGetGallery build got kicked off by &lt;a href="https://github.com/NuGet/NuGetGallery/blob/master/Build-Solution.ps1"&gt;Build-Solution.ps1&lt;/a&gt;, which internally went and grabbed the connection string from the website’s web.config using &lt;a href="https://github.com/NuGet/NuGetGallery/blob/master/Scripts/Get-ConnectionString.ps1"&gt;Get-ConnectionString.ps1&lt;/a&gt;. At the end of the file it finally calls msbuild.exe passing the &lt;a href="https://github.com/NuGet/NuGetGallery/blob/master/Scripts/NuGetGallery.msbuild"&gt;NuGetGallery.msbuild&lt;/a&gt; file and the connection string (pay special attention to the &lt;strong&gt;/t:FullBuild&lt;/strong&gt; at the end which defines which target to run):&lt;/p&gt;&lt;pre class="brush: xml;"&gt;$projFile = join-path $scriptPath Scripts\NuGetGallery.msbuild&lt;br /&gt;&amp;amp; "$(get-content env:windir)\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe" $projFile /p:DbConnection=$connectionString /t:FullBuild&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Let’s peel another piece of the onion and look at this msbuild file (simplified):&lt;/p&gt;&lt;pre class="brush: xml;"&gt;&amp;lt;Project DefaultTargets="Build"&amp;gt;&lt;br /&gt;  &amp;lt;Target Name="Clean"&amp;gt;&lt;br /&gt;    &amp;lt;MSBuild Projects="..\NuGetGallery.sln" Targets="Clean" Properties="Configuration=$(Configuration)"/&amp;gt;&lt;br /&gt;  &amp;lt;/Target&amp;gt;&lt;br /&gt;  &lt;br /&gt;  &amp;lt;Target Name="Build" DependsOnTargets="Clean"&amp;gt;&lt;br /&gt;    &amp;lt;MSBuild Projects="..\NuGetGallery.sln" Targets="Build" Properties="Configuration=$(Configuration);CodeAnalysis=true;" /&amp;gt;&lt;br /&gt;  &amp;lt;/Target&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;Target Name="RunFacts" DependsOnTargets="Build"&amp;gt; ... &amp;lt;/Target&amp;gt;&lt;br /&gt;  &amp;lt;Target Name="FullBuild" DependsOnTargets="RunFacts;UpdateDatabase" /&amp;gt;&lt;br /&gt;&amp;lt;/Project&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;This is where it starts to wire up a list of targets to run during the build. As you can see, the “FullBuild” target is empty, but depends on the “RunFacts” and “UpdateDatabase” targets. Working our way back, the “RunFacts” depends on “Build”, which in turn depends on “Clean”. &lt;br&gt;&lt;br&gt;Phew, maybe we can now do some work? All right, at this point it calls msbuild to run the “Clean” target on the &lt;a href="https://github.com/NuGet/NuGetGallery/blob/master/NuGetGallery.sln"&gt;NuGetGallery.sln&lt;/a&gt; file. I am going to skip how this part works, the important thing is that all the projects included in the solution will delete all their intermediate and final build outputs. Note: the “Clean” target is defined in “Microsoft.Common.targets” file which lives in your framework directory.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-1018456522705595587?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/1018456522705595587/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2012/01/did-you-know-nugetgallery-build-part-3.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/1018456522705595587'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/1018456522705595587'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2012/01/did-you-know-nugetgallery-build-part-3.html' title='Did you know? – NuGetGallery Build (part 3)'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-228649537890804082</id><published>2012-01-13T13:26:00.001-08:00</published><updated>2012-01-14T20:32:12.732-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Development'/><category scheme='http://www.blogger.com/atom/ns#' term='Tips and Tricks'/><title type='text'>Did you know? – NuGetGallery RequestModels</title><content type='html'>A while back, while working on ASP.NET MVC, I learned to not pass the business models directly into my Views. Especially if they were Entity Framework entities. So I got in the habit of creating specialized ViewModels for this purpose.&lt;br /&gt;&lt;br /&gt;But last week, while reading NuGetGallery’s source, I saw how they took this concept to the next step: &lt;a href="https://github.com/NuGet/NuGetGallery/tree/master/Website/RequestModels"&gt;RequestModels&lt;/a&gt;. You see, for the MVC applications that I wrote I was accustomed to re-using the ViewModel to capture data from the requests, my thinking was “well, I used the ViewModel to generate the response, it’s fitting that it should also be used to receive requests from the page that it created”.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://lh5.ggpht.com/-RHHf1CtfdSc/TxChaF-oTJI/AAAAAAAAAcU/mHQvGtj0VX4/s1600-h/RequestModels%25255B3%25255D.png"&gt;&lt;img align="left" alt="RequestModels" border="0" height="484" src="http://lh4.ggpht.com/-MVJWcZzlIfQ/TxChbt1JPrI/AAAAAAAAAcc/-CZG4f_dN8s/RequestModels_thumb%25255B1%25255D.png?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; float: left; margin: 0px 18px 0px 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="RequestModels" width="305" /&gt;&lt;/a&gt;&lt;br /&gt;I like the idea of further separating the concerns between the object that is used to create response and the one used to bind to the request. You’ll notice how the RequestModels have the validations from DataAnnotations that are to be used when binding to the request and only have the fields necessary to process each request.&lt;br /&gt;&lt;br /&gt;For some reason, the application doesn’t use this extra separation all the time and some times receives the ViewModel (for example in the &lt;a href="https://github.com/NuGet/NuGetGallery/blob/eb0b39e7e407949edd9bdb4d307ad8ddb561a83b/Website/Controllers/PackagesController.cs#L189"&gt;PackagesController.cs&lt;/a&gt;). An oversight?&lt;br /&gt;&lt;br /&gt;I am going to play around with this way of organization in my own projects and see how it feels.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-228649537890804082?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/228649537890804082/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2012/01/did-you-know-nugetgallery-requestmodels.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/228649537890804082'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/228649537890804082'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2012/01/did-you-know-nugetgallery-requestmodels.html' title='Did you know? – NuGetGallery RequestModels'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/-MVJWcZzlIfQ/TxChbt1JPrI/AAAAAAAAAcc/-CZG4f_dN8s/s72-c/RequestModels_thumb%25255B1%25255D.png?imgmax=800' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-7095519910279002569</id><published>2012-01-06T00:03:00.001-08:00</published><updated>2012-01-07T13:41:41.714-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Development'/><category scheme='http://www.blogger.com/atom/ns#' term='Tips and Tricks'/><title type='text'>Did you know? – XUnit Theories</title><content type='html'>&lt;p&gt;Another discovery while reading through the &lt;a href="https://github.com/NuGet/NuGetGallery"&gt;NuGet Gallery&lt;/a&gt; source. As I was taking a look at their tests I bumped into &lt;a href="https://github.com/NuGet/NuGetGallery/blob/master/Facts/RequireRemoteHttpsAttributeFacts.cs"&gt;RequireRemoteHttpsAttributeFacts.cs&lt;/a&gt; and saw this attribute:&lt;/p&gt;&lt;pre class="brush: csharp;"&gt;[Theory]&lt;br /&gt;[InlineData(new object[] { "POST" })]&lt;br /&gt;[InlineData(new object[] { "DELETE" })]&lt;br /&gt;[InlineData(new object[] { "PUT" })]&lt;br /&gt;[InlineData(new object[] { "head" })]&lt;br /&gt;[InlineData(new object[] { "trace" })]&lt;br /&gt;public void RequireHttpsAttributeReturns403IfNonGetRequest(string method)&lt;br /&gt;{&lt;br /&gt;    ...&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Now, I realise this may be old news since XUnit Extensions has been around since at least 2008, but it was new to me. This works very similar to NUnit Testcase attribute, each of the InlineData will be passed to the test as an argument.&lt;br&gt;&lt;br&gt;There are different data providers including in the xunit.extensions assembly:&lt;br&gt;1. ExcelData &lt;br&gt;2. InlineData &lt;br&gt;3. OleDbData &lt;br&gt;4. PropertyData &lt;br&gt;5. SqlServerData&lt;br&gt;&lt;br&gt;An introduction blog post about xunit extensions can be found &lt;a href="http://blog.benhall.me.uk/2008/01/introduction-to-xunitnet-extensions.html"&gt;here&lt;/a&gt; (by Ben Hall).&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-7095519910279002569?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/7095519910279002569/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2012/01/did-you-know-xunit-theories.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/7095519910279002569'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/7095519910279002569'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2012/01/did-you-know-xunit-theories.html' title='Did you know? – XUnit Theories'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-7944546510314930407</id><published>2012-01-05T23:40:00.001-08:00</published><updated>2012-01-14T20:23:41.230-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Development'/><category scheme='http://www.blogger.com/atom/ns#' term='Tips and Tricks'/><title type='text'>Did you know? – NuGetGallery Build (part 2)</title><content type='html'>To continue my previous post, let’s take a peek at &lt;a href="https://github.com/NuGet/NuGetGallery/blob/master/Scripts/Get-ConnectionString.ps1"&gt;Get-ConnectionString.ps1&lt;/a&gt;, because there is something in there that I had no idea you could do:&lt;br /&gt;&lt;pre class="brush: ps;"&gt;function Get-ConnectionString($configPath, $connectionStringName) &lt;br /&gt;{&lt;br /&gt;  $config = [xml](get-content $configPath)&lt;br /&gt;  &lt;br /&gt;  $connectionString = ($config.configuration.connectionStrings.add | where { $_.name -eq $connectionStringName }).connectionString&lt;br /&gt;  &lt;br /&gt;  $connectionString = $connectionString.Replace("=", "%3D")&lt;br /&gt;  $connectionString = $connectionString.Replace(";", "%3B")&lt;br /&gt;&lt;br /&gt;  return $connectionString&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Look at line #3, what’s up with that “&lt;strong&gt;[xml]&lt;/strong&gt;” statement? Is it trying to cast the output of get-content as xml? That’s ok, I guess. But then the next line hits:&lt;strong&gt;&lt;br /&gt;($config.configuration.connectionStrings.add | where { $_.name -eq $connectionStringName }).connectionString&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;It can traverse XML nodes and attributes like property objects?!? Kudos to you Mr. PowerShell. I have no idea how that &lt;strong&gt;[xml]&lt;/strong&gt; works or what others are supported but I did a small experiment in the PowerShell REPL:&lt;br /&gt;&lt;pre class="brush: ps;"&gt;$foo = [xml] "&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;"&lt;br /&gt;$foo.getType()&lt;/pre&gt;&lt;br /&gt;And it says that it is of type &lt;strong&gt;System.Xml.XmlDocument&lt;/strong&gt;. The fact that you can traverse it and the way the author uses the where command-let to filter is awesome (was that you Drew? Kudos to you too man). &lt;br /&gt;&lt;br /&gt;So now you know, maybe it will come handy some day.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-7944546510314930407?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/7944546510314930407/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2012/01/did-you-know-nugetgallery-build-part-2.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/7944546510314930407'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/7944546510314930407'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2012/01/did-you-know-nugetgallery-build-part-2.html' title='Did you know? – NuGetGallery Build (part 2)'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-506071461224158656</id><published>2012-01-05T01:37:00.001-08:00</published><updated>2012-01-14T20:21:45.307-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Development'/><category scheme='http://www.blogger.com/atom/ns#' term='Tips and Tricks'/><title type='text'>Did you know? – NuGetGallery Build</title><content type='html'>Today I read over the &lt;a href="https://github.com/NuGet/NuGetGallery"&gt;NuGetGallery source&lt;/a&gt; and naturally, started with the first entry point according to the documentation: their build script.&lt;br /&gt;&lt;strong&gt;Build-Solution.ps1&lt;/strong&gt;&lt;br /&gt;There is a lot of PowerShell stuff that I didn’t know about in this short file, so let's look at it line by line:&lt;br /&gt;1. The param() function is used to process named parameters, so the connection string can be passed when calling into this script. &lt;br /&gt;&lt;pre class="brush: ps;"&gt;param($connectionString = "")&lt;/pre&gt;&lt;br /&gt;2. Next it gets the path to the directory that contains this script file and uses it to invoke another .ps1 file. Note that the “.” is used to set PowerShell to parse the line in command mode. We’ll look at what Get-ConnectionString.ps1 does some other time, for now just be aware that it is going to load a new function to be used.&lt;br /&gt;&lt;pre class="brush: ps;"&gt;$scriptPath = Split-Path $MyInvocation.MyCommand.Path&lt;br /&gt;. (join-path $scriptPath Scripts\Get-ConnectionString.ps1)&lt;/pre&gt;&lt;br /&gt;3. This is where the function is used, note that the web.config file is passed to it, so apparently that script is capable of parsing the xml to retrieve the connection string.&lt;br /&gt;&lt;pre class="brush: ps;"&gt;if ($connectionString.Trim() -eq "") &lt;br /&gt;{&lt;br /&gt;  $connectionString = Get-ConnectionString -configPath (join-path $scriptPath Website\web.config) -connectionStringName NuGetGallery&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;4. Finally msbuild is invoked. Three things to note: &lt;br /&gt;-&amp;nbsp; it is not building the .sln file directly but instead a custom .msbuild file is used (take a look at that for some nice usage of targets).&lt;br /&gt;-&amp;nbsp; it uses the get-content command let to retrieve the value of an environment variable for the windows directory&lt;br /&gt;- note the “&amp;amp;” at the begnning of the line? This turns PowerShell into expression mode so that the string is evaluated as an expression. First time I ever saw that.&lt;br /&gt;&lt;pre class="brush: ps;"&gt;$projFile = join-path $scriptPath Scripts\NuGetGallery.msbuild&lt;br /&gt; &lt;br /&gt;&amp;amp; "$(get-content env:windir)\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe" $projFile /p:DbConnection=$connectionString /t:FullBuild&lt;/pre&gt;&lt;br /&gt;Pretty cool stuff, source file &lt;a href="https://github.com/NuGet/NuGetGallery/blob/master/Build-Solution.ps1"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-506071461224158656?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/506071461224158656/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2012/01/did-you-know-nugetgallery-build.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/506071461224158656'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/506071461224158656'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2012/01/did-you-know-nugetgallery-build.html' title='Did you know? – NuGetGallery Build'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-8904989395445549440</id><published>2012-01-03T23:35:00.001-08:00</published><updated>2012-01-14T20:18:01.562-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Development'/><category scheme='http://www.blogger.com/atom/ns#' term='Tips and Tricks'/><title type='text'>Did you know? - WCF and ClientMessageInspector</title><content type='html'>Last month I got a feature request to add time logging to the &lt;a href="https://bitbucket.org/farmas/atlassian.net-sdk"&gt;Atlassian .NET SDK&lt;/a&gt;. I thought it would be simple until I ran into a peculiar JIRA bug: it turns out that the SOAP response to any call involving time tracking blows up miserably. Curse you JIRA!&lt;br /&gt;&lt;br /&gt;After searching the inter webs, I found what the error is on the response and how to fix it. Now what I needed was a way to intercept the response from the server and fix it up before it got passed to the internals of WCF&lt;br /&gt;&lt;h2&gt;ClientMessageInspector to the rescue!&lt;/h2&gt;First create one of these guys that can update the content of the message&lt;br /&gt;&lt;pre class="brush: java;"&gt;class RemoteWorklogMessageInspector : IClientMessageInspector&lt;br /&gt;{&lt;br /&gt;    public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)&lt;br /&gt;    {&lt;br /&gt;        // update the contents of the response and return a new one with the changes&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public object BeforeSendRequest(ref Message request, IClientChannel channel)&lt;br /&gt;    {&lt;br /&gt;        return null;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;Then you have to register it, which wasn’t totally intuitive. Next you need to create an EndpointBehaviour that adds the inspector to the ClientRuntime. &lt;br /&gt;&lt;pre class="brush: java;"&gt;class RemoteWorklogPatchBehavior : IEndpointBehavior&lt;br /&gt;{    &lt;br /&gt;    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)&lt;br /&gt;    {&lt;br /&gt;        clientRuntime.MessageInspectors.Add(new RemoteWorklogMessageInspector());&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    // other methods from the interface&lt;br /&gt;}&lt;/pre&gt;Finally, add the behaviour to the endpoint of the service: &lt;br /&gt;&lt;pre class="brush: java;"&gt;var jiraSoapServiceClient = new JiraSoapServiceClient(binding, endpoint);&lt;br /&gt;jiraSoapServiceClient.Endpoint.Behaviors.Add(new RemoteWorklogPatchBehavior());&lt;/pre&gt;&lt;br /&gt;Now, whenever a SOAP request goes to JIRA, the response will be inspected and updated if necessary to fix that nasty bug. &lt;br /&gt;&lt;br /&gt;Look &lt;a href="https://bitbucket.org/farmas/atlassian.net-sdk/src/f3c44200f467/Atlassian.Jira/Remote/RemoteWorklogPatchBehavior.cs"&gt;here&lt;/a&gt; for the full source.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-8904989395445549440?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/8904989395445549440/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2012/01/quick-bite-1-did-you-know-wcf.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/8904989395445549440'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/8904989395445549440'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2012/01/quick-bite-1-did-you-know-wcf.html' title='Did you know? - WCF and ClientMessageInspector'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-7061963678044962583</id><published>2012-01-03T23:02:00.001-08:00</published><updated>2012-01-03T23:02:42.185-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Development'/><title type='text'>“Tags” plugin now available in plugins.atlassian.com</title><content type='html'>&lt;p&gt;For those interested, the entry is available &lt;a href="https://plugins.atlassian.com/plugin/details/929295"&gt;here&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Now I need to convince the admins to install it in our internal instance so that I can start using it for my test sessions.&lt;/p&gt; &lt;p&gt;- Federico&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-7061963678044962583?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/7061963678044962583/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2012/01/tags-plugin-now-available-in.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/7061963678044962583'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/7061963678044962583'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2012/01/tags-plugin-now-available-in.html' title='“Tags” plugin now available in plugins.atlassian.com'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-914635840306474473</id><published>2011-12-30T13:44:00.000-08:00</published><updated>2012-01-14T20:14:44.456-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Development'/><title type='text'>LeoMejor</title><content type='html'>Awhile ago, I&amp;nbsp;&lt;a href="http://www.federicosilva.net/2011/09/learn-spanish-while-i-learn-backbonejs.html"&gt;blogged &lt;/a&gt;about a website that my sister and I were building using backbone.js. The site is now finished and all that remains is for my sister to periodically add more content.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;img border="0" height="240" src="http://1.bp.blogspot.com/-Lt1wLtpqocg/Tv4wbeyj1mI/AAAAAAAAAZA/LNaPjU49pGE/s320/leomejor.png" width="320" /&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://leomejor.apphb.com/"&gt;http://leomejor.apphb.com&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-914635840306474473?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/914635840306474473/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2011/12/leomejor.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/914635840306474473'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/914635840306474473'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2011/12/leomejor.html' title='LeoMejor'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-Lt1wLtpqocg/Tv4wbeyj1mI/AAAAAAAAAZA/LNaPjU49pGE/s72-c/leomejor.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-3573714257931224185</id><published>2011-12-04T01:19:00.001-08:00</published><updated>2012-01-14T20:13:40.132-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Development'/><category scheme='http://www.blogger.com/atom/ns#' term='Testing'/><title type='text'>“Tags” plugin for Confluence</title><content type='html'>&lt;a href="http://www.satisfice.com/articles/what_is_et.shtml"&gt;Exploratory Testing&lt;/a&gt; is an approach that I use a lot while testing a feature, and part of it is taking good notes while doing it. For years I used to take notes with pen and paper but eventually I evolved to do it directly on the computer (mainly because it's way easier if I am taking lots of screen shots and video). &lt;br /&gt;&lt;br /&gt;My preferred tool is OneNote, primarily because it does a good job for staying out of my way and it is very flexible (the sync feature is also nice for collaboration). When I joined Atlassian, everything is written on an internal wiki using &lt;a href="http://www.atlassian.com/software/confluence"&gt;Confluence&lt;/a&gt;. For the most part, it does a good job for test note taking except that I really missed the “&lt;a href="http://www.addictivetips.com/microsoft-office/onenote-2010-tagging-guide/"&gt;tags&lt;/a&gt;” feature of OneNote. I used to rely heavily on it for my own organization of test tasks, so I decided to take some 20% time and write a Confluence plug-in to add this.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Overview&lt;/strong&gt;&lt;br /&gt;Confluence 4 plug-in that creates a status list created from "tags" added to the content of pages.&lt;br /&gt;- &lt;a href="https://bitbucket.org/farmas/confluence-tags-plugin"&gt;Bitbucket project&lt;/a&gt;&lt;br /&gt;- &lt;a href="https://bitbucket.org/farmas/confluence-tags-plugin/downloads/tags-plugin-1.1.jar"&gt;Download (.jar)&lt;/a&gt;&lt;br /&gt;&lt;h4&gt;&amp;nbsp;&lt;/h4&gt;&lt;h4&gt;Features&lt;/h4&gt;&lt;strong&gt;Tag Content&lt;/strong&gt;&lt;br /&gt;Use any of the built in emoticons to "tag" a line while typing in Confluence. For fast editing, you can use short cuts:&lt;br /&gt;- (/): check mark&lt;br /&gt;- (x): error&lt;br /&gt;- (?): question mark&lt;br /&gt;- (!): exclamation mark&lt;br /&gt;- (on): light bulb&lt;br /&gt;"Tags" can have any meaning that you want, it is a way of marking content for follow up.&lt;br /&gt;&lt;img height="480" src="http://i1207.photobucket.com/albums/bb473/fsilva_armas/tags1.png" width="622" /&gt;&lt;br /&gt;&lt;strong&gt;Tag summary&lt;/strong&gt;&lt;br /&gt;On a parent page, add the "Tag Summary" macro to view a tree that summarizes all the tags available on child pages. &lt;br /&gt;&lt;img height="480" src="http://i1207.photobucket.com/albums/bb473/fsilva_armas/tags2.png" width="459" /&gt;&lt;br /&gt;&lt;img height="361" src="http://i1207.photobucket.com/albums/bb473/fsilva_armas/tags3.png" width="640" /&gt;&lt;br /&gt;&lt;strong&gt;Page hierarchy&lt;/strong&gt;&lt;br /&gt;The tag summary becomes really useful when there are many hierarchical pages of content and the author needs to keep track of action items across them.&lt;br /&gt;&lt;img height="480" src="http://i1207.photobucket.com/albums/bb473/fsilva_armas/tags4.png" width="416" /&gt;&lt;br /&gt;&lt;strong&gt;Filter tags&lt;/strong&gt;&lt;br /&gt;Filter which tags to show on the tree to quickly identify the items that you care about.&lt;br /&gt;&lt;img height="480" src="http://i1207.photobucket.com/albums/bb473/fsilva_armas/tags5.png" width="416" /&gt;&lt;br /&gt;&lt;strong&gt;Preview&lt;/strong&gt;&lt;br /&gt;Click on a tag icon on the tree to open a preview window that loads the content of the child page, scrolled to the section where the tag is located.&lt;br /&gt;&lt;img height="480" src="http://i1207.photobucket.com/albums/bb473/fsilva_armas/tags60.png" width="640" /&gt;&lt;br /&gt;&lt;strong&gt;Clear tags&lt;/strong&gt;&lt;br /&gt;When an item is resolved you can clear the tag directly from the tree. This will remove the icon from the target page. Right click on a tree node to bring up the context dialog.&lt;br /&gt;&lt;img height="480" src="http://i1207.photobucket.com/albums/bb473/fsilva_armas/tags7.png" width="416" /&gt;&lt;br /&gt;&lt;h4&gt;&amp;nbsp;&lt;/h4&gt;- Federico&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-3573714257931224185?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/3573714257931224185/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2011/12/tags-plugin-for-confluence.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/3573714257931224185'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/3573714257931224185'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2011/12/tags-plugin-for-confluence.html' title='“Tags” plugin for Confluence'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-8856013697914286524</id><published>2011-11-18T20:46:00.001-08:00</published><updated>2011-11-18T20:47:25.058-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Announcements'/><title type='text'>Projects page</title><content type='html'>&lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Small announcemnt that there is now a &lt;a href="http://www.federicosilva.net/p/projects.html"&gt;page&lt;/a&gt; on my blog where I’ll store information of the projects that I’ve worked on.&lt;/p&gt; &lt;p&gt;- Federico&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-8856013697914286524?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/8856013697914286524/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2011/11/small-announcemnt-that-there-is-now.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/8856013697914286524'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/8856013697914286524'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2011/11/small-announcemnt-that-there-is-now.html' title='Projects page'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-3055281062438363547</id><published>2011-11-18T13:51:00.001-08:00</published><updated>2011-11-18T14:24:31.840-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Development'/><category scheme='http://www.blogger.com/atom/ns#' term='Testing'/><title type='text'>Quickly create issues with the JIRA Tray App</title><content type='html'>&lt;br /&gt;I wrote the &lt;a href="https://bitbucket.org/farmas/jiratrayapp"&gt;Jira Tray App&lt;/a&gt; to solve two problems that I had in my daily workflow:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;I practice exploratory testing and divide my work into focused sessions. I don’t open bugs as I am testing, instead I take notes of the problem and keep testing. At the end of the session, I go over my notes, perform deeper investigation of the issues I found and THEN open bugs (in a batch). I wanted a tool that would speed up creation of consecutive bugs.&lt;/li&gt;&lt;li&gt;At Atlassian, every team has its own JIRA instance to track their work with their own conventions of which fields are required. I wanted a tool that could keep track of all the servers for me and expose a common interface to create issues in all them.&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;h4&gt;Windows Tray&lt;/h4&gt;This tool is a windows tray application that maintains a list of templates to quickly open JIRA issues. The idea is that you create “issue templates” with pre-populated values for each of your JIRA projects.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://lh5.ggpht.com/-PVCnGJY52AI/TsbTO3CfQiI/AAAAAAAAARY/T3UN7x6nWXY/s1600-h/jira-tray-app-1%25255B2%25255D.png"&gt;&lt;img alt="jira-tray-app-1" border="0" height="128" src="http://lh3.ggpht.com/-neu043nGXMI/TsbTQFxs1JI/AAAAAAAAARc/R8HM7wrsU8I/jira-tray-app-1_thumb.png?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="jira-tray-app-1" width="244" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Issue Form&lt;/h4&gt;The issue template form is used to create new issues based on the template or manipulating the list of templates.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://lh3.ggpht.com/-fJuaeIsGPDI/TsbTRnjOz0I/AAAAAAAAARo/gxPuxL8DDk4/s1600-h/jira-tray-app-3%25255B5%25255D.png"&gt;&lt;img alt="jira-tray-app-3" border="0" height="496" src="http://lh4.ggpht.com/-ZG4xPZBsu3c/TsbTTJfZX7I/AAAAAAAAARw/PTlNU-tsGJ4/jira-tray-app-3_thumb%25255B3%25255D.png?imgmax=800" style="background-image: none; border-bottom-color: initial; border-bottom-style: initial; border-bottom-width: 0px; border-left-color: initial; border-left-style: initial; border-left-width: 0px; border-right-color: initial; border-right-style: initial; border-right-width: 0px; border-top-color: initial; border-top-style: initial; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="jira-tray-app-3" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Template: The name of the template (what appears on the tray menu).  &lt;/li&gt;&lt;li&gt;The summary of the issue.  &lt;/li&gt;&lt;li&gt;The description of the issue.  &lt;/li&gt;&lt;li&gt;Fields of the issue to create (also includes the data of the server). For fields that support it, a picker is available with valid values from server.  &lt;/li&gt;&lt;li&gt;List of attachments.  &lt;/li&gt;&lt;li&gt;Clears the list of attachments.  &lt;/li&gt;&lt;li&gt;Adds an attachment from disk to the list.  &lt;/li&gt;&lt;li&gt;Pastes the contents of the clipboard as an attachment (either as an image or text file). Really handy if you use a screen capturing tool like &lt;a href="http://www.techsmith.com/jing.html?gclid=CPTA25rKvawCFckF4godBg4moA"&gt;Jing&lt;/a&gt;.  &lt;/li&gt;&lt;li&gt;Template: Saves the values of current template.  &lt;/li&gt;&lt;li&gt;Template: Clones this template.  &lt;/li&gt;&lt;li&gt;Template: Deletes this template.  &lt;/li&gt;&lt;li&gt;Automatically closes the form when an issue is created.  &lt;/li&gt;&lt;li&gt;Creates an issue with the current values.  &lt;/li&gt;&lt;li&gt;Closes the form without saving template or creating an issue&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;h4&gt;Handy Features&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;The “Paste” from clipboard for adding attachments to an issue (images or text files)&lt;/li&gt;&lt;li&gt;The app automatically saves the last issue created as a template, if you need to open multiple issues with some similar data between them.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;h4&gt;Up Coming Features&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;Ability to rename attachment files&lt;/li&gt;&lt;li&gt;Ability to save/restore templates (so you can pass them around)&lt;/li&gt;&lt;li&gt;Querying capabilities.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;h4&gt;Resources&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="https://bitbucket.org/farmas/jiratrayapp"&gt;Source&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://bitbucket.org/farmas/jiratrayapp/downloads/JiraTrayApp-1.0.zip"&gt;Binaries&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Built on top of the &lt;a href="https://bitbucket.org/farmas/atlassian.net-sdk"&gt;Atlassian .NET SDK&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;- Federico&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-3055281062438363547?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/3055281062438363547/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2011/11/quickly-create-issues-with-jira-tray.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/3055281062438363547'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/3055281062438363547'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2011/11/quickly-create-issues-with-jira-tray.html' title='Quickly create issues with the JIRA Tray App'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/-neu043nGXMI/TsbTQFxs1JI/AAAAAAAAARc/R8HM7wrsU8I/s72-c/jira-tray-app-1_thumb.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-5859651552009053141</id><published>2011-11-16T02:27:00.001-08:00</published><updated>2011-11-18T14:28:34.169-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Random Tales'/><title type='text'>Upgrade testing is rotting my brain</title><content type='html'>&lt;br /&gt;Installer and upgrade testing is probably the worst activity that I have to do as a tester. To put it bluntly: I hate it.&lt;br /&gt;&lt;br /&gt;I like creating the strategy and the plan to get good coverage with smart test design, but when one gets to executing these tests, it tends to fall into the repetitive, slow grind that quickly spirals into tester fatigue land.&lt;br /&gt;&lt;br /&gt;For the past week, I have been reimaging a set of machines, preparing them with test data, performing an upgrade and verifying the state of the application and trying to find if anything unexpected happened. If I find a failure, instead of the usual rush of adrenaline that every tester gets, I groan when I think of all the extra reimaging I’ll have to do to narrow down the repro steps. Plus, trying the scenario on the previous version and the “other” platform to gather more information for developers.&lt;br /&gt;&lt;br /&gt;The sad part about this is that I feel like I am not learning anything during these periods. And I get sloppy after a while. A part of me thinks that this salt-mine work is necessary, but another wonders if there is a better way to do this…&lt;br /&gt;&lt;br /&gt;Anybody has good suggestions for a fellow tester?&lt;br /&gt;&lt;br /&gt;- Federico&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-5859651552009053141?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/5859651552009053141/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2011/11/installer-and-upgrade-testing-is.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/5859651552009053141'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/5859651552009053141'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2011/11/installer-and-upgrade-testing-is.html' title='Upgrade testing is rotting my brain'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-5792739138471878688</id><published>2011-11-12T13:16:00.001-08:00</published><updated>2011-11-18T14:30:57.513-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Development'/><title type='text'>A simple WebDriver runner for QUnit</title><content type='html'>&lt;br /&gt;I have been working on a &lt;a href="https://bitbucket.org/farmas/confluence-tags-plugin"&gt;Confluence plugin&lt;/a&gt; during my 20% time and, as part of it, writing a number of qunit tests. I was looking for a way to run them as part of CI and found this &lt;a href="http://code.google.com/p/qunit-maven-plugin/"&gt;qunit-maven-plugin&lt;/a&gt; out there. After trying to use it unsuccessfully for a couple of minutes, I confess to falling into the well-known “reinvent the wheel” mentality trap. &lt;br /&gt;&lt;br /&gt;I’ve been working with WebDriver quite a lot and the idea came to me that it would not be hard to create a simple qunit runner using it. Well, &lt;a href="https://bitbucket.org/farmas/qunit-webdriver-runner"&gt;here it is&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;How to use it?&lt;/h4&gt;Download and include it in your pom.xml (in this case I downloaded the .jar to the /lib folder of my project):&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml;"&gt;&amp;lt;dependency&amp;gt;&lt;br /&gt;    &amp;lt;groupId&amp;gt;org.farmas&amp;lt;/groupId&amp;gt;&lt;br /&gt;    &amp;lt;artifactId&amp;gt;qunit-webdriver-runner&amp;lt;/artifactId&amp;gt;&lt;br /&gt;    &amp;lt;version&amp;gt;0.1&amp;lt;/version&amp;gt;&lt;br /&gt;    &amp;lt;scope&amp;gt;system&amp;lt;/scope&amp;gt;&lt;br /&gt;    &amp;lt;systemPath&amp;gt;${project.basedir}/lib/qunit-webdriver-runner-0.1.jar&amp;lt;/systemPath&amp;gt;&lt;br /&gt;&amp;lt;/dependency&amp;gt;&lt;br /&gt;&amp;lt;dependency&amp;gt;&lt;br /&gt;    &amp;lt;groupId&amp;gt;com.atlassian.selenium&amp;lt;/groupId&amp;gt;&lt;br /&gt;    &amp;lt;artifactId&amp;gt;atlassian-pageobjects-elements&amp;lt;/artifactId&amp;gt;&lt;br /&gt;    &amp;lt;version&amp;gt;2.1.0-m8&amp;lt;/version&amp;gt;&lt;br /&gt;    &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;&lt;br /&gt;&amp;lt;/dependency&amp;gt;&lt;br /&gt;&amp;lt;dependency&amp;gt;&lt;br /&gt;    &amp;lt;groupId&amp;gt;org.mortbay.jetty&amp;lt;/groupId&amp;gt;&lt;br /&gt;    &amp;lt;artifactId&amp;gt;jetty&amp;lt;/artifactId&amp;gt;&lt;br /&gt;    &amp;lt;version&amp;gt;6.1.24&amp;lt;/version&amp;gt;&lt;br /&gt;    &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;&lt;br /&gt;&amp;lt;/dependency&amp;gt;&lt;/pre&gt;&lt;br /&gt;Then you can use the QunitWebDriver from your test (in this case I am using JUnit):&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java;"&gt;public class QunitTest {&lt;br /&gt;&lt;br /&gt;    public static QunitWebDriver driver;&lt;br /&gt;&lt;br /&gt;    @BeforeClass&lt;br /&gt;    public static void start() throws Exception&lt;br /&gt;    {&lt;br /&gt;        // these are the class loaders particular to my project&lt;br /&gt;        driver = QunitWebDriver.start(&lt;br /&gt;                        QunitTest.class.getClassLoader(), &lt;br /&gt;                        TagParser.class.getClassLoader()); &lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Test&lt;br /&gt;    public void test()&lt;br /&gt;    {&lt;br /&gt;        driver.runTest("/spec.htm");&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @AfterClass&lt;br /&gt;    public static void stopServer() throws Exception&lt;br /&gt;    {&lt;br /&gt;        driver.stop();&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;h4&gt;How does it work?&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;The module assumes that all your javascript, html and css files (product and test) are included as resources. &lt;/li&gt;&lt;li&gt;At the beginning of your test, start a QunitWebDriver passing the class loaders that are capable of locating all your resources. &lt;/li&gt;&lt;li&gt;QunitWebDriver will start a local webserver (using Jetty) that can serve requests from the resource files. &lt;/li&gt;&lt;li&gt;QunitWebDriver will then download, configure and start an instance of FireFox browser using WebDriver. &lt;/li&gt;&lt;li&gt;Lastly, you call QunitWebDriver.runTest() passing the html page that will load qunit and run your tests. &lt;/li&gt;&lt;li&gt;QunitWebDriver checks the UI of the page to verify that no test has failed.&lt;/li&gt;&lt;/ul&gt;&lt;a href="http://lh4.ggpht.com/-D10M9Lc5Oa4/Tr7wfqBP_AI/AAAAAAAAARA/A6Uh74eAOjQ/s1600-h/blogpost%25255B4%25255D.png"&gt;&lt;img alt="blogpost" border="0" height="484" src="http://lh3.ggpht.com/-0-3fEJU9UVQ/Tr7wguCq8uI/AAAAAAAAARE/of0Qnys2sDo/blogpost_thumb%25255B2%25255D.png?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="blogpost" width="583" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;atlassian-pageobjects-elements?&lt;/h4&gt;You might be wondering what’s up with this dependency. This is the Atlassian WebDriver PageObject library, another project that I worked on at Atlassian. One of the things I get for free by using it is auto-download and configuration of browsers which was very useful to get this thing going quickly&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Watch it live&lt;/h4&gt;&lt;div class="wlWriterEditableSmartContent" id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:c5485259-8024-43d5-996c-3cce4aa6e27a" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div&gt;&lt;object data="http://content.screencast.com/users/farmas/folders/Jing/media/f05b894e-5fb6-4060-a4ed-165d907161a1/jingswfplayer.swf" height="1008" id="scPlayer" type="application/x-shockwave-flash" width="951"&gt; &lt;param name="movie" value="http://content.screencast.com/users/farmas/folders/Jing/media/f05b894e-5fb6-4060-a4ed-165d907161a1/jingswfplayer.swf" /&gt; &lt;param name="quality" value="high" /&gt; &lt;param name="bgcolor" value="#FFFFFF" /&gt; &lt;param name="flashVars" value="thumb=http://content.screencast.com/users/farmas/folders/Jing/media/f05b894e-5fb6-4060-a4ed-165d907161a1/FirstFrame.jpg&amp;amp;containerwidth=951&amp;amp;containerheight=1008&amp;amp;content=http://content.screencast.com/users/farmas/folders/Jing/media/f05b894e-5fb6-4060-a4ed-165d907161a1/qunit-webdriver-runner.swf&amp;amp;blurover=false" /&gt; &lt;param name="allowFullScreen" value="true" /&gt; &lt;param name="scale" value="showall" /&gt; &lt;param name="allowScriptAccess" value="always" /&gt; &lt;param name="base" value="http://content.screencast.com/users/farmas/folders/Jing/media/f05b894e-5fb6-4060-a4ed-165d907161a1/" /&gt; Unable to display content. Adobe Flash is required.&lt;/object&gt;&lt;/div&gt;&lt;div style="clear: both; font-size: .8em; width: 951px;"&gt;qunit-webdriver-runner&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;- Federico&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-5792739138471878688?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/5792739138471878688/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2011/11/simple-webdriver-runner-for-qunit.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/5792739138471878688'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/5792739138471878688'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2011/11/simple-webdriver-runner-for-qunit.html' title='A simple WebDriver runner for QUnit'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/-0-3fEJU9UVQ/Tr7wguCq8uI/AAAAAAAAARE/of0Qnys2sDo/s72-c/blogpost_thumb%25255B2%25255D.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-3311788997671236671</id><published>2011-11-07T02:58:00.001-08:00</published><updated>2011-11-18T14:32:19.266-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Testing'/><title type='text'>What are they “really” asking?</title><content type='html'>My previous manager taught me an important principle for navigating the work place: whenever somebody asks a question, think about what they are &lt;em&gt;really &lt;/em&gt;asking. This came to mind because I recently moved to a new team full-time at work and one of the ceremonies that they have is a weekly status/progress/management type of meeting where I get asked this question:&lt;br /&gt;&lt;br /&gt;“What is the feeling from QA?” [this from product manager regarding the project that we are working on]&lt;br /&gt;&lt;br /&gt;I normally create a quality report that tells the story of the product state, but in these meetings nobody cared about any of that. I was asked for a some form of statement. My first reaction to these types of ambiguous questions is to feel the heat of being put on the spot and quickly attempt to synthesize the vast testing space into a judgment in seconds. This valiant effort is quickly followed by confusion as my mind races to evaluate the thousands of ways that I can tackle the answer.&lt;br /&gt;&lt;br /&gt;My natural solution at this stage is to simplify the terms of the problem by asking clarification of what the person means. Is there something specific that they want me to focus on? Naming examples of what I can elaborate on helps. However, what I discovered is that most product managers are as confused as I am and don’t really know what they are after with these questions!&lt;br /&gt;&lt;br /&gt;This triggers my third response: suspicion. Are they just asking for the sake of asking? Are they really going to do anything with this information? This bias comes from years of cases where no matter what is the assessment of QA, the plan remains unchanged, leaving the suspicion that the decision has already been made and voicing my opinion is just a formality.&lt;br /&gt;&lt;br /&gt;On good days, serenity brings me to my final reaction: humbleness. Product managers have a very difficult job, they never have complete information and have to balance many things to make a responsible call. Most of the times all they have to go with is their emotional reaction to something I say. That’s a tough position.&lt;br /&gt;&lt;br /&gt;What I do now is make sure that I can always summarize my test report into these 3 parts: a) top two important issues that are active, b) top test activity that we have not done yet, and c) top test activity that we have had to cut. Don’t fret too much, in my experience, product managers have a difficult time reacting to these (unless the risks are emotionally charged). Instead, the most important part is that I follow these statements by asking the product manager if there is anything else he/she wants to know. I think that this helps form clarity of what is important in the eyes of the manager. Remember that they are the ones that are going to make the ship/no-ship decision at the end and the more I can help this person be aware and articulate what information he/she feels is important the better. Make sure to address these in the written test report that you send later (where it can be read in calmness).&lt;br /&gt;&lt;br /&gt;Lastly, I never do the job for them. I do not answer questions related to ship-readiness, if we’ll be able to ship on time or if we should block the release. This is the product manager’s job (or if not them, someone higher up). If he/she wants my opinion I’ll be happy to give it over a cup of coffee. I like lattes.&lt;br /&gt;&lt;br /&gt;- Federico&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-3311788997671236671?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/3311788997671236671/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2011/11/what-are-they-really-asking.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/3311788997671236671'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/3311788997671236671'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2011/11/what-are-they-really-asking.html' title='What are they “really” asking?'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-2956222574798929016</id><published>2011-09-24T21:06:00.001-07:00</published><updated>2011-11-18T14:34:09.898-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Development'/><title type='text'>Learn Spanish while I learn Backbone.js</title><content type='html'>My sister is a bilingual teacher in the US and after seeing all the cool work books and educational software that exist for children to learn English, she decided to create something similar for Spanish. After designing some of the exercises, she asked me if I could create a program so that children could practice.&lt;br /&gt;&lt;br /&gt;I decided it would be a good opportunity to learn &lt;a href="http://documentcloud.github.com/backbone/"&gt;Backbone.js&lt;/a&gt;.&amp;nbsp;After watching some tutorials and screen casts I jumped in. I had to rewrite it two times because I got stuck and I feel like I am still learning it, but I thought I’d share it anyway. &lt;br /&gt;&lt;br /&gt;Head over to &lt;a href="http://leomejor.apphb.com/"&gt;LeoMejor.apphb.com&lt;/a&gt; to try it out and learn some Spanish in the process!&lt;br /&gt;&lt;br /&gt;If you are interested, head over to the &lt;a href="https://bitbucket.org/farmas/leomejor"&gt;BitBucket project&lt;/a&gt; to checkout the source. (Be mindful that all the art is my sister’s, if you want to use any of it please let me know.)&lt;br /&gt;&lt;br /&gt;I’ll follow this up with a write up about my experience with Backbone and some pitfalls that I fell into. &lt;br /&gt;&lt;br /&gt;- Federico&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-2956222574798929016?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/2956222574798929016/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2011/09/learn-spanish-while-i-learn-backbonejs.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/2956222574798929016'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/2956222574798929016'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2011/09/learn-spanish-while-i-learn-backbonejs.html' title='Learn Spanish while I learn Backbone.js'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-1285460839526678903</id><published>2011-08-27T21:53:00.001-07:00</published><updated>2011-11-18T14:37:50.864-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Development'/><category scheme='http://www.blogger.com/atom/ns#' term='Testing'/><title type='text'>My promise as a (future) developer</title><content type='html'>With slightly different choices, in a different life I could have been a developer. In fact, I am somewhat convinced that in my next gig, I’ll shoot for becoming a developer with a strong test mentality.&lt;br /&gt;&lt;br /&gt;If and when that happens, I might land on a team where there are dedicated QA folks, and in such an event I want to promise something to any tester that happens to work with me. That’s right, I am talking to you tester, the one who is going to help me create awesome features. This post is dedicated to you:&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;1.&lt;/strong&gt; I promise to ping you, send you an IM or shout at you when my fellow programmers and I are having a discussion about the design of a feature that you are going to test. I will constantly use this phrase: “Could you guys hold on a minute, I am going to grab our tester, he/she needs to be here”. If you are not there, I will do my best to bring you up-to-speed with any decisions made.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;2.&lt;/strong&gt; I promise that when I think I have a first implementation done, I will go grab you and walk through the code and modules with you, including automated tests. I will ask for some of your time to brainstorm additional test scenarios that we should take into account. I will welcome your feedback.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;3.&lt;/strong&gt; I promise to include you in any code reviews that I create.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;4.&lt;/strong&gt; I promise to sit with you and make sure that you know how to build and install latest versions of the product, as well as how to setup a debugging environment and run any automated tests.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;5.&lt;/strong&gt; I promise to sit with you and create a test mission plan for our feature and divide the exploration between us. I understand that sometimes you will be overwhelmed with other work, and in this case I promise to do my best and create the test missions and run exploratory sessions on my own (despite my obvious bias). I will keep test notes of what I have tried, any assumptions that I have made and areas where I am unsure about some implementation.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;6.&lt;/strong&gt; I promise that whenever I resolve a bug I will include detailed explanation of what was the problem as well as how I fixed it. I will include notes of what I did to verify my changes including manual tests performed.&lt;br /&gt;&lt;br /&gt;If I ever do make the jump, and you feel I am not treating you this way, please print this blog post and bring it to me and shove it in my face.&lt;br /&gt;&lt;br /&gt;- Federico&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-1285460839526678903?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/1285460839526678903/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2011/08/my-promise-as-future-developer.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/1285460839526678903'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/1285460839526678903'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2011/08/my-promise-as-future-developer.html' title='My promise as a (future) developer'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-2522817103404104333</id><published>2011-08-15T01:23:00.001-07:00</published><updated>2011-11-18T14:41:00.508-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Development'/><category scheme='http://www.blogger.com/atom/ns#' term='Random Tales'/><title type='text'>Mother nature always wins</title><content type='html'>This weekend I spent some time viewing Paul Irish’s &lt;a href="http://paulirish.com/2010/10-things-i-learned-from-the-jquery-source/"&gt;10 Things I Learned from the JQuery Source&lt;/a&gt; and its follow up. I was amazed at some of the code patterns that Paul shows and at one point the wife (who I will call “La Jefa”) popped up her head from behind her computer as I exclaimed “Whoa!” when I saw a particular piece of code.&lt;br /&gt;&lt;br /&gt;When asked what was so amazing, I pointed at the screen, burping out some incoherency in the lines of: “look how this crazy guy coded up that stuff”. &lt;br /&gt;&lt;br /&gt;She turned to me and said, “You want to look at something REALLY amazing?” And she turned her laptop to show me this:&lt;br /&gt;&lt;div class="wlWriterEditableSmartContent" id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:0963a082-35b3-446c-8adf-d3df2ef46bc2" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div&gt;&lt;embed allowfullscreen="true" height="334" src="http://www.sciencefriday.com/embed/video/10397.swf" width="560"&gt;&lt;/embed&gt;&lt;/div&gt;&lt;div style="clear: both; font-size: .8em; width: 560px;"&gt;Where’s the Octopus?&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;No matter how amazing the pieces of software we create are, a look at this puts things into perspective.&lt;br /&gt;&lt;br /&gt;- Federico&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-2522817103404104333?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/2522817103404104333/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2011/08/mother-nature-always-wins.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/2522817103404104333'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/2522817103404104333'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2011/08/mother-nature-always-wins.html' title='Mother nature always wins'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-7559915855035005297</id><published>2011-07-31T04:53:00.001-07:00</published><updated>2011-11-18T15:00:29.639-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Testing'/><title type='text'>Tester as an identity, have we gone too far? – Part 2</title><content type='html'>&lt;h3&gt;Summary&lt;/h3&gt;&lt;br /&gt;The need to maintain the tester’s identity is preventing us from investing in testing skills for other team members, especially programmers. In this series of blog posts, I will focus on this simple idea and how a development team might benefit from taking responsibility of more test approaches than just automation.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.federicosilva.net/2011/07/tester-as-identity-have-we-gone-too-far.html"&gt;Part 1: Rise of the Tester Identity&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Part 2: A world divided, but collaborating&lt;/h3&gt;&lt;br /&gt;Regardless of how and why, the fact is that internal test organizations exist and they are usually separate from programmers. The focus of managers and leaders then is to figure out a way to have these two groups collaborate with each other, with the assumption that each brings a different but equally important skill to the table, which if balanced correctly can produce better software.&lt;br /&gt;&lt;br /&gt;The point here is to be aware and accept that organizations spend time creating processes to satisfy two conditions: keep testers as a separate group to programmers, and keep the two groups working together as a unit. This is a noble cause, and it plays to our desires of “team work” and “better together”. I don’t doubt that there are organizations that have been able to create a co-habitat that produces good results for them, however, we should not lose track of the risks. &lt;br /&gt;&lt;br /&gt;What follows are some examples of how testers and programmers interact with each other that can be problematic. Note: I like to over simplify and show the behavior at its extreme, perhaps you would be able to identify a grain of truth in real organizations.&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Creator - Destroyer&lt;/h3&gt;&lt;br /&gt;The basis of this setup is to have each group apply force at opposite sides which hopefully results in healthy compromise. The groups are kept separate by focusing on different software dimensions. Programmers are encouraged and motivated to write as many features as possible, testers are encouraged and motivated to break the software by any means possible.&lt;br /&gt;&lt;br /&gt;I have heard this mentality put into words when describing the roles of these groups. For example: “Programmers have a creative mentality, testers have a destructive mentality” and the more ingenious “Programmers try to put as much code and features out; testers try to stop them by showing how buggy they are.”&lt;br /&gt;&lt;br /&gt;The risk of this approach is that the groups may to become too polarized. A group might be pushing too hard that over-powers the other or a group might start caring more about “winning” the battle against the other group than delivering value to customers. Actually, one symptom of this arrangement is when people start talking about “winning fights” against developers over some bug.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Creator - Verifier&lt;/h3&gt;&lt;br /&gt;Collaboration in this model has testers functioning as a checker for programmer’s work. The programmer claims that he/she is done and passes the work for a tester to verify that the claims are true and that the requirements are met. Bugs are mistakes the developer commits over a known space of functionality.&lt;br /&gt;&lt;br /&gt;This setup tends to be more harmonious than the polarizing structure, the tester is merely checking that the software does what it's supposed to do. The down-side is that it devalues the work of testing as a non-skilled activity. Programmers do not include testers in any design activity and testers feel unappreciated.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Creator - Investigator&lt;/h3&gt;&lt;br /&gt;This model of collaboration rests on the assumption that the tester will question the unwritten requirements--all assumptions made by programmers are fair game to be evaluated against their impact to customers. Testers are free to use whatever approach best fits the context of the project and provide an assessment to the project owners over more dimensions than just “defects”.&lt;br /&gt;&lt;br /&gt;In my opinion, this is one of the healthier models of collaboration, the skills of the tester are recognized and the team is thankful for the increase in awareness that the tester’s findings bring to attention. Besides the difficulty of implementing this structure, the risk is that programmers can begin to take design less seriously, because the tester is there to work out all the details of the impact of the current implementation.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Creator - Gate Keeper&lt;/h3&gt;&lt;br /&gt;Under this model, testers have veto power. If they are so intimately aware of the state of the product and not under the direct reporting structure as programmers, they have the most objective perspective and are best capable to decide whether the project is ready to be released or not. &lt;br /&gt;&lt;br /&gt;At its best, it gives testers a way to have equal say in the decision to release software and “stand up for quality” if the need arises. At its worst, it turns into law enforcement where testers refuse to sign off on a release until they are satisfied with the quality.&lt;br /&gt;&lt;br /&gt;In my opinion, this is a facade of the intentional polarized groups presented above. Its implications are mostly negative: apparently programmers would run wild releasing bad software because there would be no one to stop them and programmers are simply not good at effectively considering other dimensions of software.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Other Possibilities&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;What these collaboration strategies have in common is the belief that there must be two groups. It’s almost a requirement and we invest time and effort on creating processes, team visions, role descriptions and training so that these two groups of people learn how to work well together. &lt;br /&gt;&lt;br /&gt;I believe that two things are happening here: a) the testers identity as a profession demands that it holds a place of value, and b) too little credit is given to programmers, the assumption is that they lack testing skills and don't care to learn them.&lt;br /&gt;&lt;br /&gt;So what are we to do? Destroy the test team and move the testing responsibility to the programmers? Isn’t that what we mean by “moving quality upstream” after all?&lt;br /&gt;&lt;br /&gt;Not necessarily. Stay tuned.&lt;br /&gt;&lt;br /&gt;- Federico&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-7559915855035005297?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/7559915855035005297/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2011/07/tester-as-identity-have-we-gone-too-far_31.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/7559915855035005297'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/7559915855035005297'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2011/07/tester-as-identity-have-we-gone-too-far_31.html' title='Tester as an identity, have we gone too far? – Part 2'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-7023118475971293546</id><published>2011-07-31T03:42:00.001-07:00</published><updated>2011-07-31T03:42:14.700-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Testing'/><title type='text'>CAST 2011 keynotes on UStream.TV</title><content type='html'>&lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;For those of you that, like me, won’t be attending CAST 2011 but still want in some of the action. The keynotes and the “Emerging Topics” tack will be streamed like on UStream . August 8th and 9th.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;UStream&lt;/strong&gt;: &lt;a href="http://ustream.com/channel/CASTLive"&gt;http://ustream.com/channel/CASTLive&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Don’t miss it!&lt;/p&gt; &lt;p&gt;- Federico&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-7023118475971293546?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/7023118475971293546/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2011/07/cast-2011-keynotes-on-ustreamtv.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/7023118475971293546'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/7023118475971293546'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2011/07/cast-2011-keynotes-on-ustreamtv.html' title='CAST 2011 keynotes on UStream.TV'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-4339012182201849064</id><published>2011-07-16T21:46:00.001-07:00</published><updated>2011-07-16T21:46:57.584-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Testing'/><title type='text'>Tester as an identity, have we gone too far? – Part 1</title><content type='html'>&lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h4&gt;Summary&lt;/h4&gt; &lt;p&gt;The need to maintain the tester’s identity is preventing us from investing in testing skills for other team members, specially programmers. In this series of blog posts I focus on this simple idea and how a development team might benefit from taking responsibility of more test approaches than just automation. &lt;p&gt;&amp;nbsp; &lt;h4&gt;Rise of the Tester Identity&lt;/h4&gt; &lt;p&gt;I am too young to know how it started. It’s a bit like the Big Bang really, we all have theories about how it all began, but nobody actually knows. My guess is that at some point, really smart persons realized that software was too complex that they might benefit from double checking if the thing worked before they sold it. For good conscience sake.&lt;/p&gt; &lt;p&gt;&lt;br&gt;Then I suspect people realized that making sure that things work was boring, hard and time consuming (depending on who you asked). Some bright fellow had the idea, “Hey, let’s pay somebody to do it” And BAM! The dedicated tester came into being.&lt;/p&gt; &lt;p&gt;&lt;br&gt;From the beginning I think the tester was born into a world of struggle. I can imagine that when presented with this new person, programmer’s reactions fell into one of these:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;“They are useless, we write perfect code!” &lt;li&gt;“They are dumb, they don’t know as much as we do.” &lt;li&gt;“They are slaves, go do the things that we dislike.” &lt;li&gt;“They are evil, they just make us look bad.” &lt;li&gt;“They are a necessary evil, we ship better software thanks to them” &lt;li&gt;“They are ok, but without us there would be no business, so don’t get ideas into your head.” &lt;li&gt;“Who are these guys again? What do they do? I am confused”&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&lt;br&gt;Fortunately, there was a bit of a Renaissance, testers united and created our own national identity. We weren’t completely on our own, companies (for reasons that I won’t go into) promoted the rise of the tester as a separate identity. There were great luminaries and thought leaders that defined, and continue to define, the role of a tester in the development process.&lt;/p&gt; &lt;p&gt;&lt;br&gt;I believe that, in some part, the testing discipline needed to justify its existence. And so we created our membership group which has the side effect of creating an out-group of pretty much everyone else. This is not without merit, there are differences between a “tester” and a “non-tester” as well as concrete skills like any other profession. But the creation of a group of specialization is arbitrary. Some companies make a distinction between “developer” and “front-end developer”, others have a different set of specialized groups. Testers are no different, we exist because organizations feel that a separate specialized group is needed to best fills its needs.&lt;/p&gt; &lt;p&gt;&lt;br&gt;Over time, testers developed a very strong pride in their own identity. It is a group that is constantly reasserting its existence, like most other groups really, “developers” being a possible exception. There is a lot invested in the continued presence of this group, for example: the livelihood of many persons, whole test organizations, test managers and architects, conferences specifically tailored for testers, products for testers, plenty of books and even some certifications.&lt;/p&gt; &lt;p&gt;&lt;br&gt;All this yells at me: “we are testers and this is how we are different from the rest of the team”.&lt;br&gt;&lt;/p&gt; &lt;p&gt;Now, I work as a tester. I have been a tester for 9 years, but I ask myself, what if instead of focusing on promoting a separate testing identity, we focus on transferring our unique skills to our cousins the programmers?&lt;/p&gt; &lt;p&gt;&lt;br&gt;That is the basis of this series of blog posts. And I should remind you, dear reader, that these are just theories, all I have in terms of evidence is observation and experience having worked as a QA member in three teams at Microsoft and three teams at Atlassian. However, I do have a plan to experiment with this approach on my current team that I will share on this medium.&lt;/p&gt; &lt;p&gt;- Federico&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-4339012182201849064?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/4339012182201849064/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2011/07/tester-as-identity-have-we-gone-too-far.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/4339012182201849064'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/4339012182201849064'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2011/07/tester-as-identity-have-we-gone-too-far.html' title='Tester as an identity, have we gone too far? – Part 1'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-6315583613578523531</id><published>2011-07-04T03:44:00.001-07:00</published><updated>2011-07-04T03:44:05.288-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Random Tales'/><title type='text'>Once upon a time…</title><content type='html'>&lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;This link was shared on the internal QA chat today: &lt;a title="ftp://dc1.dawsoncollege.qc.ca/VSHelp/SAMPLES/VC98/SDK/WINUI/COMCTL/REITP/REITP.C" href="ftp://dc1.dawsoncollege.qc.ca/VSHelp/SAMPLES/VC98/SDK/WINUI/COMCTL/REITP/REITP.C"&gt;ftp://dc1.dawsoncollege.qc.ca/VSHelp/SAMPLES/VC98/SDK/WINUI/COMCTL/REITP/REITP.C&lt;/a&gt;&lt;/p&gt; &lt;p&gt;I don’t know where the source code comes from, or if its even real. But there is a part that was funny, I copy it here:&lt;/p&gt; &lt;p&gt;static TCHAR szText[] = "Once upon a time there was an edit control.&amp;nbsp; "&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "This was a happy edit control until some mean evil tester "&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "(who shall remain nameless) came along and started beating on "&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "the poor little helpless edit control.&amp;nbsp; The edit control bravely "&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "faced it's unprovoked attacker, but an edit control can only take "&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "so much.&amp;nbsp; One day when it was being ferociously tortured it thought "&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "to itself \"What have I ever done to this poor homely creature to "&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "deserve this type of punishment?\".&amp;nbsp; It stirred up it's self esteem "&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "and stood up and said to the nasty creature \"I am an edit control, "&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "hear me roar!&amp;nbsp; I deserve to be treated with dignity and respect!\".&amp;nbsp; "&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "The evil little tester was taken aback by the edit control's sudden "&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "show of courage, but being the spawn of hell, he dismissed the edit "&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "control's declaration and continued his ghastly attacks.&amp;nbsp; The edit "&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "control decided that nothing would ever reform this hideous beast "&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "imparting terror upon it so he decided to do something about it.&amp;nbsp; "&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "The next day when the heathen was preparing to nuke the edit control "&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "the edit control jumped out at the beast and ripped it's heart out.&amp;nbsp; "&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "The tester stood shocked for a millisecond and then dropped over dead.&amp;nbsp; "&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "The end.\r\n\r\n";&lt;/p&gt; &lt;p&gt;Have a good testing week!&lt;/p&gt; &lt;p&gt;- Federico&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-6315583613578523531?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/6315583613578523531/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2011/07/once-upon-time.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/6315583613578523531'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/6315583613578523531'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2011/07/once-upon-time.html' title='Once upon a time…'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-998352192012719448</id><published>2011-06-11T02:48:00.001-07:00</published><updated>2011-06-11T02:50:06.706-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Development'/><title type='text'>Atlassian .NET SDK</title><content type='html'>&lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Shortly after I joined, I participated on my first &lt;a href="http://confluence.atlassian.com/display/DEV/Atlassian+FedEx+Days"&gt;Fedex&lt;/a&gt; &lt;a href="http://www.atlassian.com/tv/episode?id=mb9r5rzmd2j4&amp;amp;product=ide"&gt;Day&lt;/a&gt; at Atlassian. This is 36 hour coding competition, where everyone in the Engineering team puts together something cool (usually with a high density of hacks) related to our products and Atlassian. There are semi-finals, finals, a big trophy and bragging rights involved.&lt;/p&gt; &lt;p&gt;My project was to build a LINQ provider for JIRA. I got like 6 votes in the first round, but it wasn’t enough to go forward on the road to fame and glory. However, it gave me a fun project to work on my 20% time in .NET in an almost 100% Java shop. &lt;/p&gt; &lt;p&gt;WIth only 173 downloads so far, the library has a tiny mini niche of users, but I have enjoyed learning about query expression trees.&lt;/p&gt; &lt;p&gt;The source is available in bitbucket: &lt;a title="https://bitbucket.org/farmas/atlassian.net-sdk" href="https://bitbucket.org/farmas/atlassian.net-sdk"&gt;https://bitbucket.org/farmas/atlassian.net-sdk&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Example:&lt;/p&gt;&lt;pre class="csharpcode"&gt;var issues = from i &lt;span class="kwrd"&gt;in&lt;/span&gt; jira.Issues&lt;br /&gt;              &lt;span class="kwrd"&gt;where&lt;/span&gt; i.Assignee == &lt;span class="str"&gt;"admin"&lt;/span&gt; &amp;amp;&amp;amp; i.Priority == &lt;span class="str"&gt;"Major"&lt;/span&gt;&lt;br /&gt;              orderby i.Created&lt;br /&gt;              select i;&lt;/pre&gt;&lt;br /&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, "Courier New", courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;br /&gt;&lt;/style&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;- Federico&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-998352192012719448?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/998352192012719448/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2011/06/atlassian-net-sdk.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/998352192012719448'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/998352192012719448'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2011/06/atlassian-net-sdk.html' title='Atlassian .NET SDK'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-2371778820499732358</id><published>2011-05-21T16:21:00.001-07:00</published><updated>2011-05-21T16:21:27.770-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Announcements'/><title type='text'>Speaking at Monash University in Victoria, Australia</title><content type='html'>&lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Next week I’ll be flying to &lt;a href="http://www.monash.edu.au/"&gt;Monash University&lt;/a&gt; to give a couple of talks about testing. This is the first time that the University offers a testing class and Dr. Yuang-Fang Li, who is in charge of the unit, invited me as a guest lecturer.&lt;/p&gt; &lt;p&gt;I am looking forward to visit the University and meet the students.&lt;/p&gt; &lt;p&gt;- Federico&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-2371778820499732358?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/2371778820499732358/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2011/05/speaking-at-monash-university-in.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/2371778820499732358'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/2371778820499732358'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2011/05/speaking-at-monash-university-in.html' title='Speaking at Monash University in Victoria, Australia'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-4618544284208080555</id><published>2011-05-18T01:56:00.001-07:00</published><updated>2011-05-18T01:56:53.431-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tips and Tricks'/><title type='text'>Learning Javascript with Douglas Crockford</title><content type='html'>&lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;This set of videos by Douglas Crockford was originally shared by &lt;a href="http://twitter.com/#!/damianedwards"&gt;Damian Edwards&lt;/a&gt;. I recently re-watched them on &lt;a href="http://developer.yahoo.com/yui/theater/"&gt;YUI Theater&lt;/a&gt; and had forgotten how packed with good info they are. Good resource to keep around:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;a href="http://video.yahoo.com/video/play?vid=630959"&gt;JavaScript: The Good Parts&lt;/a&gt; (&lt;a href="http://yui.zenfs.com/theater/crockford-goodstuff.m4v"&gt;download&lt;/a&gt;)  &lt;li&gt;The JavaScript Programming Language  &lt;ol&gt; &lt;li&gt;&lt;a href="http://video.yahoo.com/video/play?vid=111593"&gt;Part 1&lt;/a&gt; (&lt;a href="http://yui.zenfs.com/theater/crockford-tjpl-1.m4v"&gt;download&lt;/a&gt;)  &lt;li&gt;&lt;a href="http://video.yahoo.com/video/play?vid=111594"&gt;Part 2&lt;/a&gt; (&lt;a href="http://yui.zenfs.com/theater/crockford-tjpl-2.m4v"&gt;download&lt;/a&gt;)  &lt;li&gt;&lt;a href="http://video.yahoo.com/video/play?vid=111595"&gt;Part 3&lt;/a&gt; (&lt;a href="http://yui.zenfs.com/theater/crockford-tjpl-3.m4v"&gt;download&lt;/a&gt;)  &lt;li&gt;&lt;a href="http://video.yahoo.com/video/play?vid=111596"&gt;Part 4&lt;/a&gt; (&lt;a href="http://yui.zenfs.com/theater/crockford-tjpl-4.m4v"&gt;download&lt;/a&gt;)&lt;/li&gt;&lt;/ol&gt; &lt;li&gt;Advanced JavaScript  &lt;ol&gt; &lt;li&gt;&lt;a href="http://video.yahoo.com/video/play?vid=111585"&gt;Part 1&lt;/a&gt; (&lt;a href="http://yui.zenfs.com/theater/crockford-advancedjavascript-1.m4v"&gt;download&lt;/a&gt;)  &lt;li&gt;&lt;a href="http://video.yahoo.com/video/play?vid=111586"&gt;Part 2&lt;/a&gt; (&lt;a href="http://yui.zenfs.com/theater/crockford-advancedjavascript-2.m4v"&gt;download&lt;/a&gt;)  &lt;li&gt;&lt;a href="http://video.yahoo.com/video/play?vid=111587"&gt;Part 3&lt;/a&gt; (&lt;a href="http://yui.zenfs.com/theater/crockford-advancedjavascript-3.m4v"&gt;download&lt;/a&gt;)&lt;/li&gt;&lt;/ol&gt; &lt;li&gt;An Inconvenient API: The Theory of the DOM  &lt;ol&gt; &lt;li&gt;&lt;a href="http://video.yahoo.com/video/play?vid=111582"&gt;Part 1&lt;/a&gt; (&lt;a href="http://yui.zenfs.com/theater/crockford-domtheory-1.m4v"&gt;download&lt;/a&gt;)  &lt;li&gt;&lt;a href="http://video.yahoo.com/video/play?vid=111583"&gt;Part 2&lt;/a&gt; (&lt;a href="http://yui.zenfs.com/theater/crockford-domtheory-2.m4v"&gt;download&lt;/a&gt;)  &lt;li&gt;&lt;a href="http://video.yahoo.com/video/play?vid=111584"&gt;Part 3&lt;/a&gt; (&lt;a href="http://yui.zenfs.com/theater/crockford-domtheory-3.m4v"&gt;download&lt;/a&gt;)&lt;/li&gt;&lt;/ol&gt; &lt;li&gt;&lt;a href="http://developer.yahoo.com/yui/theater/video.php?v=crockford-yuiconf2009-state"&gt;The State and Future of JavaScript&lt;/a&gt; (&lt;a href="http://yuiblog.com/yuitheater/crockford-yuiconf2009-state.m4v"&gt;download&lt;/a&gt;)  &lt;li&gt;Crockford on JavaScript  &lt;ol&gt; &lt;li&gt;&lt;a href="http://developer.yahoo.com/yui/theater/video.php?v=crockonjs-1"&gt;Volume 1: The Early Years&lt;/a&gt; (&lt;a href="http://yui.zenfs.com/theater/crockonjs-1.m4v"&gt;download&lt;/a&gt;)  &lt;li&gt;&lt;a href="http://developer.yahoo.com/yui/theater/video.php?v=crockonjs-2"&gt;Chapter 2: And Then There Was JavaScript&lt;/a&gt; (&lt;a href="http://yui.zenfs.com/theater/crockonjs-2.m4v"&gt;download&lt;/a&gt;)  &lt;li&gt;&lt;a href="http://developer.yahoo.com/yui/theater/video.php?v=crockonjs-3"&gt;Act III: Function the Ultimate&lt;/a&gt; (&lt;a href="http://yui.zenfs.com/theater/crockonjs-3.m4v"&gt;download&lt;/a&gt;)  &lt;li&gt;&lt;a href="http://developer.yahoo.com/yui/theater/video.php?v=crockonjs-4"&gt;Episode IV: The Metamorphosis of Ajax&lt;/a&gt; (&lt;a href="http://yui.zenfs.com/theater/crockonjs-4.m4v"&gt;download&lt;/a&gt;)  &lt;li&gt;&lt;a href="http://developer.yahoo.com/yui/theater/video.php?v=crockonjs-5"&gt;Part 5: The End of All Things&lt;/a&gt; (&lt;a href="http://yui.zenfs.com/theater/crockonjs-5.m4v"&gt;download&lt;/a&gt;)  &lt;li&gt;&lt;a href="http://developer.yahoo.com/yui/theater/video.php?v=crockford-loopage"&gt;Scene 6: Loopage&lt;/a&gt; (&lt;a href="http://yui.zenfs.com/theater/crockford-loopage.m4v"&gt;download&lt;/a&gt;)&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;Good idea to get &lt;a href="http://www.amazon.com/JavaScript-Good-Parts-Douglas-Crockford/dp/0596517742/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1284658378&amp;amp;sr=8-1"&gt;his book&lt;/a&gt; too. &lt;p&gt;- Federico&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-4618544284208080555?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/4618544284208080555/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2011/05/learning-javascript-with-douglas.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/4618544284208080555'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/4618544284208080555'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2011/05/learning-javascript-with-douglas.html' title='Learning Javascript with Douglas Crockford'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-9044059044516951820</id><published>2011-01-08T19:37:00.001-08:00</published><updated>2011-01-08T19:37:12.582-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Random Tales'/><title type='text'>Parallel Universes</title><content type='html'>&lt;p&gt;&lt;em&gt;Note: This is a refurbished old blog post I found on my laptop.&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Many months back (while I was at Microsoft) I had a conversation with a Dev on my team that went like this:&lt;/p&gt; &lt;p&gt;Me: “All right, let me write the regression test and I can include it in our next test pass”. &lt;br&gt;Dev: “Perfect, so I’ll see results tomorrow?” &lt;br&gt;Me: “Well no, the next test pass is until next week” &lt;br&gt;Dev: “You mean you don’t run all tests every day?”&lt;/p&gt; &lt;p&gt;This simple conversation started a deluge of reality shocks between us. It turned out the majority of the Dev team had no clue how any of our processes worked. Among the mysteries where:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;No understanding of what tests we ran.  &lt;li&gt;No understanding of how we run tests.  &lt;li&gt;No understanding of what tools we used to run tests.  &lt;li&gt;No understanding of platforms or configurations.  &lt;li&gt;The belief that we just “pushed a button” and all tests where done. (I love this one, because I hear it very often from higher up managers). &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Here we were, on the same team working on the same product in close proximity with each other. Yet, most of what the test team did was a complete mystery to the Dev team. It was interesting to see this total disconnect between our activities, I called it “The Abyss”. There are many reasons why our team worked in this way. One could argue that this was a side effect of specialization, having different groups of persons focus on different things will create area expertise that is unreasonable to share with everyone. But in the case of software development, working like this made us loose the following strengths:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;&lt;em&gt;Cooperation&lt;/em&gt;&lt;/strong&gt;: Having a basic understanding of the work of other team members (what’s hard, how they tackle problems) increases the chance members want to help each other.  &lt;li&gt;&lt;strong&gt;&lt;em&gt;Improve the process&lt;/em&gt;&lt;/strong&gt;: Having an understanding of the test process is the first step to attempt to change and improve it.  &lt;li&gt;&lt;strong&gt;&lt;em&gt;Learn from each other&lt;/em&gt;&lt;/strong&gt;: I like learning how a developer writes code, because it makes me a better software engineer, the more a developer learns how I test code would make him a better software engineer.  &lt;li&gt;&lt;strong&gt;&lt;em&gt;Quality assistance instead of quality assurance&lt;/em&gt;&lt;/strong&gt;: A test team’s existence should be to support the group build great products, a smart engineer would aim to understand how to leverage the test assets to make a better product. This is in contrast with quality assurance which has the developer treat the test team as a mere checker or verifier of his/her work. &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;We were taking steps to improve this state, but culture is very hard to change and at the point I left the team the bridge over the Abyss was still under construction.&lt;/p&gt; &lt;p&gt;Dear reader, does this story sound familiar to you? What’s the distance of awarenes in terms of tools and processes between your QA and Dev team? A gopher hole, a ditch, a canyon… an abyss?&lt;/p&gt; &lt;p&gt;- Federico&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-9044059044516951820?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/9044059044516951820/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2011/01/parallel-universes.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/9044059044516951820'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/9044059044516951820'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2011/01/parallel-universes.html' title='Parallel Universes'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-8758809613587926591</id><published>2010-11-15T02:27:00.000-08:00</published><updated>2010-11-16T02:27:12.474-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Announcements'/><title type='text'>New Horizons</title><content type='html'>&lt;p&gt;It’s been a while since my last post. After 8 years working on the ASP.NET team at Microsoft, the time came to move on to something else. I am excited to announce that I have recently relocated to Australia to work for Atlassian. This is a change that was long in the making, but I finally had my first day on my new job today.&lt;/p&gt; &lt;p&gt;I am really thankful for all my time at Microsoft and I will miss the team, but I look forward to the new challenges at Atlassian. The experience will be very different, here is an example:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;From USA to Australia.  &lt;li&gt;From .NET to Java.  &lt;li&gt;From VisualStudio to Eclipse.  &lt;li&gt;From Windows to whatever OS you want.  &lt;li&gt;From Office to Google Docs.  &lt;li&gt;From individual offices to open space.  &lt;li&gt;From individual phones to no phones.  &lt;li&gt;From thousands of employees to hundreds.  &lt;li&gt;From mainly closed source to open source.  &lt;li&gt;From internal bug database to public bug database.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;I look forward to do my part to craft a QA team that is effective on an agile environment. :-)&lt;/p&gt; &lt;p&gt;- Federico&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-8758809613587926591?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/8758809613587926591/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2010/11/new-horizons.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/8758809613587926591'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/8758809613587926591'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2010/11/new-horizons.html' title='New Horizons'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-3531683599236632272</id><published>2010-08-15T20:07:00.001-07:00</published><updated>2010-08-15T20:07:49.339-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Announcements'/><title type='text'>Testing Toasters</title><content type='html'>&lt;p&gt;Mark Berryman, a tester on my team that I have worked with for years, started his own blog recently! You can follow him here: &lt;/p&gt;  &lt;p&gt;&lt;a title="http://www.testingtoasters.com" href="http://www.testingtoasters.com"&gt;http://www.testingtoasters.com&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Nice to read his perspective on the ASP.NET team. Good posts Mark.&lt;/p&gt;  &lt;p&gt;- Federico&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-3531683599236632272?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/3531683599236632272/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2010/08/testing-toasters.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/3531683599236632272'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/3531683599236632272'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2010/08/testing-toasters.html' title='Testing Toasters'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-1962643009326108084</id><published>2010-06-20T18:00:00.001-07:00</published><updated>2010-06-20T18:00:10.392-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Random Tales'/><title type='text'>… or should I say, “I do testing”?</title><content type='html'>&lt;p&gt;I received a piece of Jedi wisdom from my friend Eduardo regarding my previous post: “It is incredible how we base the identity of a person on what we do.”&lt;/p&gt;  &lt;p&gt;I love talking with people that can put my ideas into perspective, and Eduardo does it in a very gentle way. Lately I’ve been so focused on testing, that is easy to loose track that this is just what I do for work.&lt;/p&gt;  &lt;p&gt;There was this exercise that Sallie was telling me about, where in some motivational conference they would ask people to identify themselves. I thought about it, and “I am a tester” won’t really appear on that description.&lt;/p&gt;  &lt;p&gt;A small point, but I thought necessary to bring up. If this post was totally obvious for you reader, no worries, move along, these aren’t the droids you are looking for. :P&lt;/p&gt;  &lt;p&gt;- Federico&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-1962643009326108084?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/1962643009326108084/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2010/06/or-should-i-say-i-do-testing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/1962643009326108084'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/1962643009326108084'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2010/06/or-should-i-say-i-do-testing.html' title='… or should I say, “I do testing”?'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-3782587102150410512</id><published>2010-06-13T18:46:00.001-07:00</published><updated>2011-05-18T02:00:36.366-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Random Tales'/><title type='text'>“I am a tester”</title><content type='html'>&lt;p&gt;A couple of weeks ago I followed Sallie to her 15th college reunion at Brown University. It was a very different experience than my graduation in Mexico (I still think that those togas that they wear here are kind of silly), but what I am here to talk to you, dear reader, is a personal realization that I made on this trip.&lt;/p&gt;  &lt;p&gt;I met a lot of people and inevitably, they would ask me what I do, and I would answer: &amp;quot;I am a tester&amp;quot;. So what, you may ask, after introspection I noted that I know enough about my discipline as a highly skilled profession that I feel proud of telling it as it is.&lt;/p&gt;  &lt;p&gt;I remember when I first started at Microsoft, 8 years ago, I was prejudiced and was interested in making it clear that I wasn't just a button clicker. When people asked I used to say &amp;quot;I am a Software Developer in Test&amp;quot;. It was my actual title, but I still thought that a &amp;quot;developer&amp;quot; had a higher place in the totem pole.&lt;/p&gt;  &lt;p&gt;After a year or two, I learned more and I decided that I actually love to test. I began telling people &amp;quot;I am a Quality Engineer&amp;quot;. Yeah, sounds pompous, but I believed that the word tester had a social stigma for folks not involved in software development. Besides, I thought that what I was doing was so much more than &amp;quot;just testing&amp;quot;.&lt;/p&gt;  &lt;p&gt;Finally, two or three years ago it clicked to me. I am a service to my development team, a big part of my job is to support our programmers, I bring unique skills to the process and those skills take effort to master. I am still learning. Yes, I can also code, but that's just one of my skills (that also needs improvement, by the way). Others may not know this, and it is in my power to dispel the word.&lt;/p&gt;  &lt;p&gt;Reader, if you are into testing, I encourage you to think how you present yourself to others, it can reveal things about our conceptions (or miss conceptions) about our craft. &lt;/p&gt;  &lt;p&gt;What is your title in your business card? &lt;/p&gt;  &lt;p&gt;- Federico&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-3782587102150410512?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/3782587102150410512/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2010/06/i-am-tester.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/3782587102150410512'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/3782587102150410512'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2010/06/i-am-tester.html' title='“I am a tester”'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-3574629625121146007</id><published>2010-06-09T20:04:00.001-07:00</published><updated>2011-05-18T02:01:19.232-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Development'/><title type='text'>My first experience with MSpec</title><content type='html'>&lt;p&gt;In my spare time I like to implement small sample applications to keep in touch with web development. Lately, I have been working on a WishList application implemented in MVC to get better at using Moq.&lt;/p&gt;  &lt;p&gt;If you are interested you can download the sample in progress: &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Source available here: &lt;a href="https://farmas@bitbucket.org/farmas/mvcwishlist"&gt;https://farmas@bitbucket.org/farmas/mvcwishlist&lt;/a&gt; (using mercurial) &lt;/li&gt;    &lt;li&gt;See it in action: &lt;a title="http://farmas.net/wishlist" href="http://farmas.net/wishlist"&gt;http://farmas.net/wishlist&lt;/a&gt; (user=fede, pass=123) &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;However, today I decided to give BDD a try. I chose &lt;a href="http://teamcity.codebetter.com/viewType.html?tab=buildTypeStatusDiv&amp;amp;buildTypeId=bt44"&gt;MSpec&lt;/a&gt; (by Aaron Jensen) over SpecFlow because it looked more interesting. Right out of the bat, one of the disadvantages is the lack of documentation (T_T) but after searching the web and watching some &lt;a href="http://tekpub.com/"&gt;TekPub&lt;/a&gt; with Rob Conery I finally got it working. I want to paste here the transformation of my unit tests from MSTest&amp;#160; to MSpec for those of you that are looking at getting started with this tool and as a reference. You can also download the source from bitbucket to see both test styles.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;MSTest&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;This test is for the login page of the site, and it verifies that if valid credentials are provided, the user will be signed in and redirected to the the lists page. &lt;/li&gt;    &lt;li&gt;The CreateController method is separate since I use it for all the other tests for this controller. &lt;/li&gt;    &lt;li&gt;Notice the use of Moq to setup membership and verify formsauth. &lt;/li&gt; &lt;/ul&gt;  &lt;pre class="code"&gt;[&lt;span style="color: #2b91af"&gt;TestMethod&lt;/span&gt;]&lt;br /&gt;&lt;span style="color: blue"&gt;public void &lt;/span&gt;WhenLoginPost_IfUserAndPasswordAreValid_VerifyRedirectAndFormsAuth()&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: green"&gt;//Arrange&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;controller = CreateAccountController();&lt;br /&gt;    _mockMembership.Setup(m =&amp;gt; m.ValidateUser(&lt;span style="color: #a31515"&gt;&amp;quot;User1&amp;quot;&lt;/span&gt;, &lt;span style="color: #a31515"&gt;&amp;quot;ValidPassword&amp;quot;&lt;/span&gt;)).Returns(&lt;span style="color: blue"&gt;true&lt;/span&gt;);&lt;br /&gt;    &lt;span style="color: blue"&gt;var &lt;/span&gt;loginData = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;LoginViewModel&lt;/span&gt;() { UserName = &lt;span style="color: #a31515"&gt;&amp;quot;User1&amp;quot;&lt;/span&gt;, Password = &lt;span style="color: #a31515"&gt;&amp;quot;ValidPassword&amp;quot; &lt;/span&gt;};&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: green"&gt;//Act&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;result = controller.LogOn(loginData) &lt;span style="color: blue"&gt;as &lt;/span&gt;&lt;span style="color: #2b91af"&gt;RedirectToRouteResult&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: green"&gt;//Assert&lt;br /&gt;    &lt;/span&gt;_mockFormsAuth.Verify(m =&amp;gt; m.SignIn(&lt;span style="color: #a31515"&gt;&amp;quot;User1&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;false&lt;/span&gt;));&lt;br /&gt;    &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(&lt;span style="color: #a31515"&gt;&amp;quot;Lists&amp;quot;&lt;/span&gt;, result.RouteName);&lt;br /&gt;    &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(&lt;span style="color: #a31515"&gt;&amp;quot;User1&amp;quot;&lt;/span&gt;, result.RouteValues[&lt;span style="color: #a31515"&gt;&amp;quot;username&amp;quot;&lt;/span&gt;]);&lt;br /&gt;}&lt;br /&gt;&lt;span style="color: blue"&gt;private &lt;/span&gt;&lt;span style="color: #2b91af"&gt;AccountController &lt;/span&gt;CreateAccountController(&lt;span style="color: #2b91af"&gt;MockBehavior &lt;/span&gt;behavior = &lt;span style="color: #2b91af"&gt;MockBehavior&lt;/span&gt;.Default)&lt;br /&gt;{&lt;br /&gt;    _mockWishListRepo = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Mock&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;IWishListRepository&lt;/span&gt;&amp;gt;(behavior);&lt;br /&gt;    _mockFormsAuth = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Mock&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;IFormsAuthenticationService&lt;/span&gt;&amp;gt;(behavior);&lt;br /&gt;    _mockMembership = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Mock&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;IMembershipService&lt;/span&gt;&amp;gt;(behavior);&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: blue"&gt;return new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;AccountController&lt;/span&gt;()&lt;br /&gt;    {&lt;br /&gt;        FormsAuthenticationService = _mockFormsAuth.Object,&lt;br /&gt;        MembershipService = _mockMembership.Object,&lt;br /&gt;        WishListRepository = _mockWishListRepo.Object,&lt;br /&gt;    };&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;MSpec (original specification)&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;  &lt;li&gt;Of course I cheated from BDD because I basically translated the UnitTest into MSpec :P, however, you get the idea of the readable form that specs take. &lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="code"&gt;[&lt;span style="color: #2b91af"&gt;Subject&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;Login Page&amp;quot;&lt;/span&gt;)]&lt;br /&gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;when_posting_with_valid_username_and_password&lt;br /&gt;&lt;/span&gt;{&lt;br /&gt;    &lt;span style="color: #2b91af"&gt;It &lt;/span&gt;should_sign_in_the_user;&lt;br /&gt;    &lt;span style="color: #2b91af"&gt;It &lt;/span&gt;should_redirect_to_Lists_page;&lt;br /&gt;    &lt;span style="color: #2b91af"&gt;It &lt;/span&gt;should_place_username_in_the_url;&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;MSpec (the real deal)&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;  &lt;li&gt;I could have left the Establish call on the test method, but since I ended up retyping it over and over I decided to remove it to a common base class. &lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="code"&gt;[&lt;span style="color: #2b91af"&gt;Subject&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;Login Page&amp;quot;&lt;/span&gt;)]&lt;br /&gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;when_posting_with_valid_username_and_password&lt;/span&gt;: &lt;span style="color: #2b91af"&gt;with_account_controller&lt;br /&gt;&lt;/span&gt;{&lt;br /&gt;    &lt;span style="color: blue"&gt;static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;RedirectToRouteResult &lt;/span&gt;result;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #2b91af"&gt;Establish &lt;/span&gt;context = () =&amp;gt; membership.Setup(m =&amp;gt; m.ValidateUser(&lt;span style="color: #a31515"&gt;&amp;quot;User1&amp;quot;&lt;/span&gt;, &lt;span style="color: #a31515"&gt;&amp;quot;ValidPassword&amp;quot;&lt;/span&gt;)).Returns(&lt;span style="color: blue"&gt;true&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #2b91af"&gt;Because &lt;/span&gt;of = () =&amp;gt;&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: blue"&gt;var &lt;/span&gt;loginData = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;LoginViewModel&lt;/span&gt;() { UserName = &lt;span style="color: #a31515"&gt;&amp;quot;User1&amp;quot;&lt;/span&gt;, Password = &lt;span style="color: #a31515"&gt;&amp;quot;ValidPassword&amp;quot; &lt;/span&gt;};&lt;br /&gt;        result = controller.LogOn(loginData) &lt;span style="color: blue"&gt;as &lt;/span&gt;&lt;span style="color: #2b91af"&gt;RedirectToRouteResult&lt;/span&gt;;&lt;br /&gt;    };&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #2b91af"&gt;It &lt;/span&gt;should_sign_in_the_user = () =&amp;gt; formsAuth.Verify(f =&amp;gt; f.SignIn(&lt;span style="color: #a31515"&gt;&amp;quot;User1&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;false&lt;/span&gt;));&lt;br /&gt;    &lt;span style="color: #2b91af"&gt;It &lt;/span&gt;should_redirect_to_Lists_page = () =&amp;gt; result.RouteName.ShouldEqual(&lt;span style="color: #a31515"&gt;&amp;quot;Lists&amp;quot;&lt;/span&gt;);&lt;br /&gt;    &lt;span style="color: #2b91af"&gt;It &lt;/span&gt;should_place_username_in_the_url = () =&amp;gt; result.RouteValues[&lt;span style="color: #a31515"&gt;&amp;quot;username&amp;quot;&lt;/span&gt;].ShouldEqual(&lt;span style="color: #a31515"&gt;&amp;quot;User1&amp;quot;&lt;/span&gt;);&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public abstract class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;with_account_controller&lt;br /&gt;&lt;/span&gt;{&lt;br /&gt;    &lt;span style="color: blue"&gt;protected static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;AccountController &lt;/span&gt;controller;&lt;br /&gt;    &lt;span style="color: blue"&gt;protected static &lt;/span&gt;Moq.&lt;span style="color: #2b91af"&gt;Mock&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;IFormsAuthenticationService&lt;/span&gt;&amp;gt; formsAuth;&lt;br /&gt;    &lt;span style="color: blue"&gt;protected static &lt;/span&gt;Moq.&lt;span style="color: #2b91af"&gt;Mock&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;IMembershipService&lt;/span&gt;&amp;gt; membership;&lt;br /&gt;    &lt;span style="color: blue"&gt;protected static &lt;/span&gt;Moq.&lt;span style="color: #2b91af"&gt;Mock&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;IWishListRepository&lt;/span&gt;&amp;gt; repo;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #2b91af"&gt;Establish &lt;/span&gt;context = () =&amp;gt;&lt;br /&gt;    {&lt;br /&gt;        formsAuth = &lt;span style="color: blue"&gt;new &lt;/span&gt;Moq.&lt;span style="color: #2b91af"&gt;Mock&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;IFormsAuthenticationService&lt;/span&gt;&amp;gt;();&lt;br /&gt;        membership = &lt;span style="color: blue"&gt;new &lt;/span&gt;Moq.&lt;span style="color: #2b91af"&gt;Mock&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;IMembershipService&lt;/span&gt;&amp;gt;();&lt;br /&gt;        repo = &lt;span style="color: blue"&gt;new &lt;/span&gt;Moq.&lt;span style="color: #2b91af"&gt;Mock&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;IWishListRepository&lt;/span&gt;&amp;gt;();&lt;br /&gt;&lt;br /&gt;        controller = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;AccountController&lt;/span&gt;()&lt;br /&gt;        {                    &lt;br /&gt;            FormsAuthenticationService = formsAuth.Object,&lt;br /&gt;            MembershipService = membership.Object,&lt;br /&gt;            WishListRepository = repo.Object&lt;br /&gt;        };&lt;br /&gt;    };&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;Execution&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;I use TestDriven.NET to execute the tests and the output looks really cool: &lt;br /&gt;  &lt;br /&gt;------ Test started: Assembly: MvcWishList.Tests.dll ------ &lt;br /&gt;&lt;br /&gt;  &lt;br /&gt;Login Page, when posting with valid username and password &lt;br /&gt;&lt;br /&gt;  &lt;br /&gt;» should sign in the user &lt;br /&gt;&lt;br /&gt;  &lt;br /&gt;» should redirect to Lists page &lt;br /&gt;&lt;br /&gt;  &lt;br /&gt;» should place username in the url &lt;br /&gt;&lt;br /&gt;  &lt;br /&gt;3 passed, 0 failed, 0 skipped, took 4.27 seconds (MSpec).&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Even with this small app I found myself doing time consuming refactoring of code as I “discovered” hidden facts that I had not taken into account when writting the first tests for each controller. I believe that if I had written the specs first in this way, I would have ironed out parts of the design even before implementation. I’ll continue to translate my unit tests into MSpec to see how more complex controller actions look and eventually write the parts that are missing using BDD. I’ll upload all source to bitbucket.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;- Federico&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-3574629625121146007?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/3574629625121146007/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2010/06/my-first-experience-with-mspec.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/3574629625121146007'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/3574629625121146007'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2010/06/my-first-experience-with-mspec.html' title='My first experience with MSpec'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-6880312615611553592</id><published>2010-03-14T12:23:00.001-07:00</published><updated>2010-03-14T20:46:56.341-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='LTAF'/><title type='text'>LTAF Screen Cast #1: Getting Started</title><content type='html'>&lt;p&gt;I am starting to record screen casts for LTAF. This is the first in the series where I go over what is LTAF and how to write your first test. If there are any topics that you want me to cover, let me know!&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:922c2c65-aa43-47be-be38-c64d97a33a67" class="wlWriterEditableSmartContent"&gt;&lt;div id="9647eacd-83b3-4b58-ba47-8a7407f67759" style="margin: 0px; padding: 0px; display: inline;"&gt;&lt;div&gt;&lt;a href="http://www.youtube.com/watch?v=yYNrA7Ax_m4" target="_new"&gt;&lt;img src="http://lh6.ggpht.com/_xvWVHJe2bvs/S52trrQGd4I/AAAAAAAAABI/q3UrFMB8YPg/video8c3d860f6431%5B3%5D.jpg?imgmax=800" style="border-style: none" galleryimg="no" onload="var downlevelDiv = document.getElementById('9647eacd-83b3-4b58-ba47-8a7407f67759'); downlevelDiv.innerHTML = &amp;quot;&amp;lt;div&amp;gt;&amp;lt;object width=\&amp;quot;425\&amp;quot; height=\&amp;quot;355\&amp;quot;&amp;gt;&amp;lt;param name=\&amp;quot;movie\&amp;quot; value=\&amp;quot;http://www.youtube.com/v/yYNrA7Ax_m4&amp;amp;hl=en\&amp;quot;&amp;gt;&amp;lt;\/param&amp;gt;&amp;lt;embed src=\&amp;quot;http://www.youtube.com/v/yYNrA7Ax_m4&amp;amp;hl=en\&amp;quot; type=\&amp;quot;application/x-shockwave-flash\&amp;quot; width=\&amp;quot;425\&amp;quot; height=\&amp;quot;355\&amp;quot;&amp;gt;&amp;lt;\/embed&amp;gt;&amp;lt;\/object&amp;gt;&amp;lt;\/div&amp;gt;&amp;quot;;" alt=""&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;  &lt;p&gt;Resources:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://aspnet.codeplex.com/wikipage?title=ASP.NET%20QA&amp;amp;referringTitle=Home"&gt;Download LTAF from CodePlex&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://cid-ac161ba71cdef574.skydrive.live.com/self.aspx/Public/DevConnections%20LTAF%20Demos.zip"&gt;Download LTAF Demos&lt;/a&gt; (from a talk I did at DevConnections) &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;- Federico&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-6880312615611553592?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/6880312615611553592/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2010/03/ltaf-screen-cast-1-getting-started.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/6880312615611553592'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/6880312615611553592'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2010/03/ltaf-screen-cast-1-getting-started.html' title='LTAF Screen Cast #1: Getting Started'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_xvWVHJe2bvs/S52trrQGd4I/AAAAAAAAABI/q3UrFMB8YPg/s72-c/video8c3d860f6431%5B3%5D.jpg?imgmax=800' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-7476258375928816143</id><published>2010-03-07T12:50:00.001-08:00</published><updated>2011-05-18T01:59:49.672-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Random Tales'/><title type='text'>The Boat Anchor Odyssey (part 3)</title><content type='html'>&lt;p&gt;This is the third and last part in these series.&amp;#160; Part 1 can be found &lt;a href="http://testertales.blogspot.com/2010/02/boat-anchor-odyssey.html"&gt;here&lt;/a&gt;, and part 2 can be found &lt;a href="http://testertales.blogspot.com/2010/02/boat-anchor-odyssey-part-2.html"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;The Details&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Ok, enough of planning, let’s get down to the details. The work to get 2,000 tests to a robust and trusted state was:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Nightly runs. The concept is to be able to run 2,000 tests every day in a some what predictable manner. This is important because we need a way to validate the changes that we were about to make. &lt;/li&gt;    &lt;li&gt;Remove low value tests. This idea was to define what we thought our new test bed &lt;em&gt;should&lt;/em&gt; cover, and then to go back and review the 2,000 tests and make a decision whether to keep it or remove them. &lt;/li&gt;    &lt;li&gt;Increase robustness. Nothing kills automation faster than flaky tests. This idea was to track test failures very explicitly and to make it a scheduled work item to resolve them. &lt;/li&gt;    &lt;li&gt;Port old tests. This is very specific to our team, but across the 10 years of the product, there are tests written in 3 different automation frameworks. &lt;/li&gt;    &lt;li&gt;Manual tests. The idea was to create a formal manual test bed that can complement our automation.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;So there you have it, these activities went on in parallel with a team of 4 persons. What follows are the details of each activity.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Nightly Runs&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This is one of the first thing that we tackled. The system that we ended up with monitors every new build of asp.net, and kicks off an automated run every night so that we get results the next morning. This helped because we started to get a lot more history of each test and we could compare results with past results, it also allowed us to discover patterns across time frames. &lt;/p&gt;  &lt;p&gt;The first challenge was the need to make runs under many different platforms. Clay, who was in charge of this project, came up with a clever rotation schedule. We have 4 “templates”:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Up level x64&lt;/li&gt;    &lt;li&gt;Up level x86&lt;/li&gt;    &lt;li&gt;Down level x64&lt;/li&gt;    &lt;li&gt;Down level x86&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Up level means operating systems that are Vista or greater (which come with IIS 7), down level means system previous to Vista. Each day, one template would be used in sequence, and for each template an OS would be used in sequence. This gave us coverage and some degree of predictability. For example, if we saw a test fail on XP x86, we could look at previous runs and see if this was something particular to this platform or generic. And after we made a fix we could either reset it for this week run, or wait until the next scheduled XP x86 to see what happened. (As I am writing this, we are investigating including Localized builds and framework only builds into our mix)&lt;/p&gt;  &lt;p&gt;The second challenge was the reimaging of machines. The problem was that our tests need the machine to be set up in specific ways. For example, some may need some SDK tools, SSE to be installed, smtp server to be configured, an SSL certificate, etc. It was very important that the machines setup be predictable between runs, so Clay had to spend a fair amount of time making sure the install steps work correctly for each of our 4 templates. You would be surprised by the complexity of just being able set up test machines in a consistent and automated way.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Remove Low Value Tests&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This idea came after sampling some tests in our proposed test bed. There was such a high difference in level of coverage per feature. For example, some controls would test setting each property to 30 different colors and verify rendering, while others assumed that the color was handled by the base class and didn’t verify it at all. Some features considered error reporting from edge cases to be the most important test, while others assumed that the most important test was a positive case. There was also a big disparity in the number of tests between features, but I assumed that the number of tests wasn’t that relevant (we would not try to level them).&lt;/p&gt;  &lt;p&gt;Reviewing 2,000 tests was not trivial, but we thought it was worth it. So little by little we chipped at them. The challenge here was coming up with a new bar for what the tests should be covering, and then apply it across each feature. This was also a good opportunity to document our test bed. As we went along, we took note of the automated coverage that each feature in the product has.&lt;/p&gt;  &lt;p&gt;Part of this review was to remove something that we call &lt;em&gt;contexts&lt;/em&gt;, which is like a variation of a test. For example, a dynamic data test would be run on IE, FireFox and Chrome, producing 3 results in total. Even though there were 2,000 tests, when executed we actually got 9,100 results because of contexts.&lt;/p&gt;  &lt;p&gt;The result of this review was a reduction from 2,000 to 1,800 tests, and from 9,100 results per nightly to 4,000 results, with out a big impact to coverage. As you can see, the biggest gain by far was due to contexts. This is because we found out that there was little value in running some of the tests in multiple contexts. We also came up with a product “heat map” that shows the distribution of tests and contexts across the product. We plan to use this later when deciding what tests are missing.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Increase Robustness&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;All right, we had a process in place to trim down our test bed to remove duplication and low value tests and a way to run tests every day. Now we needed to make our tests robust and maintainable. We identified 4 reasons why a test would fail (assuming there is no product bug):&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;The machine was set up incorrectly.&lt;/li&gt;    &lt;li&gt;A defect in the automation framework.&lt;/li&gt;    &lt;li&gt;A defect in the test code due wrong expectation check.&lt;/li&gt;    &lt;li&gt;A fragile test code (race conditions, bad recovery, focus timing).&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;The process that we created was that we would spend one or two hours every morning to analyze the nightly results and open test defects for any test failure in these 4 buckets. We divided the tests between us so that we each started to get familiar with a segment of tests. Every week, we would triage all the bugs and assign the highest priority (usually the ones that are causing the most failures) to be fixed next week. Each of us is committed to get the bug fixed.&lt;/p&gt;  &lt;p&gt;This method allowed us to keep a very concrete count of work left. If I see 50 bugs in the database, that tells me that there are 50 problems that are preventing us for having a clean passing run, and I can some what estimate effort.&lt;/p&gt;  &lt;p&gt;Collectively, we have fixed a lot of bugs, more than 150. The result is we now have 98% pass rate in two of our nightly templates. This is 80 failures each morning, which are easily handled. We still have 20 active bugs, which we continue to push for every week.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Port Old Tests&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;I won’t spend too much time here. At the beginning of this project we still had 250 tests written in the old frameworks that none of our team has expertise in analyzing. We found out that they constituted at least 1/3 of each night’s failures. The decision was that maintaining those tests was more expensive than to port them to the new framework. At this point, we have gotten rid of those, which reduced our test bed to ~1,500 tests.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Manual Tests&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This is a touchy subject in DevDiv, where there is a strong culture of automation. But look, there are features in ASP.NET that are no longer being developed that are costly to maintain automation for. Is it good enough to run a check for these features once per milestone? This is roughly equivalent to run them once every 3 months. We would still catch the regression in time for the iteration, but we would not be checking it every single night. If frequency can be this low, the value of automation is greatly diminished. &lt;/p&gt;  &lt;p&gt;We decided to embrace manual tests where it made sense and create a set of them that are cheaper and easy to run by a person. We have clear guidelines of what should be part of our manual test bed, as well as how to run and track results for them. Some examples of good candidates for this: &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;WebParts drag and drop. This is a feature that is fairly atomic that we haven’t changed since .NET 2.0. However, it is difficult to automate for all supported browsers, but very simple for a person to run.&lt;/li&gt;    &lt;li&gt;Web Admin Tool. Our team is no longer investing in this tool, and was released since .NET 2.0 as well. Many tests were written for it, but for several reasons they are very flaky. This is another area where running by hand could makes sense.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This project is scheduled to end at the end of March 2010. We are in the home stretch. The real trial for the new test bed is yet to come, as we use it for servicing after Dev10 RTM, as well as regression coverage during the next product releases. Hopefully I will post a post mortem after a couple of months to recap how things went. &lt;/p&gt;  &lt;p&gt;What I am most excited about is the opportunity that our team has to impact the product going forward. If a regression check takes us only a couple of hours each week. Imagine all the new tests that we could be designing with the rest of the time. The plans for this next stage will have to wait for another post.&lt;/p&gt;  &lt;p&gt;I want to thank Anton, Alex, Clay and Drew for their hard work on making this happen. As I mentioned before, this was not our only deliverable during this time frame but they kept in it for all this time. &lt;/p&gt;  &lt;p&gt;- Federico&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-7476258375928816143?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/7476258375928816143/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2010/03/boat-anchor-odyssey-part-3.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/7476258375928816143'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/7476258375928816143'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2010/03/boat-anchor-odyssey-part-3.html' title='The Boat Anchor Odyssey (part 3)'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-7928493703676354978</id><published>2010-02-10T21:18:00.001-08:00</published><updated>2011-05-18T01:59:49.672-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Random Tales'/><title type='text'>The Boat Anchor Odyssey (part 2)</title><content type='html'>&lt;p&gt;Part 1 can be found &lt;a href="http://testertales.blogspot.com/2010/02/boat-anchor-odyssey.html"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Keeping it within constraints&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;I experimented with a ton of approaches to reach my objective. I knew that going and fix 20,000 tests would not scale, so there had to be some form of evaluation. Here are some ideas I tried:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Fix the failed tests. &lt;/li&gt;    &lt;li&gt;Fix the ones that have found defects in the past.&amp;#160; &lt;/li&gt;    &lt;li&gt;Remove tests that have not found defect in the past. &lt;/li&gt;    &lt;li&gt;Remove tests for features that are not high priority. &lt;/li&gt;    &lt;li&gt;Replace tests with a new designed tests. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I reviewed my findings with some team members to get feedback. The problem with these techniques is the effort of evaluating this many tests. It could work, but they depended on my resources. This was tricky, the more resources I would need, the more I ran the risk of getting into time consuming negotiations with management. I decided to create my own constraints that would seem “reasonable” to my product unit. After some not-entirely-scientific calculations I came up with:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Due date: End of March 2010. This coincides with the release of Dev10, which made it easy to justify. &lt;/li&gt;    &lt;li&gt;Resources: 3 persons. This decision fit within a bigger initiative that we were driving in the team. The basic idea was that this group would provide key services that will allow the rest of the team to really focus on product development. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Around this time, I decided to become a manager lead. My group, named Engineering Services, would consist of 3 team members and one of our charters was the Test Bed goals that I previously described. This is not our only responsibility, but it is up to us to manage our time properly so that this project is a success.&lt;/p&gt;  &lt;p&gt;It may sound backwards for some, but by arbitrarily choosing constraints that were easily “agreeable”, I got no push back and now had clear constraints that I could work with to come up with an actual strategy. Of course, it helps that I have a manager that believes in me. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Deciding on a Strategy&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;It was November 2009, which meant I had 5 months to turn things around and I had to juggle this deliverable with at least 3 others (won’t go into them): hand off our test bed to the servicing team, driving test passes, take ownership of tests.&lt;/p&gt;  &lt;p&gt;I concluded that my first priority was to create a “base line”. The idea was to create a small test bed that was well understood and robust that we could use to make intelligent decisions about our coverage going forward. I entertained the idea of creating it from scratch, a compact super integrated test bed, but I abandoned it in December after a costing exercise. Instead, we would use some of our current assets to create the base line.&lt;/p&gt;  &lt;p&gt;To understand this next part I need to talk about numbers. Our test bed is divided into 3 priorities, what each priority meant was never clearly defined, which means that it is totally subjective to what the tester thought what Pri 0, 1 or 2 meant. We knew that a human at some point made the decision of how to prioritize their tests, but we didn’t really understand how that decision was made. The break out was:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;2,000 Pri 0 &lt;/li&gt;    &lt;li&gt;10,000 Pri 1 &lt;/li&gt;    &lt;li&gt;8,000 Pri 2 &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;2,000 looked manageable, so the strategy became: the Pri 0’s will become our base line, once we get these tests to be stable and robust, we can analyze whether more tests are needed. This was a touchy subject, it read like we were going to start fresh by only keeping Pri 0 tests and discarding 18,000 tests. That made people nervous. However, this is only step #1, once we got to a stable state we would evaluate if more tests are needed in any area and surgically move tests from the 18,000 to our new test bed. The point was to protect our test bed, from now on, the only thing that goes in there are things that product development absolutely needs and that we approve.&lt;/p&gt;  &lt;p&gt;Thanks to Leslie for trusting in my methods and to Drew who helped me bounce ideas with him.&lt;/p&gt;  &lt;p&gt;Next: Details and Making it Happen.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-7928493703676354978?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/7928493703676354978/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2010/02/boat-anchor-odyssey-part-2.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/7928493703676354978'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/7928493703676354978'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2010/02/boat-anchor-odyssey-part-2.html' title='The Boat Anchor Odyssey (part 2)'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-5935256009909959863</id><published>2010-02-06T20:46:00.001-08:00</published><updated>2011-05-18T01:59:49.673-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Random Tales'/><title type='text'>The Boat Anchor Odyssey</title><content type='html'>&lt;p&gt;&lt;font color="#ff0000"&gt;&lt;strong&gt;Disclaimer:&lt;/strong&gt; These posts will go into a lot of specifics of my work, &lt;/font&gt;&lt;font color="#ff0000"&gt;the problems that I faced along the way and how I chose to solve them. I will try to give as much context as possible, but I warn you reader that to give a complete picture of the situation would take more time than I have. Any feedback is appreciated.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;The ASP.NET test bed is a franken-monster that was built over the course of 10 years, with no clear direction by over 60 different testers that came and went in short periods. We called it the “boat anchor” and you can read more about it on &lt;a href="http://testertales.blogspot.com/2009/07/finally-tackling-aspnet-qa-boat-anchor.html"&gt;this post&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Last year, me and others in my team began to seriously tackle the problem, and today I am here to report our progress and what I learned during this process.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Clear Leadership&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;We “officially” started in June 2009, we divided the test bed into 3 parts: design time (the experience of ASP.NET controls in VS); runtime controls (the page framework and controls); runtime core (the http pipeline and core app services). All in all 20,000 tests. Each of the test leads was given one of these pieces (I got design time).&lt;/p&gt;  &lt;p&gt;The goal was loosely defined as “reduce the test bed”. Each lead went out to tackle their own section, and we each came up with a different approach:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Design time: I decided that it was more cost effective to toss the current test bed and start anew (none of the tests even ran, and in my opinion where low value). &lt;/li&gt;    &lt;li&gt;Run time core: The lead decided to jump in and start porting the tests that were written with an old automation framework (a major cause of failures, and he evaluated the worth of each test along the way). &lt;/li&gt;    &lt;li&gt;Run time controls: The lead decided to create a tool so that he could query tests for each control and update its priority. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;After 3 months of work, our status was:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Design time: I had devised a methodology for evaluating the product to identify what tests needed to be written and how to measure the effectiveness of such tests. I applied it to a sample area which I thought validated the approach. Tangible results: nada. &lt;/li&gt;    &lt;li&gt;Run time core: The lead was 15% complete with porting the tests (there were 5,000 to begin with). Tangible results: ~300 tests were reviewed, and I believe we decreased the number of tests by ~200. &lt;/li&gt;    &lt;li&gt;Run time controls: He delegated the task to another team member, the tool was not finished yet. Tangible results: zilch. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;3 months of work, and we were almost where we started. What the hell happened? In my opinion it was the lack of strong leadership. For each of us, the priority of the work was different, the goal of the work was different and the approach was different. &lt;/p&gt;  &lt;p&gt;I strongly believe that the cost of our test bed was a major problem of my team, so I decided to grab the whole problem and invest myself in it. Take away: Good intentions are just that. You need a person that will truly own the effort and be held accountable for the result (which needs to be crystal clear). I decided to be that person, my review this year will be partly based on the success of this project. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Clear Expectations&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;By October 2009, I was now in charge of the whole test bed, and I was committed to fix it. First, I worked on creating the goals that will drive my effort. Here they are:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Detect regressions in the product as close to the moment of injection.&lt;/li&gt;    &lt;li&gt;Increase the capacity of the test team by treating regression testing as a service.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;That’s what I started with. Not perfect, but workable. Notice that test bed is nowhere in my goals. Also, the way I phrased them made it very easy to “sell it” to our managers. It is very simple to imagine how these goals will actually help our business. The sooner we catch regressions and the more time testers have to perform quality exploratory testing the better for our product.&lt;/p&gt;  &lt;p&gt;Ok, next I created some tactical objectives that would help me achieve my goals. Here they are:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Have a clear understanding of what our test bed is covering. &lt;/li&gt;    &lt;li&gt;Capable of running and reporting status of builds every day. &lt;/li&gt;    &lt;li&gt;Have a team that owns the test bed.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;In my mind we needed to be able to run our automated checks more often and we needed to understand what the runs where really telling us about the product. Additionally, a team of specialists would own the test bed and be responsible for it. This change has a broader cultural goal that I will not go into in this post, we will focus on the test bed aspect of the work.&lt;/p&gt;  &lt;p&gt;Two things that I would like to point out. First, it is important to take a step back and put some thinking to the bigger picture. Your efforts have to be easily mapped to your business. It helps to write it down. &lt;/p&gt;  &lt;p&gt;Second, I have seen a lot of initiatives in Microsoft die due to “paralysis analysis”. It is good to plan and take time to consider options with pros and cons, but at some point you have to bite the bullet and take action. If you find yourself going to meetings and meetings to review the vision/plan with a bunch of persons that are not directly accountable to the project, you may find that politics and processes will grind you to a halt.&lt;/p&gt;  &lt;p&gt;Next: strategy, resources and planning.&lt;/p&gt;  &lt;p&gt;- Federico&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-5935256009909959863?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/5935256009909959863/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2010/02/boat-anchor-odyssey.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/5935256009909959863'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/5935256009909959863'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2010/02/boat-anchor-odyssey.html' title='The Boat Anchor Odyssey'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-2945110423967249849</id><published>2010-01-31T10:22:00.001-08:00</published><updated>2010-01-31T10:22:34.429-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Random Tales'/><title type='text'>Lost in Metrics. A tale of process overhead.</title><content type='html'>&lt;p&gt;How do you report status in your work? Do you have to give metrics or some form of cost/value analysis? Maybe some conjured up risk analysis? I am assuming most of us have to report status some way or another. In this post I will narrate a true story that shows status reporting process overhead in action.&lt;/p&gt;  &lt;p&gt;This occurred last year, when in some random conversation with a tester in my team I asked what he was working on. He told me he was working on the “test pass status report”. Apparently he had been working on this on or off for two days. I was intrigued, I was hearing that a tester that could be finding defects was spending a lot of time doing some form of status reporting. After probing some more, I learned that there is this mandate from the test leaders in DevDiv that test pass status has to be reported in a certain cumbersome way, that ends up consuming a person 3 to 4 days to gather the data, organize it and input it in a special tool so that management can see the status of our team.&lt;/p&gt;  &lt;p&gt;This seemed excessive to me until I actually tried it myself. There is this tool created for the sole purpose of reporting on test pass status (I moan internally when I imagine the resources of other testers in the company spent creating this thing). This tool is extremely confusing. That’s the first time waste: the time to understand it. Each team in the DevDiv are tracked in there, ASP.NET is one of them, and each team has to fill metric for about 40 items. An example of one item is “Full Redist on Win2k3 x64”, which means have you run your tests against this platform install. And the metrics are things like how many tests did you run and how many failed. Just numbers.&lt;/p&gt;  &lt;p&gt;You may think that this doesn’t sound too bad and that maybe once we get accustomed it will go faster (that’s what the leaders at DevDiv told me anyway). However, whatever the cost, this activity was providing absolutely no value for my team, and I wanted to know what was the point of reporting this metrics. So I went and asked the person in charge of driving the test pass. I told her of the pain and waste that was reporting this metrics, and wondered if there was any other way that my team could get the information that management was after. The response was: “Look, I don’t care how you get the data, just get me the data in the format that I need it so that I can report it up the chain”. Great.&lt;/p&gt;  &lt;p&gt;I obviously asked who the report went to, because I wanted to learn what it was used for and how. After a couple of steps up the test leaders I arrived at the person that actually consumed the report. “I look at trends”, that’s the answer I got when I asked what was the point of this report. I didn’t totally buy it, but I could see that by seeing some red indicators in this report leaders could go and ask questions about why a team was doing bad here or there. Possibly preventing bigger issues from happening later by addressing them early. I thought it was quite sensible to ask if my team could report our areas of risk ourselves instead of this metrics based reporting. “Sorry, it has to be this way”. You see, having all teams report the same way in this repository makes it easier for our manager’s to read the report. In a way, all teams are paying a price so that managers can get a nice report, to spot what teams might be in problems. &lt;/p&gt;  &lt;p&gt;My team knows what are our problems with our product, where our risks are, and whether we are on track or not. Unfortunately we can’t simply communicate that, we have to spend our tester’s time to fill out this report. &lt;/p&gt;  &lt;p&gt;So, what did I learn from this?&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Direct challenge of management does not work. I feel kind of foolish now for even trying, indirect change through influence works better.&lt;/li&gt;    &lt;li&gt;Even though we keep reporting how we are told to, having understood the purpose of the report, by following the “spirit” of the report I could create a way to get management what they want without too much cost. (I won’t tell how :P )&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;- Federico&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-2945110423967249849?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/2945110423967249849/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2010/01/lost-in-metrics-tale-of-process.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/2945110423967249849'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/2945110423967249849'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2010/01/lost-in-metrics-tale-of-process.html' title='Lost in Metrics. A tale of process overhead.'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-6619080663897828731</id><published>2010-01-02T08:40:00.000-08:00</published><updated>2010-01-09T22:40:48.558-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Random Tales'/><title type='text'>The vicious cycle of QA</title><content type='html'>&lt;p&gt;One of the challenges that a tester must overcome is to create and sustain a reputation. This is particularly hard for testers not only because our problem space is vast and ambiguous, but because everybody expects something different from us. In this post I will narrate how having a loosely defined role for QA lead our team down a path that eventually created a culture of QA as a burden.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;i&gt;Step 1. Unclear expectations.&lt;/i&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;It probably started way before I joined 8 years ago. Nobody in the team &lt;b&gt;clearly&lt;/b&gt; understood what was expected of the QA team. The general idea existed that testers where meant to “find bugs”. But additionally each person had preconceptions of the role for QA, that included:&lt;/p&gt;  &lt;p&gt;· QA signs off on the product.&lt;/p&gt;  &lt;p&gt;· QA writes automation so that testing can be performed by just clicking a button.&lt;/p&gt;  &lt;p&gt;· QA should say exactly the time it will take to test the product at the beginning.&lt;/p&gt;  &lt;p&gt;· QA will test everything and whatever they are asked.&lt;/p&gt;  &lt;p&gt;Furthermore, nobody could explain any of the specifics. Like, what it means for a product to be “ready” to ship? What does “sign off” mean? What does each “priority” of defects mean? What does “automation” mean? What is “test complete”?&lt;/p&gt;  &lt;p&gt;It was an error from our part to not seek to fully define and declare what our role was. Hell, it would have been better if someone had come and defined what our role was for us. Instead, each person had its own story and expectation of what testers were supposed to do and deliver to the team. &lt;/p&gt;  &lt;p&gt;You can guess what happened, we failed all expectations!&lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;i&gt;Step 2. Fail and get blamed.&lt;/i&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;I mean, we did our best, but it was impossible to meet all the expectations from each Dev and PM, especially when we didn’t even know what they were. And we got the blame. It was not uncommon to hear things like &lt;/p&gt;  &lt;p&gt;“why did you miss this bug?”   &lt;br /&gt;“what are you going to do to not let it happen again?”    &lt;br /&gt;“why didn’t you run tests on this or that weird combination?”    &lt;br /&gt;“create more automated tests to patch the holes”    &lt;br /&gt;“automation is cheap, run more tests”.&lt;/p&gt;  &lt;p&gt;If any bug was missed it was because QA didn’t do its job. The message, as our leaders at the time heard it was, “you must catch all bugs pronto, and if you don’t you failed and it’s your fault”.&lt;/p&gt;  &lt;p&gt;What did we do when faced with this? We created more processes!&lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;i&gt;Step 3. Cover your back with processes&lt;/i&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;I am sure it was not the stated goal, but I have a feeling that the idea was that as long as we showed all the processes and we followed them, it was not our fault if a bug was missed. The process was not designed to do better testing, but to distribute responsibility in case of problems.&lt;/p&gt;  &lt;p&gt;For example: at the very beginning of a feature, and I am talking about when the spec was not even complete, the tester would create a “test plan” which tried to capture beforehand ALL of the tests that we would execute. Never mind that we didn’t even had a product yet. Then we would go into a review with Dev and PM and the plan was treated as a contract. The unsaid conversion would be: “this is everything that we are going to test, if it is not here it won’t be tested. This is your last chance to tell us if we need to test anything else, after this you will be partly responsible for any holes”. You can imagine that the result was a ridiculous amount of tests. There was little thought of value. If constraints are ignored and another person is doing the work, what comes out is a brute force brain dump. Furthermore, testing meant automation, so we ended up automation a ton of tests L&lt;/p&gt;  &lt;p&gt;We had similar processes for practically every test activity, although not many involved Dev and PM like the example above. Most were checklists and checklists of things to do. At some point, most testers didn’t understand why we had to do all of the activities but they were required to “sign off”.&lt;/p&gt;  &lt;p&gt;What did we gain by so much process overhead? We became the bottle neck!&lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;i&gt;Step 4. Push back when process doesn’t fit the plan.&lt;/i&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;Now enter the turf wars. It went like this: Dev and PM want to create a feature. They ask QA to cost and we came back with a &lt;b&gt;huge&lt;/b&gt; cost, I am talking months even for a small feature. We had become victims of our own brute force process and now it was impacting the team because we would not sign off on anything unless it passed through our test method juggernaut.&lt;/p&gt;  &lt;p&gt;Typical questions would go:&lt;/p&gt;  &lt;p&gt;“why does it take 2 months to test this small control?”   &lt;br /&gt;“everybody else is done, why are you so inefficient?”    &lt;br /&gt;“can’t you get more people to test? Like in China or something?”    &lt;br /&gt;“this is unacceptable, can you finish in half the time?”&lt;/p&gt;  &lt;p&gt;Interestingly, I can’t recall anyone that wanted to know just how are we spending our time. We were just “doing our thing” to sign off, that just how long it takes.&lt;/p&gt;  &lt;p&gt;It might have been bearable, except for one fact: our testing was low quality!&lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;i&gt;Step 5. QA as a burden, high cost for low value.&lt;/i&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;Put simply, we were taking more time and still missing a lot of bugs. Our shield was that it “had to be done this way”.&lt;/p&gt;  &lt;p&gt;A person external to QA would see a group of persons that are constantly pushing back against new features because of test cost, but that give little observable value to the team. We would be busy filling status and reports, automating like crazy, debugging and fixing crummy old tests, going through our checklists with little questioning. And then, a manager would grab the latest build, find an obvious bug, and wonder why the test team didn’t find it. Just what are those guys doing with all that time?&lt;/p&gt;  &lt;p&gt;And so we go back to step #1, rinse and repeat, and you settle at a culture that views QA as a burden. &lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;i&gt;Breaking the habit&lt;/i&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;This is what I named the vicious cycle of QA. Unclear expectations lead to blame which leads to more process which leads to bottle necks which leads to more un met expectations. This is what I think happened in my team and probably others in DevDiv, if you identify with this story or a piece of it, then I should say that we managed to break out of it. The road was long and the work is certainly not over, and the story of rehabilitation will have to wait for another day.&lt;/p&gt;  &lt;p&gt;Federico&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-6619080663897828731?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/6619080663897828731/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2010/01/vicious-cycle-of-qa.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/6619080663897828731'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/6619080663897828731'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2010/01/vicious-cycle-of-qa.html' title='The vicious cycle of QA'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-6025063247820951141</id><published>2009-12-23T09:37:00.001-08:00</published><updated>2009-12-23T09:37:38.179-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='LTAF'/><title type='text'>An LTAF post in Russian… translated.</title><content type='html'>&lt;p&gt;Matthew pointed me to a Russian blog that talks about LTAF &lt;a href="http://habrahabr.ru/blogs/net/77888/"&gt;here&lt;/a&gt;. And then tried the google translate service which I hadn’t used before. Check out the translation &lt;a href="http://translate.google.com/translate?hl=en&amp;amp;sl=ru&amp;amp;tl=en&amp;amp;u=http%3A%2F%2Fhabrahabr.ru%2Fblogs%2Fnet%2F77888%2F"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;- Federico&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-6025063247820951141?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/6025063247820951141/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2009/12/ltaf-post-in-russian-translated.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/6025063247820951141'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/6025063247820951141'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2009/12/ltaf-post-in-russian-translated.html' title='An LTAF post in Russian… translated.'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-4244306664376811152</id><published>2009-12-13T18:15:00.001-08:00</published><updated>2009-12-13T18:15:36.457-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Announcements'/><title type='text'>Job opportunity in the ASP.NET QA Team</title><content type='html'>&lt;p&gt;There is an opening for a tester in my team. If you are interested in help building a test team that is strongly based on the context driven testing principles, then shoot your resume to &lt;a href="mailto:markberr@microsoft.com"&gt;Mark Berryman&lt;/a&gt;, we would love to talk to you.&lt;/p&gt;  &lt;p&gt;You can see the external job post &lt;a href="https://careers.microsoft.com/JobDetails.aspx?ss=&amp;amp;pg=0&amp;amp;so=&amp;amp;rw=1&amp;amp;jid=9679&amp;amp;jlang=EN"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;- Federico&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-4244306664376811152?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/4244306664376811152/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2009/12/job-opportunity-in-aspnet-qa-team.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/4244306664376811152'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/4244306664376811152'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2009/12/job-opportunity-in-aspnet-qa-team.html' title='Job opportunity in the ASP.NET QA Team'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-2427163425899362959</id><published>2009-11-16T19:40:00.001-08:00</published><updated>2009-11-16T19:40:34.516-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='LTAF'/><title type='text'>DevConnections slides and demos</title><content type='html'>&lt;p&gt;Last week I presented at the DevConnections conference in Las Vegas. The topic was the Lightweight Test Automation Framework (LTAF) and the links to the powerpoint presentation and the demos are at the bottom of this post. &lt;/p&gt;  &lt;p&gt;The conference is mostly for developers, so I tried to mold the talk towards practical applications of a test framework to enable product teams to catch regressions sooner. I asked at the beginning how many persons in the audience considered themselves as “testers” and only 4 persons raised their hands. Based on the comments that I got after the talk, there is still the stigma that testers are second class citizens below developers, which was not too surprising. However, I did find high interest from attendees to have more test oriented talks in future conferences which was a surprise and something to look forward to. &lt;/p&gt;  &lt;p&gt;I am trying to improve my skills as a speaker, and this opportunity definitely helped (translating spanish to english on stage is harder than I thought). To my knowledge, this was the first time that a Microsoft technical conference had a session dedicated to QA, and seems like people want more. I’ll start preparing for next time. ^_^&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://cid-ac161ba71cdef574.skydrive.live.com/self.aspx/Public/AMS10%20-%20Testing%20in%20ASPNET.pptx"&gt;PowerPoint Deck&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://cid-ac161ba71cdef574.skydrive.live.com/self.aspx/Public/DevConnections%20LTAF%20Demos.zip"&gt;Demos&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;- Federico&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-2427163425899362959?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/2427163425899362959/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2009/11/devconnections-slides-and-demos.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/2427163425899362959'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/2427163425899362959'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2009/11/devconnections-slides-and-demos.html' title='DevConnections slides and demos'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-8736097304015169792</id><published>2009-11-15T18:07:00.001-08:00</published><updated>2009-11-15T18:07:36.329-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Random Tales'/><title type='text'>What I learned from James Bach?</title><content type='html'>&lt;p&gt;This Friday I got to meet and interview James Bach (episode should be available soon-ish at &lt;a href="http://codingqa.com"&gt;codingqa&lt;/a&gt;). I really want to thank James for meeting with Matthew and I on a Friday afternoon, and taken the time to teach us some ropes of the trade. Besides learning some very useful testing exercises, there were some points that I got while talking with him about being a professional tester. &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;strong&gt;Create your own definitions&lt;/strong&gt;. I thought I had taken some time to internally define what “testing” and “quality” mean, but James took it to another level. He challenged me to define and describe all my behavior so that I could explain with determinism what I was doing. I find this extremely important: to develop the capacity to synthesize behavior into its essential nature and to be able to classify it against other behaviors. In other words, to develop my own vocabulary. Why? Because once I have this framework I will be able to evaluate and standardize test work as a profession. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Train your intellect.&lt;/strong&gt; Testing is a highly intellectual activity that needs to be developed. I already knew this, or more accurately, I knew it by intuition. But to be more serious and even systematic about training my mind to be a test ninja is work that I need to start doing. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Learn by experiment&lt;/strong&gt;. The reason why I respect the people that I respect is because they lead by example. This is the type of the lead that I want to become in my team. One cannot preach without having tried it over and over, and of the best ways to do that is to experiment a lot, observe, learn and try it again. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Build your reputation&lt;/strong&gt;. A professional works hard to build and guard his/her reputation, it is this standing among peers and others that grants you executing power and it translates to money at the end of the day. My first step is to work on point #1 and #2 to increase my confidence, that is the key ingredient. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Leverage the community&lt;/strong&gt;. I care deeply about testing and the product that we are building (ASP.NET), I go to great lengths to envision new ways to test, try them out and roll them out to the team. However one thing that I haven’t done so much is reach to the community of other testers for more ideas and to help me learn. There are a lot of thought leaders out there, and I need to put myself with them to share what I got and take in what they got. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Lastly, something that was more of an experience rather than a learning, was the motivation that I got by talking with James. There is so much more out there that is exciting, just thinking of how me and my team could be better testers makes me want to get in the car and floor the gas and just go. Recklessly.&lt;/p&gt;  &lt;p&gt;- Federico&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-8736097304015169792?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/8736097304015169792/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2009/11/what-i-learned-from-james-bach.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/8736097304015169792'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/8736097304015169792'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2009/11/what-i-learned-from-james-bach.html' title='What I learned from James Bach?'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-2882378839374713439</id><published>2009-10-19T19:34:00.001-07:00</published><updated>2009-10-19T19:34:06.294-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Random Tales'/><title type='text'>Working with numbers and common sense</title><content type='html'>&lt;p&gt;The Asp.Net QA team is going through some changes to better focus our activities and avoid randomization, I’ll talk about it in some later post. For now, one of the roles that I am assuming is to oversee the “test pass”. This is basically a set of product wide runs that all QA teams in the division must do to ascertain the state of the product against team expectations.&lt;/p&gt;  &lt;p&gt;The moral of the story comes as we were ready to start a test run and I asked when it would be ready for testers to analyze it: “two days”. Wait, what? Two days? It takes 48 HOURS to execute our tests? I was told that’s what it always takes. I took a calculator and went to my office.&lt;/p&gt;  &lt;p&gt;Turns out the type of run that we wanted to run generated 9,000 results. Each test takes an average of 3 minutes to run, don’t ask me why right now, just work with me. That is 27,000 minutes. That’s 450 hours, or 18 days. So, if I wanted my results to be done in one night, or 12 hours of execution, I need roughly 35 machines. And how many machines do we use in our runs? Eight. I asked why? It’s not as if we are in a super shortage of machines in our lab. There didn’t seem to be a good reason, eight just seemed to be a “good” number and we had “learned” to live with it.&lt;/p&gt;  &lt;p&gt; We are now running with ~30 machines and I expect to see the results tomorrow.&lt;/p&gt;  &lt;p&gt;- Federico&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-2882378839374713439?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/2882378839374713439/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2009/10/working-with-numbers-and-common-sense.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/2882378839374713439'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/2882378839374713439'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2009/10/working-with-numbers-and-common-sense.html' title='Working with numbers and common sense'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-8310012158946237013</id><published>2009-10-17T19:31:00.001-07:00</published><updated>2009-10-17T19:31:36.356-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Random Tales'/><title type='text'>Has anybody used Concordion?</title><content type='html'>&lt;p&gt;Leonid pointed me to this framework/tool back in August but I hadn’t had time to check it out. It is called &lt;a href="http://www.concordion.org/"&gt;Concordion&lt;/a&gt;, and it looks like a very interesting way of writing acceptance test that read pretty much like a spec. You basically generate a set of linked HTML pages that read as a&amp;#160; functional specification, but by putting special syntax in them you can call into your test fixture code that can interact with the system under test.&lt;/p&gt;  &lt;p&gt;At first glance it sounds like a ton of work, but then again I don’t have a lot of experience writing end user applications in a team with agile methods (writing and testing a framework like ASP.NET is not quite the same as writing a testing an Amazon). &lt;/p&gt;  &lt;p&gt;If you have experience using this kind of spec-to-code approach I would be very interested in hearing your experience. Drop me a line!&lt;/p&gt;  &lt;p&gt;- Federico&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-8310012158946237013?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/8310012158946237013/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2009/10/has-anybody-used-concordion.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/8310012158946237013'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/8310012158946237013'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2009/10/has-anybody-used-concordion.html' title='Has anybody used Concordion?'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-3994349321549903599</id><published>2009-10-17T19:18:00.001-07:00</published><updated>2009-10-17T19:18:16.820-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Random Tales'/><title type='text'>Presenting at DevConnections</title><content type='html'>&lt;p&gt;Hey everyone, I got a talk lined up for November in &lt;a href="http://www.devconnections.com/"&gt;DevConnections&lt;/a&gt; about Testing ASP.NET. Here is the abstract:&lt;/p&gt;  &lt;p&gt;&lt;em&gt;&lt;b&gt;AMS09: Testing in ASP.NET&lt;/b&gt;      &lt;br /&gt;&lt;/em&gt;&lt;a href="http://www.devconnections.com/shows/FALL2009ASP/default.asp?c=2&amp;amp;s=135&amp;amp;i=2270"&gt;&lt;b&gt;&lt;em&gt;Federico Silva Armas&lt;/em&gt;&lt;/b&gt;&lt;/a&gt;    &lt;br /&gt;&lt;em&gt;As more people in the community and organizations recognize the value of testing, developers are sometimes left with the challenge of testing ASP.NET. With so many tools and approaches, it is difficult to decide what to invest in. In this introductory sessions for developers and testers alike, we'll explore different tools and strategies for testing an ASP.NET Web application. We'll focus on how to write functional tests using a variety of tools and how you can leverage them in your next project. We will also discuss some of the lessons that the ASP.NET QA team has learned while testing ASP.NET.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;I am still unsure about the audience (I have never been to DevConnections before), so I hope I don’t shoot wildly off the mark. I will be talking mostly about tools and strategies to write functional automated tests. I plan to show off LTAF, Selenium and WatiN. Hopefully get the audience excited and interested in test automation.&lt;/p&gt;  &lt;p&gt;- Federico&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-3994349321549903599?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/3994349321549903599/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2009/10/presenting-at-devconnections.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/3994349321549903599'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/3994349321549903599'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2009/10/presenting-at-devconnections.html' title='Presenting at DevConnections'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-1676335735886225019</id><published>2009-10-14T20:08:00.001-07:00</published><updated>2009-10-14T20:08:51.857-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Random Tales'/><title type='text'>Using a unit testing harness to execute functional tests</title><content type='html'>&lt;p&gt;As I am preparing for my talk at DevConnections, one of the things that I was advised to demonstrate is how to incorporate LTAF tests into MSTest&amp;#160; or NUnit. The idea is not new as certainly that’s one of the preferred ways to author Selenium or WatiN tests (if I am totally wrong, please correct me).&lt;/p&gt;  &lt;p&gt;Personally, the idea of using a tool that was designed for unit testing to write and run functional tests is a little awkward. My reasons for this are:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Functional tests need a better logging mechanism than simple asserts and exceptions. Our harness produces super cool logs that contains the HTML at each step of a test, with visualizers to see what rules failed, debug them and fix them. It is definitely leaps forward than the exception reporting of a unit test harness. &lt;/li&gt;    &lt;li&gt;Functional tests need a better test manager. What I have seen of unit test tools is some support for creating list of tests, but a formal test manager system will include additional test metadata like requirements, description, abstract, list of scenarios, contexts, several ways to organize them and dependencies. &lt;/li&gt;    &lt;li&gt;Functional tests need more advanced analysis support. A unit test tool basically &amp;quot;runs and forgets” tests, it shows you the results of the current run and some support storing data of past runs. But a good functional testing harness will provide tools like comparing results of many runs, can track what was the reason for failure of each result, it can group failures that seem to be related to make it easier to analyze, it can check the bug database to see if there are similar problems to the one you are analyzing, it can correlate how much of the product code each test touches, it can organize and display the results when there are thousands of tests into views that are useful for a test team. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;These are all things that are possible with the tools that we use internally in DevDiv. Now, you can argue that you can accomplish all of these with MSTest or NUnit or whatever, and that may be true. What I am saying is that functional tests have a specific set of requirements that having a specialized harness for functional tests makes more sense to me than trying to coerce a set of tools that were designed for dev unit tests.&lt;/p&gt;  &lt;p&gt;What do you guys think? You like using a tool like MSTest or NUnit to write and execute functional tests?&lt;/p&gt;  &lt;p&gt;- Federico&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-1676335735886225019?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/1676335735886225019/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2009/10/using-unit-testing-harness-to-execute.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/1676335735886225019'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/1676335735886225019'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2009/10/using-unit-testing-harness-to-execute.html' title='Using a unit testing harness to execute functional tests'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-2295539919032219969</id><published>2009-10-13T23:25:00.001-07:00</published><updated>2009-10-13T23:25:14.574-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Random Tales'/><title type='text'>The role of QA</title><content type='html'>&lt;p&gt;I was in a meeting recently with some higher ups in our team, we were reviewing some bugs to make a decision on whether to fix them in this milestone, and there was a comment from one of the managers that went like: “QA’s job is to measure quality, not to improve it”.&lt;/p&gt;  &lt;p&gt;That was interesting for me and gave a little insight on how our discipline is sometimes perceived by others. The tester that had opened the bug had written comments in there that specified what he thought the correct behavior of the product should be, giving a very specific way that the product should be changed. Regardless whether his recommendation was workable or totally unrealistic, I thought it was great that our testers were beginning to contribute with design suggestions. However, the rest of the persons in this meeting were very quick to dismiss it because “he didn’t know what he was talking about”. &lt;/p&gt;  &lt;p&gt;I don’t doubt that there was some reason why the recommendation was not feasible, but to discourage a tester from opening suggestions and just stick to reporting what doesn’t work according to design felt contradictory to what I am trying to achieve in our team. I felt bad for the tester that spent time thinking of what a better experience should be, describing it in full with repro steps and scenarios, only to be shot down with an implied message of “don’t waste your time with these”.&lt;/p&gt;  &lt;p&gt;We have a long ways to go as a discipline, and I hope that as we demonstrate that QA can bring more value than just measuring quality we can start turning the corner on perception.&lt;/p&gt;  &lt;p&gt;- Federico&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-2295539919032219969?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/2295539919032219969/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2009/10/role-of-qa.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/2295539919032219969'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/2295539919032219969'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2009/10/role-of-qa.html' title='The role of QA'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-1003449829753607629</id><published>2009-09-13T20:46:00.001-07:00</published><updated>2009-09-13T20:46:35.283-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Random Tales'/><title type='text'>Selenium testers, help me!</title><content type='html'>&lt;p&gt;As I was preparing for my talk, I ran into the problem described &lt;a href="http://stackoverflow.com/questions/1419532/problem-using-selenium-to-automate-a-postback-link-that-is-inside-an-asp-net-upda"&gt;here&lt;/a&gt;. I’ll be the first to admit that I have not used Selenium in over 2 years (yikes!), so hopefully what I am running into is known and has an easy work around:&lt;/p&gt;  &lt;p&gt;“I have a GridView control with sorting enabled inside an UpdatePanel. I used Selenium IDE to record a test that clicks on the sort link of the table, but when I try to execute the test it get's stuck on the click command. Looking at the log I see:&lt;/p&gt;  &lt;pre&gt;&lt;code&gt;[info] Executing: |click | link=Name | | &lt;br /&gt;[error] Timed out after 30000ms&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;I haven't tried it with Selenium-RC yet, I don't know if it will be any different. I don't want Selenium to wait for anything. Any ideas of how to work around it?”&lt;/p&gt;&lt;br /&gt;&lt;br /&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/1641812635873375394-1003449829753607629?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/1003449829753607629/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2009/09/selenium-testers-help-me.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/1003449829753607629'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/1003449829753607629'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2009/09/selenium-testers-help-me.html' title='Selenium testers, help me!'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-6614894147998203333</id><published>2009-09-13T20:27:00.001-07:00</published><updated>2009-09-13T20:27:10.167-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Random Tales'/><title type='text'>Presenting at DevConnections</title><content type='html'>&lt;p&gt;Whoa, it’s been a long time since my last post. I have to pick up the slack. &lt;/p&gt;  &lt;p&gt;First I want to announce that I will be presenting at &lt;a href="http://www.devconnections.com/"&gt;DevConnections&lt;/a&gt; in Las Vegas this year. Even though it is not the first time that I do a talk at a conference, it is the first time that is a regular break out session. &lt;/p&gt;  &lt;p&gt;The topic of my presentation is testing in ASP.NET. The description is listed &lt;a href="http://www.devconnections.com/shows/FALL2009ASP/default.asp?c=1&amp;amp;s=135"&gt;here&lt;/a&gt;, but I copy it below:&lt;/p&gt;  &lt;p&gt;&lt;b&gt;AMS09: Testing in ASP.NET&lt;/b&gt;    &lt;br /&gt;&lt;a href="http://www.devconnections.com/shows/FALL2009ASP/default.asp?c=2&amp;amp;s=135&amp;amp;i=2270"&gt;&lt;b&gt;Federico Silva Armas&lt;/b&gt;&lt;/a&gt;    &lt;br /&gt;As more people in the community and organizations recognize the value of testing, developers are sometimes left with the challenge of testing ASP.NET. With so many tools and approaches, it is difficult to decide what to invest in. In this introductory sessions for developers and testers alike, we'll explore different tools and strategies for testing an ASP.NET Web application. We'll focus on how to write functional tests using a variety of tools and how you can leverage them in your next project. We will also discuss some of the lessons that the ASP.NET QA team has learned while testing ASP.NET.&lt;/p&gt;  &lt;p&gt;Mmh, I need to figure out how to put my Bio in the DevConnections site…&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-6614894147998203333?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/6614894147998203333/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2009/09/presenting-at-devconnections.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/6614894147998203333'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/6614894147998203333'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2009/09/presenting-at-devconnections.html' title='Presenting at DevConnections'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-7256161083202490115</id><published>2009-08-23T10:39:00.001-07:00</published><updated>2009-08-23T10:39:30.985-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Random Tales'/><title type='text'>Nice post from Telerik's QA dept.</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;Today I found myself quoted in this nice &lt;b&gt;&lt;a href='http://blogs.telerik.com/testing/posts/08-12-08/don_ts_in_software_testing.aspx'&gt;post&lt;/a&gt;&lt;/b&gt; by Konstantine Petkov, I can't remember if this was always the case, but the post is now part of the Telerik's QA blog. I am now following it since I am very interested in their new automation tool which looks awesome.&lt;br/&gt;&lt;br/&gt;- Federico&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img src='http://img.zemanta.com/pixy.gif?x-id=86f21ddb-f70d-86a9-b3e2-1b26f5c3e4e0' alt='' class='zemanta-pixie-img'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-7256161083202490115?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/7256161083202490115/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2009/08/nice-post-from-telerik-qa-dept.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/7256161083202490115'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/7256161083202490115'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2009/08/nice-post-from-telerik-qa-dept.html' title='Nice post from Telerik&amp;#39;s QA dept.'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-1852889283196875053</id><published>2009-08-22T14:20:00.001-07:00</published><updated>2009-08-22T14:20:47.989-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='LTAF'/><title type='text'>Another LTAF blog post</title><content type='html'>&lt;p&gt;Matthew recently pointed me to this &lt;a href="http://www.sontek.net/post/Integration-Tests-with-Lightweight-Test-Automation-Framework-%28LTAF%29-and-ASPNET.aspx"&gt;blog post&lt;/a&gt; by John Anderson that talks about Lightweight Test Automation Framework. &lt;/p&gt;  &lt;p&gt;I understand that there is some confusion around how LTAF positions itself against Selenium and other automation tools. I am working on a blog post to try to clarify this point. For now you can learn some more about it in &lt;a href="http://www.codingqa.com/index.php?post_id=461458"&gt;CodingQA Podcast Episode #1&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;- Federico&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-1852889283196875053?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/1852889283196875053/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2009/08/another-ltaf-blog-post.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/1852889283196875053'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/1852889283196875053'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2009/08/another-ltaf-blog-post.html' title='Another LTAF blog post'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-343257625107245005</id><published>2009-08-21T19:15:00.000-07:00</published><updated>2011-05-18T02:00:51.106-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Testing'/><title type='text'>Change the process or change the team?</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;Lately I have been reading about Scrum (book called “&lt;a href="http://www.amazon.com/Agile-Project-Management-Microsoft-Professional/dp/073561993X"&gt;Agile Project Management with Scrum&lt;/a&gt;”). I figured that I had never actually read a formal book about this methodology, and it was a book that we got for free in our team (although to my knowledge we have never done Scrum). One of the things that I found interesting is the way that it talks about change.     &lt;br /&gt;    &lt;br /&gt;According to the majority of this book, Scrum is a set of practices and rules that an organization can follow to achieve great results, and it goes to lengthy explanations of how the organization had to be changed to adopt Scrum. There is very little said about how to change Scrum to fit an organization. There are even certification seminars that one can attend to be a ScrumMaster.    &lt;br /&gt;    &lt;br /&gt;The reason why this is interesting to me is because the approach that I used to transmit test methodology within my team is so different. Scrum presents itself as a process that is already a proven best practice, and as long as you can change the team to follow it you’ll see the goodness. I operate under the assumption that the process that I come up with hasn’t been validated until it can be successfully used by my team. In other words, I fully expect to change the process so that it adapts to the circumstances and particularities of my team.    &lt;br /&gt;    &lt;br /&gt;Am I miss reading this? Maybe the book that I got isn’t very good, and I’ll just assume that successful implementations of Scrum actually change the process to adapt it to the circumstance. Anybody has experience with it that they want to share?&amp;#160; &lt;br /&gt;    &lt;br /&gt;- Federico    &lt;br /&gt;    &lt;div class="zemanta-pixie"&gt;&lt;/div&gt; &lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-343257625107245005?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/343257625107245005/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2009/08/change-process-or-change-team.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/343257625107245005'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/343257625107245005'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2009/08/change-process-or-change-team.html' title='Change the process or change the team?'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-4126652747961215769</id><published>2009-08-03T20:45:00.000-07:00</published><updated>2011-05-18T02:00:36.366-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Testing'/><title type='text'>QA Myth #1: “I can’t work without a spec!”</title><content type='html'>&lt;p&gt;One of the complaints that some times I hear in my team is the bad state of the design specs, or how late we get them. This is rooted in the original way of doing development in MS, where the PM is responsible for writing a very detailed specification that the Dev then uses to come up with an implementation that matches its requirements, and that QA uses to create test cases. You can image how under this model, if a spec is not produced it is cause for much grief on the tester that otherwise has no way of knowing what the feature is going to do.&lt;/p&gt;  &lt;p&gt;Don’t get me wrong, an agile team needs a why to document design, be it email, notes on a board, or hallway conversations (whatever works), but when a tester is “blocked” because the lack of a spec is sign of bad QA culture. I have two problems with this:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;The belief that a full blown specification is required to successfully test a product.&lt;/li&gt;    &lt;li&gt;The belief that a specification is something that happens externally from QA.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;The first one I consider a skill of a good tester. So what if you don’t have a written specification? You have the code and you know the customer’s problems that the feature is meant to solve. And if you don’t, you have the rest of the team (Dev, QA, PM, UE) to go and figure it out. All you need is to figure out one way to call into the feature, and from there put yourself in the shoes of your customer and use the feature in all ways that you can come up with. Is it doing what you expect? No? Raise an issue. Are there problems that it doesn’t address? Yes? Raise an issue. Is it too hard to figure out how to use it? Yes? Raise an issue. &lt;/p&gt;  &lt;p&gt;The key is to constantly talk to your team. Is there anything else that the feature can do that you haven’t discovered? Are there any known cases where it won’t work? Are you ok with that? This is another reason why I love exploratory testing, it can be adapted very well to &lt;strong&gt;discover&lt;/strong&gt; functionality. &lt;/p&gt;  &lt;p&gt;The second problem I believe is cultural. When a QA person starts waiting and demanding that a spec be written so that he/she can do their job, they are implicitly promoting a return to a waterfall model. It can be very subtle, but what they are saying is “look, coming up with the design is not my job, you just tell me what the thing is supposed to do, and I’ll figure out how to test it. And don’t leave any details out, otherwise I am going to miss scenarios”. In contrast, a good QA person wants to be involved in the design, and puts him/herself where the design happens and gives input. He knows exactly what is being implemented because he/she was part of designing it.&lt;/p&gt;  &lt;p&gt;Whenever I start hearing that a QA team got in problems or is blocked because of lack of good specs, its a sign that some change in the way they develop software and they think of themselves might be needed.&lt;/p&gt;  &lt;p&gt;- Federico&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-4126652747961215769?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/4126652747961215769/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2009/08/qa-myth-1-i-cant-work-without-spec.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/4126652747961215769'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/4126652747961215769'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2009/08/qa-myth-1-i-cant-work-without-spec.html' title='QA Myth #1: “I can’t work without a spec!”'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-627768710616577061</id><published>2009-07-31T20:50:00.000-07:00</published><updated>2011-05-18T02:00:51.106-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Testing'/><title type='text'>Evolution of the ASP.NET Test Process (Part 2)</title><content type='html'>&lt;p&gt;&lt;em&gt;This series was originally seen on the &lt;a href="http://weblogs.asp.net/asptest/"&gt;ASP.NET QA team blog&lt;/a&gt; and never finished. I decided to continue it on my personal blog as its my own opinions of our processes.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;This is the second part of a short narration that describes how the testing process has evolved in the ASP.NET QA Team. First part can be found &lt;a href="http://testertales.blogspot.com/2009/07/evolution-of-aspnet-test-process-part-1.html"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;The Feature Crew Model&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;After the release of .NET 2.0, all of Developer Division underwent a general change in the way we built software. This change came from top-down, and it was called the &amp;quot;Feature Crew Model'. I remember that all DevDiv made a lot of preparations for this new methodology, taking months out of development time to build a lot of infrastructure and tools to make it happen. Soma must be recognized for taking this bold step across the division. The basics are:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Each Product Unit (PU) inside DevDiv would divide their release into features. A &amp;quot;feature&amp;quot; meant a logical sub component of the product, that in theory could be developed independently. &lt;/li&gt;    &lt;li&gt;A feature crew would be created from resources from the PM, Dev and QA disciplines and they would be given some degree of autonomy to shape the feature and manage their milestones. &lt;/li&gt;    &lt;li&gt;A feature crew would develop everything on a separate independent branch. &lt;/li&gt;    &lt;li&gt;A series of Quality Gates were put in place and only after a feature passed all of them, would the code be permitted to integrate into the main product branch. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;The key part of this process was that it enforced a high level of quality before each individual piece made it into the build, and that each piece was finished. This was a big improvement because in the past there was a lot code churn happening on the main branch from all over the division that generated a lot of regressions. The second benefit was that this way of working encouraged better communication between Dev and Test, and allowed for teams that wanted to experiment with SCRUM or other agile methodologies.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Our First Feature Crews (ASP.NET Ajax 1.0 Release)&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Our team's first encounter with this process was during a project code named Atlas (later to be known as ASP.NET AJAX). Back then, nobody was really sure how this would work out (and there wasn't a lot of guidelines coming from the division either), so it was understood that we would experiment and modify as we went. &lt;/p&gt;  &lt;p&gt;Atlas was divided into the following feature crews (they were kicked off in this order, since subsequent crews relied on the previous):&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Core: which included the type system and BCL. &lt;/li&gt;    &lt;li&gt;Networking: everything under Sys.Net &lt;/li&gt;    &lt;li&gt;Partial Rendering: UpdatePanel (this is the feature crew that I worked on, along side Eilon Lipton) &lt;/li&gt;    &lt;li&gt;UpdateProgress/Timer: targeted crews for only these 2 controls. &lt;/li&gt;    &lt;li&gt;Services: script callable Membership, Profile and Roles services. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;ASP.NET QA Process in a Feature Crew&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Looking back, the QA team didn't made any substantial changes from our old process, we were too busy preparing for having our test sources in different branches. So the QA process ended up being:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;QA resources would be assigned to a feature crew. &lt;/li&gt;    &lt;li&gt;Dev/PM/Test would start working on the feature at the same time, on an independent branch. &lt;/li&gt;    &lt;li&gt;Dev was now responsible for writing UnitTests &lt;/li&gt;    &lt;li&gt;Each feature crew would meet at least 3 times a week to design the feature and provide status updates. (The crew was in charge of costing all work, and arranging it in milestones. At the end of each milestone, the crew would integrate the progress into main). &lt;/li&gt;    &lt;li&gt;As the design was being developed, the PM worked on the spec, Dev on prototypes and QA on the test plan. &lt;/li&gt;    &lt;li&gt;QA would have a test plan review as before. &lt;/li&gt;    &lt;li&gt;QA would start testing the feature as soon as code was checked in by Dev, and would start writing automation. &lt;/li&gt;    &lt;li&gt;Progress was still tracked by automation complete numbers. &lt;/li&gt;    &lt;li&gt;QA was responsible of signing off a number of items on the Quality Gates check list. Of importance, is the fact a quality gate was to be automation complete, and to have run all test in a number of configuration runs. &lt;/li&gt;    &lt;li&gt;After all quality gates were met, feature was integrated to Main. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;How did it Work?&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Benefits      &lt;ul&gt;       &lt;li&gt;Better collaboration between disciplines (we were all on the same boat to get our stuff integrated). &lt;/li&gt;        &lt;li&gt;QA was involved in the design. &lt;/li&gt;        &lt;li&gt;Code that entered the build was of high quality already. &lt;/li&gt;        &lt;li&gt;Dev's wrote unit tests which caught bugs earlier. &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;Disadvantages      &lt;ul&gt;       &lt;li&gt;Probably the biggest problem was that QA still tried to do everything that we used to do on a 2-3 year release, but now on a compressed 3-4 months iterations. Because we didn't change anything in our process, we now really became the bottle neck. &lt;/li&gt;        &lt;li&gt;QA was still creating full featured test plans and focused heavily on automation, for features that now changed even more often. &lt;/li&gt;        &lt;li&gt;Overlap between dev unit tests and QA functional tests, the old mentality of &amp;quot;test everything&amp;quot; did not go away. &lt;/li&gt;        &lt;li&gt;Dependencies between crews created version problems that sometimes got crews blocked. &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;In the end, the team pushed quality up stream, but the QA team bled and struggled a lot. And some of the problems that we had identified before began happening again, in particular, finding bugs to late. My opinion is that after Atlas was shipped, the team had a better development process that put quality first and helped the QA team, but our own QA processes still needed to adapt to this new way of doing things. &lt;/p&gt;  &lt;p&gt;In the next part I'll narrate how the QA team reinvented its methodology for the next ASP.NET release, and how it did it from the bottom up. &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-627768710616577061?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/627768710616577061/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2009/08/evolution-of-aspnet-test-process-part-2.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/627768710616577061'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/627768710616577061'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2009/08/evolution-of-aspnet-test-process-part-2.html' title='Evolution of the ASP.NET Test Process (Part 2)'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-5429809231566790024</id><published>2009-07-26T18:17:00.001-07:00</published><updated>2011-05-18T02:00:51.107-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Testing'/><title type='text'>Evolution of the ASP.NET Test Process (part 1)</title><content type='html'>&lt;p&gt;&lt;em&gt;This series was originally seen on the &lt;a href="http://weblogs.asp.net/asptest/"&gt;ASP.NET QA team blog&lt;/a&gt; and never finished. I decided to continue it on my personal blog as its my own opinions of our processes.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;For those of you interested in testing methodologies, in these series of posts I'll go over how the QA team has changed the way we test ASP.NET over the years. I have been in the team for over 6 years now and have witnessed several transitions (most of which I think are for the better).&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;The Early Days (.NET 1.0, 1.1 and 2.0)&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;I joined the team when .NET 1.1 was about to be released and the team was getting ready to work on 2.0 (which turned out to be a major and lengthy release). Back then the general QA process was:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;By the time the QA team finished testing and singing off on a release, the next release was well under development. There is usually a &amp;quot;stabilization&amp;quot; time at the end of a release where the QA team is busy writing automated tests, running them under all sorts of configurations and going through a list of checks called &amp;quot;Exit Criteria&amp;quot;. This meant that Dev/PM were off prototyping and designing the features of the next release while we were fully engaged testing the current release. &lt;/li&gt;    &lt;li&gt;The QA team divided the features between its members, taking into account interest and affinity. This was called &amp;quot;owning&amp;quot; a feature. When I very first started I was the owner of the new GridView and Login controls. At that point, the spec was pretty much finished, and the controls were already checked into the build. &lt;/li&gt;    &lt;li&gt;The first thing to do was to write a test plan. What this meant was to define the totality of tests that you planned to verify and automate. These documents were very descriptive and usually amounted to many pages. We entered the tests into an internal tool that DevDiv uses called &amp;quot;Maddog&amp;quot;. &lt;/li&gt;    &lt;li&gt;This test plan got reviewed by the PM and the Dev of the feature and by fellow testers to try and uncover anything missing or worthy of expansion. &lt;/li&gt;    &lt;li&gt;Next came the main testing phase where the tester divided his/her time between performing &amp;quot;ad-hoc&amp;quot; (which meant playing with the features trying out all sorts of scenarios to uncover defects), and writing automation. &lt;/li&gt;    &lt;li&gt;Progress was tracked by the number of tests automated that were defined in the test plan. For example, a test plan defined 200 tests (with different priorities) and we would report status of how many tests were left to automate and that's how we scheduled the remaining work. &lt;/li&gt;    &lt;li&gt;One thing to note is that the Developers were not writing any UnitTests back then. &lt;/li&gt;    &lt;li&gt;At some point, the team would start to kick off runs. This means grabbing all tests in the repository and running them on many different platforms and configurations to uncover any possible defects. In this phase the time of a tester was divided between writing automation and analyzing the inevitable failures of each run. &lt;/li&gt;    &lt;li&gt;This is were we entered the &amp;quot;stabilization&amp;quot; time for the release that I mentioned at the beginning. Making lab runs on different SKU's, languages, side by side, x32 and x64, stress, perf, etc. &lt;/li&gt;    &lt;li&gt;After many months, at last we would have finished automating all the tests and have them executing on all the runs. Any bugs found were logged, and either fixed or postponed. At this point each feature owner would sign off, and the product would be shipped. (A similar process was repeated for every beta release as well). &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Problems with this model&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Over-Automation      &lt;ul&gt;       &lt;li&gt;By placing too much focus on automation, the tester spent more time writing and debugging a huge amount of regression tests rather than trying scenarios on the product. &lt;/li&gt;        &lt;li&gt;There was a philosophy of leaving no stone unturned and to automate everything that you could think of. &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;High cost of change      &lt;ul&gt;       &lt;li&gt;ASP.NET is a framework, and frameworks go through many revisions and changes before they are released. However, our QA process was not designed to accommodate this. The QA methodology consistently tried to lock down details too early. &lt;/li&gt;        &lt;li&gt;We spent a lot of time writing fully detailed test plans based on the spec for things that were bound to change a lot, and immediately after test plan creation we launched ourselves into an automation frenzy. &lt;/li&gt;        &lt;li&gt;What ended up happening is that changes in the design of a feature where disastrous, the cost of updating all test plans and all the previously written automation was very high. &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;No UnitTests      &lt;ul&gt;       &lt;li&gt;The QA team was responsible for testing everything, from passing every possible value to each public method of a class to end to end integration tests. This amounted to a TON of tests written by QA. &lt;/li&gt;        &lt;li&gt;Since the only automated mechanism to find regressions was the QA tests it was common for the builds to be broken regularly. &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;QA team found bugs to late      &lt;ul&gt;       &lt;li&gt;A side effect of our automation story was that scenarios were not verified until it came time to automate the test, which usually meant months after the feature was coded. &lt;/li&gt;        &lt;li&gt;All this miss placed effort meant that bugs where found later rather than sooner. &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;QA team did not start at the same time as Dev/PM.      &lt;ul&gt;       &lt;li&gt;In some ways this fact set us up to be the long pole of the team. There were occasions where the Dev had completed all his/her work, but the QA team still had months and months of work to go through. &lt;/li&gt;        &lt;li&gt;It was also common practice for the QA members to have little input on the design of the product. By the time we became fully engaged, most of the features were already designed and implemented. &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;How we survived&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;By reading this post you may be disappointed by our team, but keep in mind that I only focused on the &amp;quot;bad&amp;quot; things of the way we used to do things 6 years ago. I believe that regardless of the limitations of our approach the release had a high quality bar. The problems that I mention here, plus the problems with the Dev's process and with our automation infrastructure, all these together are one of the reasons why the .NET 2.0 release took such a long time. Luckily, most of these have been addressed during subsequent releases, and I'll go through the changes that we made and how well they worked in following posts. Maybe you can learn something from our experience...&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-5429809231566790024?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/5429809231566790024/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2009/07/evolution-of-aspnet-test-process-part-1.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/5429809231566790024'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/5429809231566790024'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2009/07/evolution-of-aspnet-test-process-part-1.html' title='Evolution of the ASP.NET Test Process (part 1)'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-6339112587407508019</id><published>2009-07-26T18:12:00.001-07:00</published><updated>2011-05-18T02:00:51.107-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Testing'/><title type='text'>I am a “subjective” person…</title><content type='html'>&lt;p&gt;Last week I was reminded by a coworker what the agile manifesto statement of “People over Process” means. We were having a hallway discussion whether the QA team had a process for analyzing the root cause of test failures over time. For me the point wasn’t whether we had a process like that or not, but rather whether we needed to impose a team wide process like that or not. &lt;/p&gt;  &lt;p&gt;I have a bit of a problem with processes that do not give enough value, and I try to always ask 3 simple questions:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;What is the problem that this is trying to solve?&lt;/li&gt;    &lt;li&gt;Is fixing the problem really worth it?&lt;/li&gt;    &lt;li&gt;If it is, is this the only way to fix it?&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;I should mention that the individuals in our QA team are divided into cross-discipline “feature crews” that are in charge of developing several features within ASP.NET, and you can imagine that each crew has a different problem space, which is why context-driven testing is so valuable to me.&lt;/p&gt;  &lt;p&gt;In this particular case, the tester wanted a process that he could use to know when it made sense to invest in re-writing tests that failed often. A worthy cause, but was it high enough to go and pay the overhead tax of creating, documenting and transmitting this new “process” for the whole team? &lt;/p&gt;  &lt;p&gt;Even though I oversee test methodologies across the QA team, I work more closely with the MVC crew (what I consider my crew) and we have put such processes in place that we didn’t really have a need for the new process. I mean, we run all our tests very often (twice&amp;#160; day), they pass all the time, and if they don’t we fix them relatively quickly. We run them so frequently that if a test begins failing often, we would notice and take action. At least I didn’t feel my crew needed to follow and be monitored by some team wide process to find this out. For this I was called a “subjective” person, because I didn’t need tabulated data and some process to measure it and make a call.&lt;/p&gt;  &lt;p&gt;And that is really the key: in the context of &lt;em&gt;our&lt;/em&gt; crew, and the way that &lt;em&gt;we&lt;/em&gt; work, we don’t need this process. Maybe in the context of some other crew, that makes sense, and hard historical data analysis is required. That is what “people over process” means to me: that people are empowered to create whatever processes makes sense for their project to be successful. What we don’t want is to impose and maintain a barrage of processes for the whole team unless it has a high enough value for everyone.&lt;/p&gt;  &lt;p&gt;Another thought: I suppose that at the end there are some persons that need more structured and highly defined processes than others, and this adds an interesting dynamic to a team. How much should we standardize and how much should we leave flexible for each feature crew? I am still not quite sure what the right balance is.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-6339112587407508019?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/6339112587407508019/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2009/07/i-am-subjective-person.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/6339112587407508019'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/6339112587407508019'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2009/07/i-am-subjective-person.html' title='I am a “subjective” person…'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-4027775326620659235</id><published>2009-07-20T19:46:00.001-07:00</published><updated>2011-05-18T02:00:51.108-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Testing'/><title type='text'>How to learn exploratory testing?</title><content type='html'>&lt;p&gt;One of the process changes that I have been in charge of in the team is to use &lt;a href="http://en.wikipedia.org/wiki/Exploratory_testing"&gt;exploratory testing&lt;/a&gt; as a technique to discover bugs earlier. Not only am I a huge a fan of exploratory testing, I am of those who believe that it takes skill and training to be truly good at it. And that’s what this post is about, how does someone “learn” something as subtle as exploratory testing.&lt;/p&gt;  &lt;p&gt;I’ll start by saying that ET can’t be learned, is more of an acquired taste, and as such, there are some people that can really identify with it, and others that could not care less. If I think of myself, the reasons why I got convinced that this testing approach works were:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;I could very easily identify the problems with the way we did testing in our team.&lt;/li&gt;    &lt;li&gt;I was willing to try something new.&lt;/li&gt;    &lt;li&gt;I practiced and practiced and practiced.&lt;/li&gt;    &lt;li&gt;I made the methodology my own by tweaking it.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;I had the luck of working with another tester that was equally passionate about agile testing that we could experiment together. We would sit together, testing whatever we could find, taking notes and reviewing our results. I don’t think I will ever claim that I am a master at it, since there is always ways to improve, but now I am very proficient at taking good notes, coming up with good scenarios and fishing out bugs (Note: being a lead has severely decreased the time that I have to keep practicing, which is definitely a downside for me. I am already feeling that I am getting rusty at it).&lt;/p&gt;  &lt;p&gt;Once we were convinced that this methodology would work for our product, the real challenge was how to transmit this to the rest of the QA team. In particular:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Even though we had made a fair amount of research, you can’t really teach ET by theory alone, just having a presentation wasn’t enough.&lt;/li&gt;    &lt;li&gt;Most of the team could not relate with the problems that we used to have because they weren’t here when we had them.&lt;/li&gt;    &lt;li&gt;Some people were not willing or did not see the need to try something new.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;The best thing that I could come up with was to slowly introduce the concept in some “pilot” feature crews. Where I would act as the “expert” and coach other testers using the methodology. This worked fine in most cases, because I would spend a lot of time in ET sessions with other testers, and we would practice and discuss together. The problem was that I could not do this for all the team members for lack of time.&lt;/p&gt;  &lt;p&gt;Eventually, the value of ET was obvious to the team, that we decided to roll out the methodology for the VS2010 release cycle. The idea was that I would do some hands on training with everyone (in groups of 4) and then a group of senior testers would act as coaches overseeing how this worked with all crews. However, one problem that we faced was that due to resources all coaches ended being sucked into feature crews of their own, and so where not available as true coach resources. &lt;/p&gt;  &lt;p&gt;Following my belief that ET is about skills and practice, I established a bi-weekly optional session where testers interested would get together and practice testing software. Unfortunately, most team members don’t attend, they either don’t have time or they think this is not useful at all.&lt;/p&gt;  &lt;p&gt;The end result, in my opinion, is that overall our team took a step in the right direction but we are still missing that last mile where we practice ET as a highly disciplined skill instead of just a process. And this takes a personal commitment and lots of practice. &lt;/p&gt;  &lt;p&gt;I am interested in hearing your comments: Do you use ET in your work? How do you “teach” it to other team members? How do you manage a team of exploratory testers?&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-4027775326620659235?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/4027775326620659235/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2009/07/how-to-learn-exploratory-testing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/4027775326620659235'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/4027775326620659235'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2009/07/how-to-learn-exploratory-testing.html' title='How to learn exploratory testing?'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-3570310092554892045</id><published>2009-07-15T22:39:00.001-07:00</published><updated>2009-07-15T22:39:23.253-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Random Tales'/><title type='text'>Meeting Frenzy</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;Today I was reminded of why some times it feels like we move so slowly in my team and in Microsoft. Here is how my day looked like:&lt;br/&gt;&lt;br/&gt;9am: Mail/Work&lt;br/&gt;10am: Meeting&lt;br/&gt;11am: Meeting&lt;br/&gt;12:30: Lunch&lt;br/&gt;1pm: Work&lt;br/&gt;2:30pm: Meeting&lt;br/&gt;3pm: Meeting&lt;br/&gt;4pm: Meeting&lt;br/&gt;5pm: Meeting&lt;br/&gt;&lt;br/&gt;I don't know if it's being a lead, but with all these meetings its a wonder I get to test software at all. What few hours I get in front of my computer I have to work as a fast madman to get stuff done. It's this the same in other companies? Or do we have a case of Meetinguitis in my team?&lt;br/&gt;&lt;br/&gt;- Federico&lt;br/&gt;&lt;br/&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-3570310092554892045?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/3570310092554892045/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2009/07/meeting-frenzy.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/3570310092554892045'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/3570310092554892045'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2009/07/meeting-frenzy.html' title='Meeting Frenzy'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-7844658221658603181</id><published>2009-07-14T20:43:00.001-07:00</published><updated>2011-05-18T01:59:49.673-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Random Tales'/><title type='text'>Finally tackling the ASP.NET QA “Boat Anchor”</title><content type='html'>&lt;p&gt;We have mentioned several times in the CodingQA podcast the problem of our oversized test bed. I am happy to tell that we are now seriously looking at addressing it. In this series of blog posts I’ll describe our progress, as well as our approach.&lt;/p&gt;  &lt;p&gt;First thing, what is the problem? I thought that the facts would illustrate our current situation better than anything:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;We currently have ~ 20,000 functional tests that have been accumulating since .NET 1.0&lt;/li&gt;    &lt;li&gt;In average, each test has at least 3 contexts that it runs with (for example, a test might run with IE and FireFox browsers, but it is not unlikely to see tests with 5 or 10 contexts). Roughly, that produces ~60,000 results on each “full test run”.&lt;/li&gt;    &lt;li&gt;We’ll ignore how much time it takes to even execute the tests, let’s assume that we can get an infinite number of machines in a time warp so that we can run all of this in one night.&lt;/li&gt;    &lt;li&gt;We’ll ignore the fact that we have to make multiple runs to sign off on a release. Let’s assume we only do one (otherwise, we would be closer to 300,000 results).&lt;/li&gt;    &lt;li&gt;Even if 95% of the tests passed that leaves us with 3,000 failures. &lt;/li&gt;    &lt;li&gt;Even if you are a genius and it only takes you a minute to analyze a failure (meaning, you investigate if the failure was due to a test issue or a product bug), that is 50 hours of effort, equivalent to 6 full work days (assuming that you don’t take bathroom breaks at all).&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Now, even though the tests are distributed amongst a 12 person team, let’s consider that our pass rates are rarely as high as 95% and nobody takes a minute to analyze a test. Why? Because we are in a vicious cycle of:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;It is too expensive to run the tests.&lt;/li&gt;    &lt;li&gt;As a result, we don’t run them as often.&lt;/li&gt;    &lt;li&gt;As a result, they get stale and never get robust and the tester never gains enough experience with them.&lt;/li&gt;    &lt;li&gt;As a result, is too expensive to run the tests…&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Me and two other of my team members are tasked with correcting the course of this ship, and it is a challenge which I always like. So far, the strategies that we have come up with sound good on paper, but start looking overwhelming if we consider the magnitude of the problem (20,000 tests!)&lt;/p&gt;  &lt;p&gt;I’ll keep you posted with our progress.&lt;/p&gt;  &lt;p&gt;- Federico&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-7844658221658603181?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/7844658221658603181/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2009/07/finally-tackling-aspnet-qa-boat-anchor.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/7844658221658603181'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/7844658221658603181'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2009/07/finally-tackling-aspnet-qa-boat-anchor.html' title='Finally tackling the ASP.NET QA “Boat Anchor”'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641812635873375394.post-7315403524919775105</id><published>2009-07-13T23:18:00.001-07:00</published><updated>2009-07-20T19:47:57.551-07:00</updated><title type='text'>Just another tech blog...</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;This past month I had the good luck of talking with Scott Bellware over the phone, and he re-sparked my interest in sharing and learning more about testing from others. I have been doing a lot of experimenting in the ASP.NET QA team with different ways of testing (mostly ideas spawned from James Back), but I don't have an easy way to share these experiences nor to get feedback from others testers/devs out there.&lt;br /&gt;&lt;br /&gt;So I decided to start yet another tech blog where I can bore whoever is willing to listen with some lessons learned from a tester in the trenches. And hopefully, listen to other points of view and learn in the process.&lt;br /&gt;&lt;br /&gt;- Federico Silva Armas&lt;br /&gt;SDET, ASP.NET QA Team&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641812635873375394-7315403524919775105?l=www.federicosilva.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.federicosilva.net/feeds/7315403524919775105/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.federicosilva.net/2009/07/just-another-tech-blog.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/7315403524919775105'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641812635873375394/posts/default/7315403524919775105'/><link rel='alternate' type='text/html' href='http://www.federicosilva.net/2009/07/just-another-tech-blog.html' title='Just another tech blog...'/><author><name>Federico Silva Armas</name><uri>http://www.blogger.com/profile/16155208748351237093</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-fobfCduzJvY/Tv41dNhxnHI/AAAAAAAAAZ8/dot7GhhPc34/s220/logo.jpg'/></author><thr:total>0</thr:total></entry></feed>
