<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;A0ADQ3oycSp7ImA9WhBaEUw.&quot;"><id>tag:blogger.com,1999:blog-8623130854307760074</id><updated>2013-05-21T00:02:52.499-07:00</updated><category term="Debugging" /><category term="Tools" /><category term="Lessons Learned" /><category term="Whining" /><category term="Testing" /><title>Testing Toasters</title><subtitle type="html">Because those toasters aren't going to test themselves</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://www.testingtoasters.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://www.testingtoasters.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Mark Berryman</name><uri>http://www.blogger.com/profile/13905061216954268804</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_ffCx4LN58Fg/TGQi28CvgRI/AAAAAAAAAAM/NNfs4UhQkM8/S220/Me.JPG" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>34</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/TestingToasters" /><feedburner:info uri="testingtoasters" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;CUIBRH47eCp7ImA9WhJSGEk.&quot;"><id>tag:blogger.com,1999:blog-8623130854307760074.post-363033738423024132</id><published>2012-07-03T14:02:00.001-07:00</published><updated>2012-07-09T07:19:15.000-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-07-09T07:19:15.000-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Testing" /><title>Building an Awesome User Experience</title><content type="html">&lt;p&gt;Hot on the heels of my last post that my blogging was moving, I’m right back here with a test focused post.&lt;/p&gt; &lt;p&gt;Something hit me again yesterday, and not for the first time, that I had to call out.&lt;/p&gt; &lt;p&gt;Let’s talk about building a quality user experience and compare this to where I see folks spending most of their time – building a quality &lt;strong&gt;*functional*&lt;/strong&gt; experience.&lt;/p&gt; &lt;p&gt;When I think about a quality user experience, I think about a feature that plays well with others and is trivial to understand and use. So that’s easy to write down and it’s easy for folks to agree that building such an experience is important. But what’s hard is detecting when you &lt;u&gt;don’t&lt;/u&gt; have a quality user experience. &lt;/p&gt; &lt;p&gt;As I’ve commented before, you have a number of elements working against you here. Some of these are psychological. When you work with a feature day in and day out, you becomes used to its warts. You figure how to work around them and this workaround mentality becomes ingrained so that it’s second nature. You become blind to detractors of a quality user experience and you’re surprised when someone else tries your feature and struggles to use it. I wouldn’t be surprised if your work environment is also working against you. It’s been a hectic week and you have lots of deliverables like test plans and automation. You’re not thinking about the optimal user experience, because you’re swamped just trying to cover basic functional testing.&lt;/p&gt; &lt;p&gt;You need to change and make a mental shift to wearing that proverbial customer hat and evaluating the user experience. When I think about a feature, the first thing I want to know is the user experience we’re trying to nail. I don’t care about technical implementation details &lt;/p&gt; &lt;p&gt;This is a key tenet of Scenario Focused Engineering (SFE) which we push heavily at Microsoft. The primary idea being that the customer is put at the center of the development process and the focus is on delighting the customer. Notice that we’re not talking about engineering details of “how” this is going to be done. Our users don’t care about that. The technical challenges you had to overcome to deliver your feature are irrelevant to them. That’s a key point. We often get bogged down in technical details around implementation or integration with other features and this causes us to miss seeing the forest because of the trees. We need to clearly define the user scenarios we want to deliver, avoid getting bogged down in technical details, and constantly check ourselves against delivering those uncompromised user experiences. This is what Apple does so well these days and the results speak for themselves.&lt;/p&gt; &lt;p&gt;With a clear understanding of the ideal user experience you want to deliver, assess your feature against this. This is the hard part for the reasons I previously noted. So much is working against you here and it takes training to stay focused to produce the best assessment.&lt;/p&gt; &lt;p&gt;Let’s go through an example showing an integration scenario between an Azure web site and Hosted TFS which will be used for source code control. I thought a video would be best, so here we go:&lt;/p&gt;&lt;video poster="http://az152889.vo.msecnd.net/testingtoastersvideos/UserExperienceVideoFirstFrame.png" preload="none" width="660" height="380" controls="controls"&gt;&lt;source src="http://az152889.vo.msecnd.net/testingtoastersvideos/UserExperienceTestingExample.mp4" type="video/mp4" /&gt;  &lt;source src="http://az152889.vo.msecnd.net/testingtoastersvideos/UserExperienceTestingExample.ogv" type="video/ogg" /&gt;  *** Sorry, either your browser does not support the HTML5 video tag, or I don't have the movie in a format appropriate for your browser. Still, you can &lt;a href="http://az152889.vo.msecnd.net/testingtoastersvideos/UserExperienceTestingExample.mp4"&gt;directly download&lt;/a&gt; the video.***&lt;/video&gt;  &lt;p&gt;Now that you have ideas around how the actual user experience differed from the ideal, you’re probably ready to go back to the developers to discuss this. Often, the gaps between the ideal from the actual are caused by technical challenges (i.e., stuff is just hard to do). That’s understandable, but it shouldn’t always excuse us from tackling those problems. That’s why we’re paid the big bucks, right? We’re able to solve these challenging problems. We need to fight harder to deliver awesome user experiences. Just nailing fundamental functionality isn’t enough. You have to go the extra mile. Customers are worth it.&lt;/p&gt; &lt;p&gt;Mark&lt;/p&gt;  &lt;img src="http://feeds.feedburner.com/~r/TestingToasters/~4/S88o6i9fhtg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.testingtoasters.com/feeds/363033738423024132/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.testingtoasters.com/2012/07/building-awesome-user-experience.html#comment-form" title="10 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/363033738423024132?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/363033738423024132?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TestingToasters/~3/S88o6i9fhtg/building-awesome-user-experience.html" title="Building an Awesome User Experience" /><author><name>Mark Berryman</name><uri>http://www.blogger.com/profile/13905061216954268804</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_ffCx4LN58Fg/TGQi28CvgRI/AAAAAAAAAAM/NNfs4UhQkM8/S220/Me.JPG" /></author><thr:total>10</thr:total><feedburner:origLink>http://www.testingtoasters.com/2012/07/building-awesome-user-experience.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0IBQHw8eSp7ImA9WhJTGE0.&quot;"><id>tag:blogger.com,1999:blog-8623130854307760074.post-8399934244723999418</id><published>2012-06-27T06:59:00.001-07:00</published><updated>2012-06-27T06:59:11.271-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-06-27T06:59:11.271-07:00</app:edited><title>Changing Blogs</title><content type="html">&lt;p&gt;Hey folks,&lt;/p&gt; &lt;p&gt;My day to day work at Microsoft has changed in the past year such that I now focus more on testing via development using Microsoft’s Cloud and Web technologies. As part of this change, I want to share more content that’s specifically oriented to development. Hence, I’ve started a new blog with a few other co-workers at &lt;a href="http://www.cloudydeveloper.com"&gt;www.cloudydeveloper.com&lt;/a&gt;. So head on over there and check us out!&lt;/p&gt; &lt;p&gt;If I do bump into some interesting test focused material, I’ll still likely share that here.&lt;/p&gt; &lt;p&gt;Thanks,&lt;br&gt;Mark&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/TestingToasters/~4/dDE5mLdMek8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.testingtoasters.com/feeds/8399934244723999418/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.testingtoasters.com/2012/06/changing-blogs.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/8399934244723999418?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/8399934244723999418?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TestingToasters/~3/dDE5mLdMek8/changing-blogs.html" title="Changing Blogs" /><author><name>Mark Berryman</name><uri>http://www.blogger.com/profile/13905061216954268804</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_ffCx4LN58Fg/TGQi28CvgRI/AAAAAAAAAAM/NNfs4UhQkM8/S220/Me.JPG" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.testingtoasters.com/2012/06/changing-blogs.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUIER3k8eyp7ImA9WhRXEUg.&quot;"><id>tag:blogger.com,1999:blog-8623130854307760074.post-4502094529367821091</id><published>2011-12-17T13:30:00.001-08:00</published><updated>2011-12-17T13:31:46.773-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-17T13:31:46.773-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Tools" /><category scheme="http://www.blogger.com/atom/ns#" term="Testing" /><title>Drawn to Test</title><content type="html">&lt;p&gt;I’m a visual thinker. When collaborating with another tester, I always go to the whiteboard to draw up the system we’re testing. Pictures help me understand. Just listening to someone for ten minutes while they describe all of the pieces, communication, data flow, etc. in a system causes my brain to melt. I need to write things down to *see* what they’re describing. That’s the way my brain works. I’m probably just getting old. &lt;/p&gt; &lt;p&gt;Anyway, I think this is a useful process so I’ll share it.  &lt;p&gt;Taking a step back, this process helps me because it engages multiple parts of my brain simultaneously. Instead of being a passive listener while someone explains a system, I’m actively engaged. My hands are drawing while my ears are listening. In drawing, I’m focused on identifying the &lt;u&gt;critical&lt;/u&gt; pieces of information I’m being told (that’s what I draw) while ignoring extraneous details. This makes me focus on what’s important. &lt;p&gt;For those involved, drawing on the whiteboard also gets everyone on the same page. If I’m explaining software interactions to you, I’m not certain you’re understanding me. Granted, you might ask for clarification here and there, but maybe not always or you might make incorrect assumptions in your head. Putting our thoughts on the whiteboard helps ensure we’re on the same page because we can see what we’re thinking. If I draw two components and join them with an arrow indicating data flow, you can correct me if I’m wrong.  &lt;p&gt;Drawing also helps identify what we don’t know. In a way, we’re teaching the system to each other while we’re drawing. There’s no fudging of information here. Lots of questions are being asked. When we can’t explain how part of the system works, we’ve identified a gap in our knowledge. Perfect. Now we know that we don’t know. Time to figure it out.  &lt;p&gt;Okay, enough hand waving. Let’s go through an example using &lt;a href="http://www.nuget.org"&gt;NuGet&lt;/a&gt;. Never heard of NuGet? No sweat. It's a package management system. Read more about if you’re interested. I’ll wait.  &lt;p&gt;First, a bit of NuGet background to set the stage. If you haven’t read a bit about NuGet, none of this will make sense, but bear with me. &lt;p&gt;When you add a NuGet package to a Visual Studio project, NuGet adds the files for the package (e.g., a dll) to your project and additionally copies the files to disk at the Visual Studio solution level which is a few physical directories up the hierarchy. It’s like making a backup. But what if you don’t want the copy. Maybe your constantly forgetting to check them into source control, and when your buddy loads up your project on another machine, it fails to build because those files are missing. &lt;p&gt;Wouldn’t it be nice if NuGet was smart enough to download your packages again. Surprise! NuGet v1.6 has this feature!  &lt;p&gt;When first explained to me, I mentally drew pictures, but when you’re pouring a gallon of knowledge into a shot glass of a brain, knowledge spill out.  &lt;p&gt;I stopped the explanation, picked up a marker, and went to the whiteboard to produce this (yes, my penmanship is laughable):  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/-mren0BIT_jA/Tu0KCXAvNuI/AAAAAAAAAHs/9YZUKqeDfoE/s1600-h/NuGetDiagram6.png"&gt;&lt;img style="display: inline" title="NuGetDiagram" alt="NuGetDiagram" src="http://lh5.ggpht.com/-c_neTrPrNm0/Tu0KCymQF3I/AAAAAAAAAH0/j87u5sVtW-o/NuGetDiagram_thumb3.png?imgmax=800" width="605" height="480"&gt;&lt;/a&gt;  &lt;p&gt;On the whiteboard we see:  &lt;ul&gt; &lt;li&gt;Web applications (App A and App B) in the upper left corner that are part of the same VS solution.  &lt;li&gt;A “packages.config” file which records the NuGet packages used by an application.  &lt;li&gt;In the upper right is the local package cache (PKG CACHE) that’s queried first during the project build phase. &lt;li&gt;In the bottom right, is a cloud representing NuGet feeds (NuGet Src). Package bits are downloaded again if they weren’t found in the package cache.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Between each of these are arrows with notes indicating operations. For example, between the web applications and the “packages.config” file we have a “read” operation. That’s Visual Studio looking up the packages used by a project. Next, Visual Studio checks the package cache to see if the package bits are available on-disk. If that fails, we download the package again.&lt;/p&gt; &lt;p&gt;While drawing this system, we came up with questions (see the ‘?’s) regarding functionality and design. &lt;/p&gt; &lt;p&gt;For example, we wondered what would happen if downloading a package required authentication (i.e., a username/pwd)? How would you prompt a user to enter these during a project's build process. Would a blocking prompt pop-up? What if the build was triggered via the command line? There’s no UI shell to work with there. Maybe we need a way to pre-define these credentials?&lt;/p&gt; &lt;p&gt;One question you might be asking is “Where’s the developer design spec?”. Wouldn’t that answer your questions? The answer is the classic “it depends”. We’ve become more “agile” with our development and I now see less formal design documents and specs. We use wiki’s heavily and the level of detail is sometimes low. Let’s sidestep the debate on whether this is good or bad. The bottom line is that in the absence of such documentation, drawing out the system is one way to help you identify what you know and some of what you don’t know.&lt;/p&gt; &lt;p&gt;Long story short, drawing the system under test is helping me raise design questions and identify interesting test scenarios at a low cost. &lt;/p&gt; &lt;p&gt;Still not interested in this approach? Grab a fist full of whiteboard markers, remove the caps and inhale deeply. I’m certain you’ll see my point eventually.&lt;/p&gt;  &lt;img src="http://feeds.feedburner.com/~r/TestingToasters/~4/Y6kLyzN_66k" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.testingtoasters.com/feeds/4502094529367821091/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.testingtoasters.com/2011/12/drawn-to-test.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/4502094529367821091?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/4502094529367821091?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TestingToasters/~3/Y6kLyzN_66k/drawn-to-test.html" title="Drawn to Test" /><author><name>Mark Berryman</name><uri>http://www.blogger.com/profile/13905061216954268804</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_ffCx4LN58Fg/TGQi28CvgRI/AAAAAAAAAAM/NNfs4UhQkM8/S220/Me.JPG" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/-c_neTrPrNm0/Tu0KCymQF3I/AAAAAAAAAH0/j87u5sVtW-o/s72-c/NuGetDiagram_thumb3.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://www.testingtoasters.com/2011/12/drawn-to-test.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUAFRXo5cSp7ImA9WhRREkk.&quot;"><id>tag:blogger.com,1999:blog-8623130854307760074.post-3219496245710294170</id><published>2011-11-25T10:56:00.001-08:00</published><updated>2011-11-25T11:01:54.429-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-11-25T11:01:54.429-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Testing" /><title>Unhelpful Help</title><content type="html">&lt;p&gt;I’m becoming obsessed with error messages. Working with web development frameworks and related tooling, I bump into lots of these, and as I’ve &lt;a href="http://www.testingtoasters.com/2010/09/error-messages-whats-not-to-love.html"&gt;written before&lt;/a&gt;, it’s easy for them to go wrong. It’s also easy to brush off their imperfections and simply continue on my way. By arming myself with this checklist, I’m less likely to do that. Here’s my new error message testing checklist:&lt;/p&gt;&lt;strong&gt;&lt;font size="3"&gt;Does the error message point to the right problem?&lt;/font&gt;&lt;/strong&gt;  &lt;p&gt;This one’s a no-brainer. Simply put, does the error message match the error. This one points nowhere.&lt;br&gt;&lt;br&gt;&lt;a href="http://lh3.ggpht.com/-Yg5H-pWHWJY/Ts_k3asOqEI/AAAAAAAAAHU/hnT3AqeyIC8/s1600-h/image1%25255B5%25255D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/-Uy1A0P29YWY/Ts_k3hOUwzI/AAAAAAAAAHY/PoHSGrDmBr0/image1_thumb%25255B3%25255D.png?imgmax=800" width="242" height="148"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;br&gt;&lt;font size="3"&gt;Is the error message out-of-date?&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;We often re-use error messages across multiple versions of a product, but it can become out-of-date. For example, we might have an ASP.NET error message might reference a version of IIS, but that version of IIS might differ than the one shipped with a newer OS.&lt;br&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;font size="3"&gt;Is the error message easy to read?&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;A smaller than usual font might be used to pack a lot of information in a small amount of space. Or maybe there’s a poor choice of formatting. For example, you have a single large paragraph that could easily be broken up into easy to read bullet points.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;font size="3"&gt;Is the error message content appropriate for the setting in which it’s encountered?&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Stack traces are often helpful, but only in the right context. An ASP.NET error stack trace is often valuable since it tells the user how *their* code triggered an error (e.g., passing a null value). This stack trace, presented in Visual Studio, is a counterexample. Maybe it’s an exception that should have been caught and re-thrown with a user friendly error message. Anyway, you get the idea.&lt;br&gt;&lt;br&gt;&lt;a href="http://lh4.ggpht.com/-sYudNBdh964/Ts_k32cFOmI/AAAAAAAAAGo/leDYkqHWDm0/s1600-h/image4%25255B1%25255D%25255B1%25255D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/-aSgPv7pQ29A/Ts_k4VkzkYI/AAAAAAAAAGs/AheFcV8qHqM/image4%25255B1%25255D_thumb.png?imgmax=800" width="354" height="422"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;font size="3"&gt;Should the error message include a link to more information?&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;If you need to display a lot of content and have limited space, you could include a link to a web page that has more details. This has an additional benefit since you can update the information web page without changing any product code. Here’s an example.&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;a href="http://lh4.ggpht.com/--c6Se1SjM5w/Ts_k4mQaWcI/AAAAAAAAAGw/YwHXUapfrYY/s1600-h/image1%25255B1%25255D%25255B1%25255D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/-o7Y36LCa8kA/Ts_k41QqSYI/AAAAAAAAAG0/RVsHuwTPnwA/image1%25255B1%25255D_thumb.png?imgmax=800" width="486" height="221"&gt;&lt;/a&gt;&lt;br&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;font size="3"&gt;Can the error message be easily copied?&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;In the dialog above, it’s not easy to highlight the link for copying. The trick is to select the dialog and press CTRL+C to get the contents. Probably not obvious to users. Making the link clickable directly from the dialog would have been event better.&lt;br&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;font size="3"&gt;Does the error message provide overwhelming detail?&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Instead or providing individual error messages for individual error conditions, sometimes a single error message is used for a collection of error conditions. Here’s the error message when an ASP.NET automatic database creation step fails. It covers a number of possible reasons for the failure. I’m not saying this is a bad error message, but it’s a possible example of overwhelming detail.&lt;br&gt;&lt;br&gt;&lt;a href="http://lh4.ggpht.com/-_LNyhFgtTSE/Ts_k5EGo2WI/AAAAAAAAAHc/0fxjLEW9cpo/s1600-h/image%25255B12%25255D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/-IfMQFMdGcRY/Ts_k55QJvgI/AAAAAAAAAHg/7KovfTctcnM/image_thumb%25255B10%25255D.png?imgmax=800" width="636" height="360"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;br&gt;&lt;font size="3"&gt;Is the error message ambiguous?&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Looking at the error message below, which operation is it referring to? I might have specified more than one.&lt;br&gt;&lt;br&gt;&lt;a href="http://lh3.ggpht.com/-6p5qAWaUYTQ/Ts_k6aDG8PI/AAAAAAAAAHk/cdeF-IOMaqw/s1600-h/image%25255B13%25255D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/-qg4P54DyqpA/Ts_k6upxwfI/AAAAAAAAAHo/Pj2PktP7WaY/image_thumb%25255B11%25255D.png?imgmax=800" width="561" height="93"&gt;&lt;/a&gt;&lt;br&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;font size="3"&gt;Is the error message localizable?&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Showing the same string regardless of OS language would be a mistake. It needs to be translated. With the .NET framework, we pull the text of error messages from resource files that are localized into different languages.&lt;br&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;font size="3"&gt;Does the error message require additional context to be understood?&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;This one was triggered only if in a previous dialog the user targeted their local machine for the “deployment action”. Looking at this error message in isolation, the connection isn’t obvious.&lt;br&gt;&lt;br&gt;&lt;a href="http://lh4.ggpht.com/-KLqPcW1-cAs/Ts_k6vr-v9I/AAAAAAAAAHI/WMl5CKdKPWk/s1600-h/image14%25255B1%25255D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/-4NM29nVcmEk/Ts_k7Onw0DI/AAAAAAAAAHM/IIzMy4QLf48/image14_thumb.png?imgmax=800" width="382" height="145"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Showing an error message to a co-worker unfamiliar with a feature is a great way to catch this.&lt;/p&gt; &lt;p&gt;&lt;br&gt;So there you have it. A set of some additional checks you can use to better asses the quality of your error messages. Now if we could only prevent users from causing errors in the first place…&lt;/p&gt;  &lt;img src="http://feeds.feedburner.com/~r/TestingToasters/~4/GIbvQGCXANg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.testingtoasters.com/feeds/3219496245710294170/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.testingtoasters.com/2011/11/unhelpful-help.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/3219496245710294170?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/3219496245710294170?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TestingToasters/~3/GIbvQGCXANg/unhelpful-help.html" title="Unhelpful Help" /><author><name>Mark Berryman</name><uri>http://www.blogger.com/profile/13905061216954268804</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_ffCx4LN58Fg/TGQi28CvgRI/AAAAAAAAAAM/NNfs4UhQkM8/S220/Me.JPG" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/-Uy1A0P29YWY/Ts_k3hOUwzI/AAAAAAAAAHY/PoHSGrDmBr0/s72-c/image1_thumb%25255B3%25255D.png?imgmax=800" height="72" width="72" /><thr:total>2</thr:total><feedburner:origLink>http://www.testingtoasters.com/2011/11/unhelpful-help.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0UDQHgyfip7ImA9WhdaGU8.&quot;"><id>tag:blogger.com,1999:blog-8623130854307760074.post-5321042642097735180</id><published>2011-10-29T13:47:00.001-07:00</published><updated>2011-10-29T13:47:51.696-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-29T13:47:51.696-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Whining" /><title>Oh, Poor QA</title><content type="html">&lt;p&gt;Geez &lt;a href="http://www.dilbert.com/"&gt;Dilbert&lt;/a&gt;. Must we perpetuate the stereotype that QA engineers (or testers) are intellectually inferior to developers.&lt;/p&gt; &lt;p&gt;Here’s the strip for 10/28/11:&lt;/p&gt;&lt;a title="Dilbert.com" href="http://dilbert.com/strips/comic/2011-10-28/"&gt;&lt;img border="0" alt="Dilbert.com" src="http://dilbert.com/dyn/str_strip/000000000/00000000/0000000/100000/40000/0000/000/140052/140052.strip.gif"&gt;&lt;/a&gt;  &lt;p&gt;While I don’t doubt that there are QA jobs that require little brainpower, many folks seem quick to generalize and lump *all* QA jobs into this bucket. I even get a whiff of this when interviewing external candidates for testing positions at Microsoft. &lt;/p&gt; &lt;p&gt;Candidate asks - &lt;em&gt;“How much time will I spend coding?” &lt;/em&gt;&lt;/p&gt; &lt;p&gt;I translate this into - &lt;em&gt;“How little time will I have to spend doing inferior QA type activities?”&lt;/em&gt;&lt;/p&gt; &lt;p&gt;It makes me ill.&lt;/p&gt; &lt;p&gt;Marketing folks, I’ll let you defend yourselves.&lt;/p&gt;  &lt;img src="http://feeds.feedburner.com/~r/TestingToasters/~4/rNAd4FvZ1AE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.testingtoasters.com/feeds/5321042642097735180/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.testingtoasters.com/2011/10/oh-poor-qa.html#comment-form" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/5321042642097735180?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/5321042642097735180?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TestingToasters/~3/rNAd4FvZ1AE/oh-poor-qa.html" title="Oh, Poor QA" /><author><name>Mark Berryman</name><uri>http://www.blogger.com/profile/13905061216954268804</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_ffCx4LN58Fg/TGQi28CvgRI/AAAAAAAAAAM/NNfs4UhQkM8/S220/Me.JPG" /></author><thr:total>4</thr:total><feedburner:origLink>http://www.testingtoasters.com/2011/10/oh-poor-qa.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcNQ3s9eip7ImA9WhdXGE0.&quot;"><id>tag:blogger.com,1999:blog-8623130854307760074.post-3595630768468276723</id><published>2011-08-28T22:19:00.001-07:00</published><updated>2011-08-31T08:04:52.562-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-31T08:04:52.562-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Tools" /><category scheme="http://www.blogger.com/atom/ns#" term="Testing" /><title>Setup Testing–Execution and Verification</title><content type="html">&lt;p&gt;Hopefully you read the &lt;a href="http://www.testingtoasters.com/2011/08/setup-testingplanning.html"&gt;previous blog post&lt;/a&gt; which set up (no pun intended) the context of this second follow up post. If not, take a few minutes and read it before continuing here.&lt;/p&gt;&lt;p&gt;With your matrix of setup configurations fully defined, it’s time to turn our attention to executing the individual scenarios in an effective and efficient manner.&lt;/p&gt;&lt;p&gt;The first thing to do is check your set of test configurations and double check that there aren’t any in there that are invalid. For example, maybe there are some operations systems you mistakenly assumed your product would support, but it turns out that with this version, you’ve dropped support for some of the older ones.&lt;/p&gt;&lt;p&gt;The next big task is to prioritize the setup configurations. Assuming you have neither infinite time or resources, you need to selectively pick the configurations you can run. Here, having a good sense of your customers’ common configurations help. Hopefully you have some historical data on this or maybe it’s something you can collect it via a survey. Otherwise, you’ll just have to rely on your best guess of the likely configurations. If that’s the case, you might want to enlist a pairwise testing tool.&lt;/p&gt;&lt;p&gt;If you’re not familiar with the concept of &lt;a href="http://en.wikipedia.org/wiki/All-pairs_testing"&gt;pairwise testing (or all-pairs testing)&lt;/a&gt;, it’s a way to reduce the full combinatorial matrix of your variables down to a smaller set that will likely provide “good” test coverage. It’s a cost-benefit tradeoff that might be worth exploring. Let me provide a quick example.&lt;/p&gt;&lt;p&gt;Imagine that your dealing with three variables for your setup test plan and each have two values:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Operating system&lt;/strong&gt; – Windows 7, Windows XP&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Machine architecture&lt;/strong&gt; – 32-bit and 64-bit&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Product SKU&lt;/strong&gt; – Basic Edition and Professional edition&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;A complete combinatorial matrix would produce 2 x 2 x 2 = 8 setup configurations.&lt;/p&gt;&lt;p&gt;A pairwise analysis of these variables would only yield 4 setup configurations, but would ensure that each pair of variables would be covered at least once. So you might get something like:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Windows 7, 32-bit, Basic Edition&lt;/li&gt;
&lt;li&gt;Windows XP, 64-bit, Professional Edition&lt;/li&gt;
&lt;li&gt;Windows 7, 64-bit, Professional Edition&lt;/li&gt;
&lt;li&gt;Windows XP, 32-bit, Basic Edition&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;You can see that “Windows 7, 32-bit, Professional Edition” is not in the list. Breaking this configuration down in variable pairs, you’ll get coverage for “Windows 7, 32-bit” in configuration #1, “Windows 7, Professional Edition” in configuration #3, and “32-bit, Professional Edition” in configuration #4.&lt;/p&gt;&lt;p&gt;Here’s &lt;a href="http://www.pairwise.org/tools.asp"&gt;a list of pairwise testing tools&lt;/a&gt; to explore. &lt;a href="http://download.microsoft.com/download/f/5/5/f55484df-8494-48fa-8dbd-8c6f76cc014b/pict33.msi"&gt;PICT&lt;/a&gt; is from Microsoft.&lt;/p&gt;&lt;p&gt;Now, with your setup matrix streamlined and prioritized, you can finally get down to testing. The question though is “who” should do it? In my opinion, this is a great task to be offloaded to less costly resources like vendors or offshore teams. We do this in my group, and it works well, but only because we’re crystal clear and detailed in our communication. Notation is standardized so there’s no confusion on what each setup test definition means in terms of products, install/uninstall order or verification steps. If there’s a lot of back and forth between you and the other resource, you’re not going to save much time or effort.&lt;/p&gt;&lt;p&gt;After running a setup test, you need to verify “success”, but what is this verification process? Are you simply verifying that the setup process ran end-to-end without crashing, or is there more to check? &lt;/p&gt;&lt;p&gt;I hope you answered “there’s more to check”. At a high level, you should at least be evaluating the following:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;A sanity customer scenario can be completed after the product is installed.&lt;/li&gt;
&lt;li&gt;If there are other apps that might be affected by the setup, verify they haven’t been broken. We do such checks when testing SxS setups of Visual Studio. An install of the latest version shouldn’t break the previous.&lt;/li&gt;
&lt;li&gt;If testing uninstall as well, verify you haven’t left any “turds” on the box. This could be files, registry entries, etc. Doing so is just sloppy and might break a future install of a new version of your product. Using tools to take a snapshot of the file system and registry for comparison purposes can help here.&lt;/li&gt;
&lt;li&gt;Assess the speed of the setup install. Is it reasonable? Is there a UI providing meaningful feedback to the customer so they know it’s proceeding successfully?&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;Okay, so those are my thoughts on setup testing planning, execution and verification. In closing, I’ll paraphrase my primary message from the previous post. Your product is useless, if your customers can’t successfully install it on their machines. Please don’t screw this up. :-)&lt;/p&gt;&lt;p&gt;Mark&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/TestingToasters/~4/86lg-9jlJMQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.testingtoasters.com/feeds/3595630768468276723/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.testingtoasters.com/2011/08/setup-testingexecution-and-verification.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/3595630768468276723?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/3595630768468276723?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TestingToasters/~3/86lg-9jlJMQ/setup-testingexecution-and-verification.html" title="Setup Testing–Execution and Verification" /><author><name>Mark Berryman</name><uri>http://www.blogger.com/profile/13905061216954268804</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_ffCx4LN58Fg/TGQi28CvgRI/AAAAAAAAAAM/NNfs4UhQkM8/S220/Me.JPG" /></author><thr:total>2</thr:total><feedburner:origLink>http://www.testingtoasters.com/2011/08/setup-testingexecution-and-verification.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEIDQXg8eyp7ImA9WhdXE04.&quot;"><id>tag:blogger.com,1999:blog-8623130854307760074.post-7506243648229411075</id><published>2011-08-25T21:22:00.001-07:00</published><updated>2011-08-25T21:22:50.673-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-25T21:22:50.673-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Testing" /><title>Setup Testing–Planning</title><content type="html">&lt;p&gt;We do a lot of setup testing at Microsoft. Given the wide distribution of our technologies across a massive matrix of user machine configurations, we can’t afford to skimp on this testing and only cover a few mainline combinations and hope for the best. We put a lot of thought and effort into setup testing.&lt;/p&gt; &lt;p&gt;In this first post of what I think will be a two part series, I’ll focus on setup testing planning. How do you create the test scenarios that go into this type of test plan. In a subsequent post, I’ll dive into execution and verification of the setup test plan. Now the way I approach setup testing is heavily influenced by my experiences at Microsoft, which shouldn’t be a surprise, but I hope there’s some generic points below that can be applied to almost any product.&lt;/p&gt; &lt;p&gt;Let me take a step back and define the purpose of setup testing. Simply, we’re trying to install a product on a machine and verify it works as expected while having no negative impact. That last part is sometimes inadvertently omitted, but you’d be embarrassed if your product’s install broke other products on the user’s machine (unless they were competitors).&lt;/p&gt; &lt;p&gt;Okay, let me take another quick step back (I’ll move forward soon) and describe the motivation for discussing this topic. Up until now, every time I’ve been asked to develop a setup test plan or review one, I’ve primarily relied on my memory to come up with the scenarios. This is idiotic. I’m biting the bullet here and spending a bit of time to document my approach. No more solely relying on you squishy brain.&lt;/p&gt; &lt;p&gt;Moving ahead, the first step in setup test planning is to define the variables that form the different configurations we need to test. We’re thinking about all of the moving parts in the system that could impact whether setup succeeds or fails. &lt;/p&gt; &lt;p&gt;Let me try to define a semi-structured list of variables to consider and questions to answer.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Machine configuration:&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Operating systems – Which OS’s does your product support?  &lt;li&gt;&lt;a href="http://codingqa.com/Episode-56-Localization-and-Globalization"&gt;Localization&lt;/a&gt; – Which languages is your product localized into?  &lt;li&gt;&lt;a href="http://codingqa.com/Episode-56-Localization-and-Globalization"&gt;Globalization&lt;/a&gt; – Which OS languages will your product install on?  &lt;li&gt;Architecture – Does your product run on both 32-bit and 64-bit machines?  &lt;li&gt;“Dirty” machines – What other bits might installed on a customer’s machine that could interfere with your products setup (e.g., aggressive anti-virus software)? Similarly, make sure you’re not *always* testing on brand new clean machines.  &lt;li&gt;Screen size – If you' have a UI based installer, run it on a monitor with a low resolution (think netbook). Does the UI scale properly or does it get cropped?  &lt;li&gt;Disk space – Run the install on a disk that doesn’t have enough free space for the install to succeed.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Product configuration:&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Versions – Have you shipped previous versions of your product? Do you plan to ship future versions beyond the current version you’re working on? &lt;/li&gt; &lt;ul&gt; &lt;li&gt;Future versions are an interesting test scenario. You’ll want to ensure you’re not doing something today with your current setup that will cause you setup pain in the future. For example, not writing a registry key which indicates the version of your product installed. You might want a future version of your product to have this information. &lt;br&gt;&lt;br&gt;When we test our frameworks, we often build a “mock” vNext-Next version (that’s two versions ahead) and do setup testing with it.&lt;/li&gt;&lt;/ul&gt; &lt;li&gt;SKU’s – What are the different SKU’s (or flavors) of your product (e.g., basic, pro, ultimate, etc.)?  &lt;li&gt;Side-by-Side (SxS) – Can your product be installed SxS with other versions of your product? If so, which combinations are supported?&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Install/Uninstall configuration:&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Different Installers - Is there more than one way to install your product? Maybe you have an interactive UI based installer and an automated command line installer. Or maybe different installers for different OS’s?  &lt;li&gt;Location of installer – Does it matter if the installer is run locally versus on a remote network share?  &lt;li&gt;Install location – Is this fixed for the user or can they customize it? &lt;/li&gt; &lt;ul&gt; &lt;li&gt;We’re sometimes nailed by this because all of our test machines have the same setup of two drives and when a customer installs the product on a machine with just one drive, we bomb.&lt;/li&gt;&lt;/ul&gt; &lt;li&gt;User accounts – Does your product have to be installed by an administrator level account or will a non-admin account work as well? Can one user account install the product and another user account uninstall it? &lt;/li&gt; &lt;ul&gt; &lt;li&gt;This scenario of one user installing and another user uninstalling is interesting for shared servers where the first user account is deleted at some point.&lt;/li&gt;&lt;/ul&gt; &lt;li&gt;Product uninstallation – Don’t forget to test uninstalling the product. &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Install/Uninstall execution:&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Order of operations – If SxS configurations (see above) of your product are possible, vary the installation and uninstallation of them. For example, you could [install v1, uninstall v1, install v2] as one configuration or [install v1, install v2, uninstall v1] as a second configuration. Both should produce roughly the same result.  &lt;li&gt;Redundant operations – Test installing your product, uninstalling and then re-installing it.&lt;!--EndFragment--&gt;  &lt;li&gt;Cancellation – Abort your install and uninstall in the middle of execution via built-in functionality (e.g., typical Cancel button) and via the unexpected (e.g., reboot).  &lt;li&gt;Blocking – Are there configurations where an install or uninstall operation should be blocked? Maybe installation shouldn’t be possible if there’s a previous version of the product already on the machine, or you can’t uninstall because other products have a dependency on this one. Related to that, if the operation is blocked, is a meaningful message presented to the user instructing them on how to become unblocked?&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Miscellaneous:&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Dependent products - Are you assuming that some components must already be on the box? &lt;/li&gt; &lt;ul&gt; &lt;li&gt;I’ve seen my team make assumptions that IIS will always be installed before we try to install ASP.NET because that’s the way our test machines are set up, but there’s no guarantee of this. &lt;/li&gt;&lt;/ul&gt; &lt;li&gt;Files in use - Are there files that setup needs to access that might be locked by another process? &lt;/li&gt; &lt;ul&gt; &lt;li&gt;Microsoft products seem to often recommend exiting all other applications before installation begins to help ensure there’s no “file in use” conflicts.&lt;/li&gt;&lt;/ul&gt; &lt;li&gt;&lt;font color="#000000"&gt;Right bits - Make sure the build you’re testing is the one you’re shipping. If you’ve done some testing and the bits change, re-evaluate the setup test scenarios you need to re-run.&lt;/font&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;With the configuration variables defined and the various questions answered, it’s time to crank out the matrix of individual configurations to test. In a follow up post, we’ll continue with setup testing execution and verification.&lt;/p&gt; &lt;p&gt;&lt;font color="#ff0000"&gt;&lt;font color="#000000"&gt;Oh, one last thought:&lt;/font&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font color="#ff0000"&gt;&lt;strong&gt;If your setup fails, your product is worthless to customers. Take setup testing seriously. Seriously.&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;Okay, so what did I miss?&lt;/p&gt; &lt;p&gt;Mark&lt;/p&gt;  &lt;img src="http://feeds.feedburner.com/~r/TestingToasters/~4/9KK1_pK1NB4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.testingtoasters.com/feeds/7506243648229411075/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.testingtoasters.com/2011/08/setup-testingplanning.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/7506243648229411075?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/7506243648229411075?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TestingToasters/~3/9KK1_pK1NB4/setup-testingplanning.html" title="Setup Testing–Planning" /><author><name>Mark Berryman</name><uri>http://www.blogger.com/profile/13905061216954268804</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_ffCx4LN58Fg/TGQi28CvgRI/AAAAAAAAAAM/NNfs4UhQkM8/S220/Me.JPG" /></author><thr:total>2</thr:total><feedburner:origLink>http://www.testingtoasters.com/2011/08/setup-testingplanning.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkQFQX0-fSp7ImA9WhdXEUs.&quot;"><id>tag:blogger.com,1999:blog-8623130854307760074.post-8285148168321175659</id><published>2011-08-23T21:31:00.001-07:00</published><updated>2011-08-23T21:31:50.355-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-23T21:31:50.355-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Lessons Learned" /><title>Time Wasted</title><content type="html">&lt;p&gt;I recently spent a few weeks (off and on) porting the &lt;a href="http://www.codingqa.com"&gt;Coding QA&lt;/a&gt; website from a proprietary closed web hosting platform to an MVC 3 application hosted on your typical budget web hosting platform. Overall it was a fun experience mixed with lots of pain and suffering (bad database connection string can nuke your site), but in the end, I learned valuable stuff. I also learned a non-technical lesson that I wanted to note down for future reference.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Mark’s Lesson of the Day – “&lt;u&gt;I DON’T KNOW WHEN TO ASK FOR HELP&lt;/u&gt;”&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Okay, so back to the upgrade of the Coding QA website. The code was written and tested so I “published” it to the web server and gave it a spin. &lt;/p&gt; &lt;p&gt;First check – create a dummy blog post. That required logging in with my super secret admin account. Done. Next, create a blog post, fill in some dummy data and then “Save”. &lt;/p&gt; &lt;p&gt;I got dumped back to my site’s the login screen.&lt;/p&gt; &lt;p&gt;Looking back, it was this point that I started unknowingly proceeding through &lt;a href="http://en.wikipedia.org/wiki/Stages_of_grief"&gt;The Five Stages of Grief&lt;/a&gt;.&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Denial &lt;/strong&gt;- Uh, no I didn’t just get logged out of the site when trying to create a new blog post. I repeated my steps. Same result. I fulfilled the definition of insanity by repeating the process a third and fourth time. &lt;br&gt;&lt;br&gt; &lt;li&gt;&lt;strong&gt;Anger&lt;/strong&gt; -&lt;strong&gt;&amp;nbsp;&lt;/strong&gt;WTF is wrong with this web server’s setup!? Everything works fine on my development box. Serves me right for picking the cheapest web hosting plan possible.&lt;br&gt;&lt;br&gt; &lt;li&gt;&lt;strong&gt;Bargaining&lt;/strong&gt; - Okay, maybe the situation isn’t that bad. After being logged out, if I log in again, it seems like I can sometimes get the “Save” operation to work. Painful, but at least I have a workaround although it might take a few tries.&lt;br&gt;&lt;br&gt; &lt;li&gt;&lt;strong&gt;Depression&lt;/strong&gt; - Seriously? I’ve got to go through this multiple login/logout crap each time. Why, oh why did I want to move the website? I didn’t have to do this. I’m not even saving any money. I only have myself to blame for this mess. I’m a moron.&lt;br&gt;&lt;br&gt; &lt;li&gt;&lt;strong&gt;Acceptance&lt;/strong&gt; - Okay, I’m just going to have to live with this. Too much time and effort have gone into porting the site. I can’t back out now. It’s full steam ahead with a steaming POS of a solution.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;&lt;br&gt;I then proceeded for hours trying to debug the problem using my &lt;strike&gt;vast&lt;/strike&gt; limited knowledge of ASP.NET.&lt;/p&gt; &lt;p&gt;Okay, what are all of the possible reasons for getting unexpectedly logged out of the site?&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Um, maybe each web request is getting redirected to a different box and that new box doesn’t recognize the authorization cookie issued by the first box.  &lt;li&gt;Or, maybe there’s a problem with being redirected to the login page when I directly request a restricted page. At one point, I actually convinced myself this was the issue and thought I had a workaround by only logging in directly through the Account login page.  &lt;li&gt;Ah, there must be a problem with the expiration date set on the authorization cookie after I login. I bet my local web.config setting for this (set at 2 days) isn’t being honored.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;No, none of this madness was even close. Nothing worked and I couldn’t get over the fact that I, someone who has worked on ASP.NET for 8+ years, couldn’t solve this stupid logout problem. Geez, if I couldn’t solve this, the rest of the folks using this web hosting company are screwed.&lt;/p&gt; &lt;p&gt;Feeling totally helpless, I made a last ditch effort and sent the web hosting company a one sentence e-mail with a subject line of “&lt;em&gt;I keep getting logged out of my site&lt;/em&gt;”.&lt;/p&gt; &lt;p&gt;Their reply – “&lt;em&gt;Your application might be exceeding the 100 MB memory limit&lt;/em&gt;”.&lt;/p&gt; &lt;p&gt;Uh, the what limit?&lt;/p&gt; &lt;p&gt;Yep, right there on their hosting plan summary page they call out the 100 MB memory limit for an application. Exceed that and your application is recycled and that logs you out.&lt;/p&gt; &lt;p&gt;I wasted hours trying to solve a problem that an entry level support engineer looked up in two minutes. &lt;/p&gt; &lt;p&gt;I don’t know when to ask for help.&lt;/p&gt; &lt;p&gt;Mark&lt;/p&gt;  &lt;img src="http://feeds.feedburner.com/~r/TestingToasters/~4/C0eVS7IKgrk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.testingtoasters.com/feeds/8285148168321175659/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.testingtoasters.com/2011/08/time-wasted.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/8285148168321175659?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/8285148168321175659?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TestingToasters/~3/C0eVS7IKgrk/time-wasted.html" title="Time Wasted" /><author><name>Mark Berryman</name><uri>http://www.blogger.com/profile/13905061216954268804</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_ffCx4LN58Fg/TGQi28CvgRI/AAAAAAAAAAM/NNfs4UhQkM8/S220/Me.JPG" /></author><thr:total>2</thr:total><feedburner:origLink>http://www.testingtoasters.com/2011/08/time-wasted.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DE4DRHk_eCp7ImA9WhdQFUQ.&quot;"><id>tag:blogger.com,1999:blog-8623130854307760074.post-6696571651382380603</id><published>2011-08-17T08:59:00.000-07:00</published><updated>2011-08-17T09:02:55.740-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-17T09:02:55.740-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Testing" /><title>Effective Integration Testing</title><content type="html">&lt;p&gt;If your test team isn’t doing &lt;u&gt;effective&lt;/u&gt; integration testing*, you’re making a big mistake. Skipping integration testing is like testing all of the parts of a car individually, but never assembling it and taking it for a drive. &lt;/p&gt; &lt;p&gt;For years I felt our team gave this type of testing minimal attention, and we paid a high price for it – critical bugs found late in the development cycle, high profile demo failures, hotfixes shipped right after the product was released, etc. &lt;/p&gt; &lt;p&gt;Fortunately, our approach today is different. We have at least two team members (I’m one), that spend the majority of their time using Microsoft’s Web Frameworks and Tools (e.g., ASP.NET, Visual Web Developer, etc.) to build real world applications. I call this our “Dedicated Integration Testing” effort.&lt;/p&gt; &lt;p&gt;Let me contrast our team’s current approach with the past. &lt;/p&gt; &lt;p&gt;We always knew integration testing was important because of the “high cost” issues noted previously, but we never did it effectively. Here are &lt;u&gt;some&lt;/u&gt; approaches we’ve tried and why I think they’re ineffective:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Told the entire team of testers to do integration testing  &lt;ul&gt; &lt;li&gt;You can’t simply tell someone to “do integration” testing and expect meaningful results. Integration testing requires broad knowledge of all of the pieces in the software system. Your standard tester is probably focused on depth testing a small set of features. They won’t have this broad product knowledge, and it’s not that they couldn’t learn it. They just don’t have time to do it. Granted, some folks that have been with the team for years have been able to develop a bit of product breadth, but I’d argue it’s not enough.&lt;br&gt;&lt;/li&gt;&lt;/ul&gt; &lt;li&gt;Schedule the entire product team to spend a few weeks doing integration testing (that’s application building for us)  &lt;ul&gt; &lt;li&gt;This activity is typically scheduled towards the end of a major product milestone. It’s on the calendar, and we all know it’s coming.&amp;nbsp; But we’ve had previous schedule delays, and now we need to cut work to get us back on track. Hmm – I wonder what’s first to get whacked?  &lt;li&gt;Okay, let’s say we actually get to this work. Based on my past experience, the applications produced are “toy” applications. They’re not meaningful in terms of providing effective integration testing coverage. They don’t cover the interactions of all of the features in the system or they don’t exercise the pieces in a meaningful way. Going back to my car analogy, we’re starting the car but never taking it out of park.&lt;br&gt;&lt;/li&gt;&lt;/ul&gt; &lt;li&gt;Form a virtual integration testing team  &lt;ul&gt; &lt;li&gt;Who do you pick for this? Do you randomly select a handful of folks and tell them to go focus on integration testing scenarios? If so, you’ve likely got the wrong people in this group. You’re probably going to hit the problem of a lack of broad product knowledge, and this is going to cripple your ability to produce meaningful integration test scenarios.&lt;br&gt;&lt;br&gt;We tried this approach a few years ago. It went poorly. Members of the team took the features they knew (i.e., a subset of what should have been covered) and crammed them together in ways they thought were realistic (i.e., not what our customer’s would do) and called this integration testing. Again, it wasn’t the team members fault. They just didn’t have the right product knowledge or customer understanding.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;Here’s why I think we’re doing more effective integration testing today.&lt;/p&gt; &lt;p&gt;First, we don’t rely on any of the above three approaches to cover our integration testing needs. Some of those activities might still happen, but we don’t depend on them to feel confident that we’ve done sufficient integration testing.&lt;/p&gt; &lt;p&gt;Second, there’s two of us &lt;u&gt;dedicated&lt;/u&gt; to integration testing, and by dedicated, I meant that we’re not distracted by most traditional tester activities. For example:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;We don’t own individual features.  &lt;li&gt;We don’t write test automation.  &lt;li&gt;We don’t work on test infrastructure.  &lt;li&gt;We don’t sit in product triage meetings.  &lt;li&gt;We don’t manage other team members.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;Third, we’re committed to integration testing. Come review time, we’re graded against these efforts. This means we’re unlikely to sucked into other activities not related to integration testing.&lt;/p&gt; &lt;p&gt;Forth, we spend a lot of time learning. We attend brown bags, we do pair test sessions, we participate in customer SDR’s (software design reviews), we watch training videos, we read blogs, etc. This is how we build a broad product understanding and a deep understanding of our customers. &lt;/p&gt; &lt;p&gt;So this is the approach our team is taking today. It took a long time to get here, and it wasn’t a trivial commitment of resources for the team to make. I thank our management team for allowing us to experiment with this approach, and I hope our customers appreciate the effort as well.&lt;/p&gt; &lt;p&gt;Mark&lt;/p&gt; &lt;p&gt;&lt;font size="1"&gt;*Some folks might call what I’m describing as “systems testing”. That’s fine. The terminology isn’t critical for this post.&lt;/font&gt;&lt;/p&gt;  &lt;img src="http://feeds.feedburner.com/~r/TestingToasters/~4/_k3V4GdFJtk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.testingtoasters.com/feeds/6696571651382380603/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.testingtoasters.com/2011/08/effective-integration-testing.html#comment-form" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/6696571651382380603?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/6696571651382380603?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TestingToasters/~3/_k3V4GdFJtk/effective-integration-testing.html" title="Effective Integration Testing" /><author><name>Mark Berryman</name><uri>http://www.blogger.com/profile/13905061216954268804</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_ffCx4LN58Fg/TGQi28CvgRI/AAAAAAAAAAM/NNfs4UhQkM8/S220/Me.JPG" /></author><thr:total>3</thr:total><feedburner:origLink>http://www.testingtoasters.com/2011/08/effective-integration-testing.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkIMQXc4fSp7ImA9WhZUFUo.&quot;"><id>tag:blogger.com,1999:blog-8623130854307760074.post-5884221023973837588</id><published>2011-06-08T15:03:00.000-07:00</published><updated>2011-06-08T15:03:00.935-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-08T15:03:00.935-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Testing" /><title>Thinking About Alternative Implementations</title><content type="html">&lt;p&gt;I’ve been helping test a new feature coming out with the next version of Visual Studio. Essentially, we want to light up new functionality in the code editor via a new dialog of actions. To trigger it, the current implementation has the user placing the mouse cursor over a keyword and after a short delay, the dialog appears next to the keyword. When I was first shown the feature, this is how it was explained to me and this understanding was foremost in my mind as I tested it.&lt;/p&gt; &lt;p&gt;After spending a few minutes testing it, a few issues cropped.&amp;nbsp; For example:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;How would folks know where to put the mouse cursor? Would they expect that placing the cursor near (e.g., just before the start or just after the end) to also trigger the dialog?&lt;br&gt;&lt;/li&gt; &lt;li&gt;How long did the mouse have to hover over the keyword? We didn’t want the feature to be triggered instantaneously as that could be annoying, and it couldn’t take too long or users would think the feature was broken.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;These points were debated and decisions made. A few weeks later, another team member looked at the feature. They had similar feedback as well as an interesting recommendation. They wondered why we didn’t just show the dialog when a user right clicks anywhere on the line containing the keyword. &lt;/p&gt; &lt;p&gt;Um, yeah, that’s a good idea and would bypass the previous issues raised. I don’t know if this approach will be accepted, but it’s a nice alternative implementation.&lt;/p&gt; &lt;p&gt;So why didn’t I think of such a recommendation? Reviewing my thought process and test approach, I realized that I &lt;strong&gt;&lt;u&gt;started&lt;/u&gt;&lt;/strong&gt; with the current feature implementation.&amp;nbsp; &lt;/p&gt; &lt;p&gt;My understanding and evaluation of the feature looked like this:&lt;/p&gt; &lt;p&gt;&lt;a href="http://lh6.ggpht.com/-OMxQq3EgyJ4/TeqsBDyXraI/AAAAAAAAAEo/b4lIaT9Mbv4/s1600-h/BeforeProcessCropped%25255B3%25255D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="BeforeProcessCropped" border="0" alt="BeforeProcessCropped" src="http://lh6.ggpht.com/-eyx58-NjQRM/TeqsB8lAikI/AAAAAAAAAEs/7jKxgFKMFlk/BeforeProcessCropped_thumb%25255B1%25255D.png?imgmax=800" width="260" height="177"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Being told the current implementation seemed to crush my test creativity around discovering alternate ways to achieve the goal – show a dialog with actions.&amp;nbsp; This is quite similar to how reading a spec can crush testing creativity (see previous post - &lt;a href="http://www.testingtoasters.com/2010/12/spec-i-dont-need-no-stinking-spec.html"&gt;&lt;u&gt;I Don't Need No Stinking Spec&lt;/u&gt;&lt;/a&gt;).&amp;nbsp; Had I backed up my thought process one step, I might have come up with the “right click” approach and the issues raised with the current design could have been leapfrogged.&lt;/p&gt; &lt;p&gt;Then we could have done this:&lt;/p&gt; &lt;p&gt;&lt;a href="http://lh3.ggpht.com/-QD23SJpV0-k/TeqsCn9iRcI/AAAAAAAAAEw/dx4Z9KHeMU4/s1600-h/AfterProcessCropped%25255B4%25255D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="AfterProcessCropped" border="0" alt="AfterProcessCropped" src="http://lh3.ggpht.com/-heV-OxJpKek/TeqsDFIoRoI/AAAAAAAAAE0/zWy-M9jCFrw/AfterProcessCropped_thumb%25255B2%25255D.png?imgmax=800" width="397" height="169"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Lesson learned.&amp;nbsp; All feature team members (not just testers) need to be cognizant about when they’re focusing too much on a single approach and issues related to how it will be achieved. Doing so means you might miss more elegant solutions which could leave your users wondering why you made things so damn complicated.&lt;/p&gt;  &lt;img src="http://feeds.feedburner.com/~r/TestingToasters/~4/5SO6mbJT2P8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.testingtoasters.com/feeds/5884221023973837588/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.testingtoasters.com/2011/06/thinking-about-alternative.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/5884221023973837588?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/5884221023973837588?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TestingToasters/~3/5SO6mbJT2P8/thinking-about-alternative.html" title="Thinking About Alternative Implementations" /><author><name>Mark Berryman</name><uri>http://www.blogger.com/profile/13905061216954268804</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_ffCx4LN58Fg/TGQi28CvgRI/AAAAAAAAAAM/NNfs4UhQkM8/S220/Me.JPG" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/-eyx58-NjQRM/TeqsB8lAikI/AAAAAAAAAEs/7jKxgFKMFlk/s72-c/BeforeProcessCropped_thumb%25255B1%25255D.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://www.testingtoasters.com/2011/06/thinking-about-alternative.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0EEQ3syfyp7ImA9WhZUEU0.&quot;"><id>tag:blogger.com,1999:blog-8623130854307760074.post-2320313476166633016</id><published>2011-06-03T07:00:00.000-07:00</published><updated>2011-06-03T07:00:02.597-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-03T07:00:02.597-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Testing" /><title>Testing the Feature Specification</title><content type="html">&lt;p&gt;A feature’s specification is undoubtedly important, but literally translating it into a corresponding test plan is a poor choice. If that’s going to be your approach, you might as well outsource the testing to someone less skilled. Instead, a high value tester will apply a mix of her own test creativity and understanding of her customer’s needs to help define additional feature expectations that are never mentioned in the spec.&lt;/p&gt; &lt;p&gt;Let’s walk through an example. We use &lt;a href="http://en.wikipedia.org/wiki/Hyper-V"&gt;Hyper-V&lt;/a&gt; frequently in my team. If you’re not familiar with it or some other virtual machine technology, you should be. It’s an essential component in your &lt;a href="http://www.testingtoasters.com/p/testing-tools.html"&gt;tester’s toolbox&lt;/a&gt;. Anyway, I wanted to copy a virtual machine another teammate had spent hours setting up. Doing a little research on the web, I discovered that there is an export feature for a virtual machine available by right clicking on the machine’s name in the Hyper-V manager. I tried that. I didn’t see the feature.&lt;/p&gt; &lt;p&gt;Here’s what I got:&lt;/p&gt; &lt;p&gt;&lt;a href="http://lh6.ggpht.com/-cSnKjvNJoI4/TecAscwZoHI/AAAAAAAAAEM/8uXgqBbIwTE/s1600-h/NoExport2.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="NoExport" border="0" alt="NoExport" src="http://lh6.ggpht.com/-fh-k1wDpYgc/TecAs77fWuI/AAAAAAAAAEQ/gMDNl_QYwd4/NoExport_thumb.png?imgmax=800" width="139" height="244"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Huh?&amp;nbsp; My first guess was that the blog post describing the feature was for a different version of Hyper-V so I double checked the versions. Not the problem. Reading another blog post on the feature, I learned it was only available under certain conditions. Ah, that explained it. The virtual machine had to be in a “stopped” state.&amp;nbsp; &lt;/p&gt; &lt;p&gt;Right clicking on a machine in the “Off” state showed:&lt;/p&gt; &lt;p&gt;&lt;a href="http://lh3.ggpht.com/-A422eg535_g/TecAtabSIyI/AAAAAAAAAEU/aJUiS3KLrG0/s1600-h/Export2.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Export" border="0" alt="Export" src="http://lh3.ggpht.com/-2paALoe01lc/TecAtiJ1wUI/AAAAAAAAAEY/LbtIb_-dRLE/Export_thumb.png?imgmax=800" width="167" height="244"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Hmm. This could have been designed a bit better from a usability perspective.&amp;nbsp; Thinking back to the specification for this feature, I imagine* it read something like this:&lt;/p&gt; &lt;p&gt;&lt;a href="http://lh6.ggpht.com/-sJ0YQOG8zjU/TecAuOPa8PI/AAAAAAAAAEc/taCiCJBlC3k/s1600-h/ExportFeatureSpec13.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="ExportFeatureSpec" border="0" alt="ExportFeatureSpec" src="http://lh6.ggpht.com/-6_cBnOdb77k/TecAuTfRWwI/AAAAAAAAAEg/T_toh-khIKI/ExportFeatureSpec_thumb9.png?imgmax=800" width="522" height="98"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;And the feature tester might have verified the feature behaved exactly as stated in the spec without giving additional attention to how a user might have trouble discovering the export functionality. I wouldn’t be surprised if this is the implicit expectation of testers in some organizations.&lt;/p&gt; &lt;p&gt;Anyway, taking a step back, we can think beyond the spec and consider a few tweaks to improve usability. For example, the Export menu option could be grayed out when the virtual machine is not in a stopped state. Or it could still be clickable but offer an instructive error stating the operation is not allowed when the virtual machine is running.&amp;nbsp; This would be a good example of helping your users solve their own roadblocks.&lt;/p&gt; &lt;p&gt;So the next time your crafting your test plan, make sure you’re not simply testing the feature spec. Flex your testing creativity muscles and show off your usability testing prowess. Incidentally, those skills are much harder to outsource.&lt;/p&gt; &lt;p&gt;*&lt;font size="1"&gt;Could be wrong here.&amp;nbsp; Just using this as an example.&amp;nbsp; No offense intended to the feature testers of Hyper-V.&lt;/font&gt;&lt;/p&gt;  &lt;img src="http://feeds.feedburner.com/~r/TestingToasters/~4/P2FsBNkjYYY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.testingtoasters.com/feeds/2320313476166633016/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.testingtoasters.com/2011/06/testing-feature-specification.html#comment-form" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/2320313476166633016?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/2320313476166633016?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TestingToasters/~3/P2FsBNkjYYY/testing-feature-specification.html" title="Testing the Feature Specification" /><author><name>Mark Berryman</name><uri>http://www.blogger.com/profile/13905061216954268804</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_ffCx4LN58Fg/TGQi28CvgRI/AAAAAAAAAAM/NNfs4UhQkM8/S220/Me.JPG" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/-fh-k1wDpYgc/TecAs77fWuI/AAAAAAAAAEQ/gMDNl_QYwd4/s72-c/NoExport_thumb.png?imgmax=800" height="72" width="72" /><thr:total>3</thr:total><feedburner:origLink>http://www.testingtoasters.com/2011/06/testing-feature-specification.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUIAQ3s4eyp7ImA9WhZVGEQ.&quot;"><id>tag:blogger.com,1999:blog-8623130854307760074.post-3202713628985715568</id><published>2011-05-31T20:05:00.001-07:00</published><updated>2011-05-31T20:05:42.533-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-31T20:05:42.533-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Testing" /><title>Why Does Your Feature Exist?</title><content type="html">&lt;p&gt;As I’ve mentioned before, either on this blog or in the &lt;a href="http://www.codingqa.com"&gt;Coding QA podcast&lt;/a&gt;, my software testing activities include hopping around our larger product set to help test various features.&amp;nbsp; Whenever I take a look at a feature for the first time, I often ask the assigned feature tester “Why does your feature exist?”.&amp;nbsp; I expect to hear a convincing one minute &lt;a href="http://en.wikipedia.org/wiki/Elevator_pitch"&gt;elevator pitch&lt;/a&gt; explaining the customer value of the feature.&amp;nbsp; When testers can’t give this elevator pitch, it means they haven’t done their homework and are probably on tester auto-pilot which leads to testing devoid of creativity, and that spells bad news for customers.&lt;/p&gt; &lt;p&gt;Even when people can provide the elevator pitch, I try to challenge it.&amp;nbsp; For example, if you say “we’ve gotten a lot of customer feedback that this feature is something they really want.”, I’m going to ask about where the feedback came from and how much feedback did we actually get.&amp;nbsp; I want to know that I’m not just hearing a repeat of what’s defined in the feature spec or a regurgitation of something the PM has said.&amp;nbsp; Again, I’m hoping that people have truly internalized the customer value of their feature.&amp;nbsp; At a more fundamental level, I’m also doing a quick gut check to see if we’re wasting time on a feature that shouldn’t even exist.&lt;/p&gt; &lt;p&gt;Another benefit to understanding why your feature exists is that you’ll have a better sense of it’s priority relative to other features in the product. All features are not created equal. That doesn’t mean your feature isn’t exciting because it’s not at the top the list, but when testing or bug fixing time is limited and less is assigned to your feature, you’ll know why, and you won’t feel bad about it.&amp;nbsp; At a lead or manager level, this knowledge will also help you make better testing resource allocation decisions.&lt;/p&gt; &lt;p&gt;I also find that having a deeper understanding of why we develop certain features helps form a stronger connection to the customer, and this deeper understanding of the customer enables a tester to provide value that might be beyond expectations.&amp;nbsp; For example, if you know why the feature is valuable to customers, you’ll have a better understanding of how customers will use it.&amp;nbsp; This will in turn give you more ideas of how the feature should be tested to emulate that customer usage.&amp;nbsp; Finally, you’ll also be able to provide feedback on whether the feature is incomplete in terms of functionality or over designed.&lt;/p&gt; &lt;p&gt;The next time you’re assigned “Feature X”, make sure you understand why the feature exists.&amp;nbsp; Get excited about contributing to its development and know that you’ll be delighting your customers when it’s delivered.&amp;nbsp; After all, why would you want to spend your precious time working on something you don’t care about?&amp;nbsp; Life’s short.&amp;nbsp; Try to enjoy it.&lt;/p&gt;  &lt;img src="http://feeds.feedburner.com/~r/TestingToasters/~4/PWH1DDStq4A" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.testingtoasters.com/feeds/3202713628985715568/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.testingtoasters.com/2011/05/why-does-your-feature-exist.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/3202713628985715568?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/3202713628985715568?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TestingToasters/~3/PWH1DDStq4A/why-does-your-feature-exist.html" title="Why Does Your Feature Exist?" /><author><name>Mark Berryman</name><uri>http://www.blogger.com/profile/13905061216954268804</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_ffCx4LN58Fg/TGQi28CvgRI/AAAAAAAAAAM/NNfs4UhQkM8/S220/Me.JPG" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.testingtoasters.com/2011/05/why-does-your-feature-exist.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CE8FQHk6fCp7ImA9WhZVFEg.&quot;"><id>tag:blogger.com,1999:blog-8623130854307760074.post-7926947638102789734</id><published>2011-05-26T16:33:00.001-07:00</published><updated>2011-05-26T16:33:31.714-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-26T16:33:31.714-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Testing" /><title>Faster Bug Investigations – Guaranteed</title><content type="html">&lt;p&gt;A critical and likely time consuming role of any software tester’s job is conducting bug investigations.&amp;nbsp; I’ve certainly done my fair share over the years.&amp;nbsp; Some of these require minutes while others seem to drag on endlessly.&amp;nbsp; Personally, nothing is more groan inducing than having to investigate a bug report for an issue that occurs on the Albanian* version of Windows Server 2003, running as a Domain Controller in Turkmenistan, targeting a legacy version of the product and the application interacts with 3rd party components companies that no longer exist.&amp;nbsp; Oh, and it also occurs randomly. This is the bug from hell.&amp;nbsp; And it’s assigned to &lt;strong&gt;&lt;u&gt;You&lt;/u&gt;&lt;/strong&gt;!&lt;/p&gt; &lt;p&gt;Argh, chest pains…&lt;/p&gt; &lt;p&gt;So what’s your test plan?&amp;nbsp; Setting up a reproduction of this system and software will take you decades.&amp;nbsp; Flying to Turkmenistan** to meet with the customer to debug their system is unlikely to happen.&amp;nbsp; You’ve got to make progress and your next steps will determine whether this investigation completes in years, hours or never.&lt;/p&gt; &lt;p&gt;Now I’ve never had to investigate a bug like the one described but I’ve seen other examples that are kind of similar.&amp;nbsp; They’re complex, difficult to understand, involve many components and make me want to cry when I read about them.&amp;nbsp; But, I’ve embraced the Microsoft attitude of always trying to do my work more efficiently and have come up with some approaches to cut down on my costs.&amp;nbsp; &lt;br&gt;&lt;br&gt;Here’s an ordered list of questions to ask yourself and actions to take:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Are you the best person to do this investigation?  &lt;ul&gt; &lt;li&gt;Sometimes folks just assume that since the issue is assigned to them, they have to do it.&amp;nbsp; No.&amp;nbsp; Bad idea.&amp;nbsp; It’s possible someone else in the group is a much better choice for a host of reasons.&amp;nbsp; Maybe they’re an expert in the area.&amp;nbsp; Maybe they’re new to the team and you already dislike them.&lt;/li&gt;&lt;/ul&gt; &lt;li&gt;Scour the Internet for any information related to the bug.  &lt;ul&gt; &lt;li&gt;Believe it or not, this might not be the first time the issue has occurred and someone might have already taken a few minutes to do a nice write-up explaining things.&amp;nbsp; I’ve personally wasted plenty of time with bug investigations for scenarios that were easily discoverable and well-documented on the web.&lt;/li&gt;&lt;/ul&gt; &lt;li&gt;Who can help you understand the scenario and features involved?  &lt;ul&gt; &lt;li&gt;Never &lt;strike&gt;drink&lt;/strike&gt; work alone.&amp;nbsp; Use your extensive network of experts (Dev, Test, PM, &lt;a href="http://www.stackoverflow.com"&gt;StackOverflow&lt;/a&gt;) to help you fully understand the bug and the conditions under which it occurs.&lt;/li&gt;&lt;/ul&gt; &lt;li&gt;Which components of the bug investigation are immaterial?  &lt;ul&gt; &lt;li&gt;You can usually boil down the number of variables to a much smaller set of those that matter.&amp;nbsp; One approach might be to start from a “normal” configuration and tweak the system to match the bug repro one by one.&amp;nbsp; Using the crazy example from the beginning, start with an English version of Windows Server 2003 (I assume this is easier than the Albanian version to setup), not running as a domain controller and using a current version of the product.&amp;nbsp; If that doesn’t reproduce the issue, tweak one of the variables to align it with the original bug report. &lt;/li&gt;&lt;/ul&gt; &lt;li&gt;What can you fudge?  &lt;ul&gt; &lt;li&gt;Those 3rd party components from companies that no longer exist killing you?&amp;nbsp; What about coding up some stubs/mocks/fakes or whatever to simulate those pieces?&amp;nbsp; Or hook up a fantastic debugger (like the one in VS) and make the instruction pointer skip over those 3rd party component calls and then define your own values for any expected return values.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;Again, the point here is to try tactics to reduce the cost and pain of dealing with non-trivial bug reports.&amp;nbsp; If nothing else, remember my first point, and always consider how you can dump this task on someone else who happens to be (at least in your eyes) better capable to deal with the problem.&lt;/p&gt; &lt;p&gt;What did I miss here?&amp;nbsp; Anyone, anyone?&lt;/p&gt; &lt;p&gt;&lt;br&gt;&lt;font size="1"&gt;* No offense intended for Albanians.&amp;nbsp; My first manager at Microsoft was from Albania and he was (and likely still is) awesome.&lt;br&gt;** I’ve got a peer from Turkmenistan on my team.&amp;nbsp; He doesn’t recommend flying there.&amp;nbsp; I’ll taking his word on this.&lt;/font&gt;&lt;/p&gt;  &lt;img src="http://feeds.feedburner.com/~r/TestingToasters/~4/-7h0umqNgJM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.testingtoasters.com/feeds/7926947638102789734/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.testingtoasters.com/2011/05/faster-bug-investigations-guaranteed.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/7926947638102789734?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/7926947638102789734?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TestingToasters/~3/-7h0umqNgJM/faster-bug-investigations-guaranteed.html" title="Faster Bug Investigations – Guaranteed" /><author><name>Mark Berryman</name><uri>http://www.blogger.com/profile/13905061216954268804</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_ffCx4LN58Fg/TGQi28CvgRI/AAAAAAAAAAM/NNfs4UhQkM8/S220/Me.JPG" /></author><thr:total>2</thr:total><feedburner:origLink>http://www.testingtoasters.com/2011/05/faster-bug-investigations-guaranteed.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUYFQn86fSp7ImA9WhdQFUw.&quot;"><id>tag:blogger.com,1999:blog-8623130854307760074.post-5387767216309552771</id><published>2011-05-19T20:27:00.001-07:00</published><updated>2011-08-16T09:45:13.115-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-16T09:45:13.115-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Testing" /><category scheme="http://www.blogger.com/atom/ns#" term="Debugging" /><title>You’ll Probably Never Find This Bug</title><content type="html">At Microsoft there’s an expectation that Software Development Engineers in Test (SDET) are familiar with writing and reading code.&amp;nbsp; You’ll here me harping on this topic on various &lt;a href="http://www.codingqa.com/"&gt;Coding QA podcasts&lt;/a&gt; and this week, I was reminded again of why such skills are valuable.&lt;br /&gt;
&lt;br /&gt;
I’ve been spending my past few weeks testing new ASP.NET runtime features for our next release.&amp;nbsp; Some of these features have been easy to understand while others have baffled me in one way or another.&amp;nbsp; While testing one of the features that falls into the latter bucket, I was reminded of the value of white-box testing. &amp;nbsp;Since I don’t want to divulge the contents of unreleased features, I’ll frame this lesson in a made up context.&lt;br /&gt;
&lt;br /&gt;
Imagine you test an editor that’s way behind the times, and your team is finally getting around to adding a basic spell checking feature.&amp;nbsp; The feature is simple.&amp;nbsp; It scans the current text in editor and if it finds a spelling mistake, a dialog pops-up indicating this.&amp;nbsp;&amp;nbsp; That’s it.&amp;nbsp; No other fanciness was needed.&amp;nbsp; To invoke the feature, a new option has been added to the Edit menu item and you get the new design below.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&lt;a href="http://lh5.ggpht.com/_ffCx4LN58Fg/TdXfuERboPI/AAAAAAAAAD4/6xZ3m_t5wAw/s1600-h/SpellCheckMenu%5B32%5D.png"&gt;&lt;img alt="SpellCheckMenu" border="0" height="268" src="http://lh5.ggpht.com/_ffCx4LN58Fg/TdXfuaDabNI/AAAAAAAAAD8/iVGojoC_j3E/SpellCheckMenu_thumb%5B24%5D.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="SpellCheckMenu" width="210" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
You approach testing this feature from a black box perspective.&amp;nbsp; Using an automated data generation tool, you run through a ton of different input files.&amp;nbsp; All is well. The feature works perfectly, and the product is released.&lt;br /&gt;
&lt;br /&gt;
After a few months, your team starts receiving customer complaints that the spell checking feature is “slow” when running against large files.&amp;nbsp; Thinking back to your testing, you never really focused on performance testing so this isn’t a surprise.&amp;nbsp; Anyway, there’s a dedicated performance testing team that should have picked up on this.&amp;nbsp; That’s their domain after all.&lt;br /&gt;
&lt;br /&gt;
You head over to talk to the performance folks and they review their data.&amp;nbsp; Since it was a new feature, they didn’t have a baseline number to compare against so they focused on the fact that the time taken to run the spell check increased linearly with the size of the document.&amp;nbsp; That seemed logical and no performance issues were reported. &amp;nbsp;At this point, you resort to looping in the feature developer to review the code.&amp;nbsp; She does a quick scan, but comes up with nothing.&lt;br /&gt;
&lt;br /&gt;
Now what?&amp;nbsp;The story could simply end here with dissatisfied customers and an unexplained performance issue.&amp;nbsp; Fortunately though, we can go back to the beginning and convert the black box testing approach to also include some white box testing.&lt;br /&gt;
&lt;br /&gt;
After playing around with the feature for a while, you take a look at the code and decide it’s worth a few minutes of your time to set a few breakpoints and step through its execution.&amp;nbsp; That’s when you realize that every time the spell check feature is invoked from the menu, your breakpoint in the spell checking code is not hit once, but three times.&amp;nbsp; The results from the first two runs are tossed into the bit bucket while the result from the third run is returned to the user.&lt;br /&gt;
&lt;br /&gt;
Huh!?&amp;nbsp;Shouldn’t the developer have noticed this?&amp;nbsp; Possibly, but there’s a host of reasons why they might have missed this.&amp;nbsp; The issue is in an integration point between the editor application and the spell checking feature.&amp;nbsp; When the features were tested in isolation, the issue didn’t surface.&amp;nbsp; There’s something about the interaction between the two that triggers the problem.&amp;nbsp;As far fetched as this example might seem, I’ve seen it before and I’ve seen it again this week.&lt;br /&gt;
&lt;br /&gt;
Take a few minutes to set a few break points and step through your features code.&amp;nbsp; Make sure methods aren’t being invoked repeatedly when it doesn’t make sense and if you’re not familiar with debugging your product’s code, become familiar.&amp;nbsp; A few minutes of your time could uncover some interesting problems that are near impossible to identify with other testing techniques.&lt;br /&gt;
&lt;br /&gt;
Happy testing and debugging!&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;/span&gt;&lt;img src="http://feeds.feedburner.com/~r/TestingToasters/~4/kx6wvqm0mfc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.testingtoasters.com/feeds/5387767216309552771/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.testingtoasters.com/2011/05/youll-probably-never-find-this-bug.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/5387767216309552771?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/5387767216309552771?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TestingToasters/~3/kx6wvqm0mfc/youll-probably-never-find-this-bug.html" title="You’ll Probably Never Find This Bug" /><author><name>Mark Berryman</name><uri>http://www.blogger.com/profile/13905061216954268804</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_ffCx4LN58Fg/TGQi28CvgRI/AAAAAAAAAAM/NNfs4UhQkM8/S220/Me.JPG" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/_ffCx4LN58Fg/TdXfuaDabNI/AAAAAAAAAD8/iVGojoC_j3E/s72-c/SpellCheckMenu_thumb%5B24%5D.png?imgmax=800" height="72" width="72" /><thr:total>2</thr:total><feedburner:origLink>http://www.testingtoasters.com/2011/05/youll-probably-never-find-this-bug.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkUESHs6eip7ImA9WhZWEEQ.&quot;"><id>tag:blogger.com,1999:blog-8623130854307760074.post-6479980442523136700</id><published>2011-05-10T21:57:00.001-07:00</published><updated>2011-05-10T22:03:29.512-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-10T22:03:29.512-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Testing" /><title>Thinking Like a Developer</title><content type="html">&lt;p&gt;I don't often engage in pure black-box testing, but when I do, I try to make educated decisions about the test scenarios I run.&amp;nbsp; Just because you can't see the code, doesn't mean you can't identify test scenarios that are likely to uncover bugs.&amp;nbsp; &lt;/p&gt; &lt;p&gt;One tactic I like to employ is challenging unstated developer assumptions.&amp;nbsp; Uh, if they're unstated, how do you know what to challenge?&amp;nbsp; Well, you can expect that some of these assumptions might be universal.&amp;nbsp; In other words, you might make exactly the same assumptions.&amp;nbsp; So put yourself in the developer's shoes and imagine you had to implement the feature you're trying to test.&amp;nbsp; What assumptions might you make and how can you translate these into high value test scenarios?&amp;nbsp; Let's go through an example.&lt;/p&gt; &lt;p&gt;Image you're doing black-box testing for an XML editor feature whereby matching open and closing elements are highlighted when you put the cursor on one or the other.&amp;nbsp; Below is a screenshot of this editor editing an XML file. Imagine your cursor is over the opening tag for the first &amp;lt;Person&amp;gt; element so the corresponding closing tag is highlighted.&lt;/p&gt; &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_ffCx4LN58Fg/TcoXK3Ny3aI/AAAAAAAAADw/mqDJNCPl0kI/s1600-h/XmlFile%5B3%5D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="XmlFile" border="0" alt="XmlFile" src="http://lh5.ggpht.com/_ffCx4LN58Fg/TcoXLUZxTUI/AAAAAAAAAD0/DtjdOiDdPUs/XmlFile_thumb%5B1%5D.png?imgmax=800" width="370" height="271"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;br&gt;So you have an idea of how the feature behaves.&amp;nbsp; Now, put on the developer hat and challenge yourself to write the code implementing this feature.&lt;/p&gt; &lt;p&gt;What assumptions might you make about the XML file being edited or the editor environment itself?&lt;/p&gt; &lt;p&gt;Here are a few assumptions I came up with:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Opening and closing tag are never on the same line.  &lt;ul&gt; &lt;li&gt;Maybe every sample XML file you've seen always has the tag pairs on separate lines.&amp;nbsp; You therefore write code that one you find the opening tag, you immediately look at the next line and all subsequent lines for the closing tag.&lt;/li&gt;&lt;/ul&gt; &lt;li&gt;XML document is always encoded in UTF-8.  &lt;ul&gt; &lt;li&gt;That's the default encoding for any new XML file created and you've verified your string comparison operations work for UTF-8 encoding.&lt;/li&gt;&lt;/ul&gt; &lt;li&gt;There's always an open and closing tag pair  &lt;ul&gt; &lt;li&gt;Again, all of the sample XML files you've seen follow this rule.&amp;nbsp; To find the matching closing tag for an element, your code looks for a string matching the format "&amp;lt;/elementName&amp;gt;".&lt;/li&gt;&lt;/ul&gt; &lt;li&gt;Tags are edited via single character changes  &lt;ul&gt; &lt;li&gt;Users type characters one at a time using the keyboard.&amp;nbsp; After each keystroke, your code checks to see if the cursor is over a tag and then looks for the matching tag to highlight.&lt;/li&gt;&lt;/ul&gt; &lt;li&gt;The entire content of the XML file is always loaded in memory  &lt;ul&gt; &lt;li&gt;Looking for a matching closing tag always involves scanning each line of the file until you reach that matching tag or an end-of-file marker.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;Now take each of these assumptions, challenge it and generate a test scenario.&amp;nbsp; The tests for the first two assumptions above should be obvious so I'll just go over the last three.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;There's always an open and closing tag pair  &lt;ul&gt; &lt;li&gt;Test with tags that are self closing like "&amp;lt;Age /&amp;gt;".&lt;/li&gt;&lt;/ul&gt; &lt;li&gt;Tags are edited via single character changes  &lt;ul&gt; &lt;li&gt;Test changing tag names using copy/paste and find/replace operations.&lt;/li&gt;&lt;/ul&gt; &lt;li&gt;The entire content of the XML file is always loaded in memory  &lt;ul&gt; &lt;li&gt;Test using a very large file where the opening tag for an element is at the top of the file and the closing tag is at the very end of the file.&amp;nbsp; Maybe the editor implements some memory optimization whereby it only loads a chunk of the file necessary for displaying the current viewable contents.&amp;nbsp; Therefore, there's no end-of-file marker currently loaded into memory.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Good.&amp;nbsp; You've played the developer and thought about the assumptions you would make and then converted these into valuable test scenarios.&amp;nbsp; &lt;/p&gt; &lt;p&gt;You could take this approach a step further and also consider which feature scenarios might be hard to implement correctly.&amp;nbsp; Going back to the malformed XML document scenario, your feature implementation might still try to guess at the matching tag to highlight.&amp;nbsp; Getting this right could depend on the degree to which the document is malformed.&amp;nbsp; Is it only missing a single closing tag or is it a large file that's missing every single closing tag?&amp;nbsp; You'd want to test both of these scenarios.&lt;/p&gt; &lt;p&gt;When faced with black-box testing, look at as a challenge to generate educated test scenarios by doing some role playing.&amp;nbsp; Have fun pretending you're the developer.&amp;nbsp; Take your assumptions, test them and see what goes wrong.&lt;/p&gt;  &lt;img src="http://feeds.feedburner.com/~r/TestingToasters/~4/vzR0hotTa04" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.testingtoasters.com/feeds/6479980442523136700/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.testingtoasters.com/2011/05/thinking-like-developer.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/6479980442523136700?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/6479980442523136700?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TestingToasters/~3/vzR0hotTa04/thinking-like-developer.html" title="Thinking Like a Developer" /><author><name>Mark Berryman</name><uri>http://www.blogger.com/profile/13905061216954268804</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_ffCx4LN58Fg/TGQi28CvgRI/AAAAAAAAAAM/NNfs4UhQkM8/S220/Me.JPG" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/_ffCx4LN58Fg/TcoXLUZxTUI/AAAAAAAAAD0/DtjdOiDdPUs/s72-c/XmlFile_thumb%5B1%5D.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://www.testingtoasters.com/2011/05/thinking-like-developer.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkABRng-fSp7ImA9Wx9aFU0.&quot;"><id>tag:blogger.com,1999:blog-8623130854307760074.post-4050968052785079623</id><published>2011-03-07T06:39:00.001-08:00</published><updated>2011-03-07T06:39:17.655-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-03-07T06:39:17.655-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Testing" /><title>Podcast - CodingQA.com</title><content type="html">&lt;p&gt;Fellow team member &lt;a href="http://www.osbornm.com/"&gt;Matthew Osborn&lt;/a&gt; has turned over the &lt;a href="http://codingqa.com/"&gt;CodingQA podcast&lt;/a&gt; to myself and &lt;a href="http://weblogs.asp.net/jimwang/"&gt;Jim Wang&lt;/a&gt;.&amp;nbsp; The podcast has provided deep insight into the way testing is done on the ASP.NET QA Team, and I hope we can continue that.&amp;nbsp; Please join us there each week (or maybe every other week) as we discuss current topics in testing based on our real-world experiences at Microsoft..&lt;/p&gt; &lt;p&gt;The latest episode, &lt;a href="http://codingqa.com/episode-51-new-owners-and-testers-as-developers"&gt;“Episode 51 – New Owners and Test as Dev”&lt;/a&gt; was just uploaded this weekend.&amp;nbsp; Check it out and let me know what you think.&amp;nbsp; Future show topic ideas are much appreciated.&lt;/p&gt;  &lt;img src="http://feeds.feedburner.com/~r/TestingToasters/~4/RzWKI3I6u5E" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.testingtoasters.com/feeds/4050968052785079623/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.testingtoasters.com/2011/03/podcast-codingqacom.html#comment-form" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/4050968052785079623?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/4050968052785079623?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TestingToasters/~3/RzWKI3I6u5E/podcast-codingqacom.html" title="Podcast - CodingQA.com" /><author><name>Mark Berryman</name><uri>http://www.blogger.com/profile/13905061216954268804</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_ffCx4LN58Fg/TGQi28CvgRI/AAAAAAAAAAM/NNfs4UhQkM8/S220/Me.JPG" /></author><thr:total>4</thr:total><feedburner:origLink>http://www.testingtoasters.com/2011/03/podcast-codingqacom.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUMERn48fyp7ImA9Wx9WFkU.&quot;"><id>tag:blogger.com,1999:blog-8623130854307760074.post-3329706218442046855</id><published>2011-01-22T00:03:00.001-08:00</published><updated>2011-01-22T00:03:27.077-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-01-22T00:03:27.077-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Testing" /><title>Here Today, Gone Tomorrow</title><content type="html">&lt;p&gt;Quick post on a common bug I see with code using &lt;a href="http://en.wikipedia.org/wiki/Cache"&gt;Caches&lt;/a&gt;. It's easy to forget that a cache is "volatile" storage. Items inserted (cached) today, might not be there later since they can be evicted from the cache. The reason for the eviction is dependent on the caching system implementation. When writing code utilizing a cache, they key point is to always check the return value from a "cache get" operation to ensure the result wasn't a "cache miss". I've often seen code like this:  &lt;blockquote&gt; &lt;p&gt;&lt;font face="Consolas"&gt;string dataToCache = &amp;lt;generate data to cache&amp;gt;;&lt;br&gt;cache.Set("item", dataToCache );&lt;/font&gt;  &lt;p&gt;&lt;font face="Consolas"&gt;&amp;lt;other code here&amp;gt;&lt;/font&gt;  &lt;p&gt;&lt;font face="Consolas"&gt;string cachedData = Cache.Get("item");&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;Danger! Danger!&lt;/font&gt;&lt;/strong&gt; At the point you do the "Cache.Get("item")" call, you've no guarantee that the your cached data item will be returned. You could get a "null" value back indicating a cache miss. Further use of your "cachedData" variable beyond this point won't end well.  &lt;p&gt;The code needs to be re-written and include a check on the value of "cachedData". Something like:  &lt;blockquote&gt; &lt;p&gt;&lt;font face="Consolas"&gt;string cachedData = Cache.Get("item");&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font face="Consolas"&gt;if (cachedData == null) {&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // cache miss; need to generate the data again&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; dataToCache = &amp;lt;generate data to cache&amp;gt;;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // shove it back into the cache and hope it stays there&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Cache.Set("item", dataToCache );&lt;br&gt;}&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;A tricky aspect of this type of bug is that it’s hard to catch given the non-deterministic nature of cache item eviction. The code could run perfectly hundreds of times because the right "pressure" isn't put on the cache to trigger item eviction. Code inspections are helpful here. Just do a high level "find" on your code base for your known caching API's and see what turns up.  &lt;p&gt;Looking ahead, I see that HTML5 has a new "localStorage" feature for long-term "persistent" storage. I'm no expert on this, but from what I can tell, it seems like code working with this feature might be prone to core caching mistake I've described. We'll see...  &lt;p&gt;Happy testing.&lt;/p&gt;  &lt;img src="http://feeds.feedburner.com/~r/TestingToasters/~4/FWmCL1LaqzA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.testingtoasters.com/feeds/3329706218442046855/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.testingtoasters.com/2011/01/here-today-gone-tomorrow.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/3329706218442046855?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/3329706218442046855?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TestingToasters/~3/FWmCL1LaqzA/here-today-gone-tomorrow.html" title="Here Today, Gone Tomorrow" /><author><name>Mark Berryman</name><uri>http://www.blogger.com/profile/13905061216954268804</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_ffCx4LN58Fg/TGQi28CvgRI/AAAAAAAAAAM/NNfs4UhQkM8/S220/Me.JPG" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.testingtoasters.com/2011/01/here-today-gone-tomorrow.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0UHRnk6cCp7ImA9Wx9WEEs.&quot;"><id>tag:blogger.com,1999:blog-8623130854307760074.post-9124417695374656370</id><published>2011-01-14T21:27:00.001-08:00</published><updated>2011-01-14T21:27:17.718-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-01-14T21:27:17.718-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Testing" /><title>Fails On My Machine</title><content type="html">&lt;p&gt;This past week, I've been busy working on final testing activities for our launch of &lt;a href="http://www.microsoft.com/web/"&gt;WebMatrix&lt;/a&gt;. Last minute sanity checks and stuff like that. As part of this work, I ran into an issue that stumped me. I couldn't explain why I hit the issue and nobody else could reproduce it.  &lt;p&gt;Ah, no need for alarm here. Must be a common case of "Fails on My Machine"&lt;strong&gt;*&lt;/strong&gt; meaning that I've simply screwed up something on my box (tweaked a config setting I've since forgot, deleted a necessary binary, etc.). No product bug here.  &lt;p&gt;Wait a minute!  &lt;p&gt;Letting go of these "one off" failures is hard for me. They often reappear in a customer bug report down the road, and I feel foolish for not investigating them when I hit them.  &lt;p&gt;No way that's happening again. I took a step back and tried to reason through the problem. Below is a dump of my thought process. (If .NET and ASP.NET are not familiar to you, sorry. Hopefully, you can still glean some value out of this post.)  &lt;p&gt;The first step was to identify the variables involved on all machines where we tried to reproduce the problem. I ended up with this: &lt;/p&gt; &lt;table border="1" cellspacing="0" cellpadding="2" width="438"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td valign="top" width="80"&gt; &lt;p align="center"&gt;&amp;nbsp;&lt;/p&gt;&lt;/td&gt; &lt;td valign="top" width="93"&gt; &lt;p align="center"&gt;&lt;strong&gt;Web Server&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt; &lt;td valign="top" width="101"&gt; &lt;p align="center"&gt;&lt;strong&gt;Dll’s location&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt; &lt;td valign="top" width="74"&gt; &lt;p align="center"&gt;&lt;strong&gt;OS&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt; &lt;td valign="top" width="88"&gt; &lt;p align="center"&gt;&lt;strong&gt;Result&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" width="80"&gt; &lt;p align="center"&gt;Me&lt;/p&gt;&lt;/td&gt; &lt;td valign="top" width="93"&gt; &lt;p align="center"&gt;IIS&lt;/p&gt;&lt;/td&gt; &lt;td valign="top" width="101"&gt; &lt;p align="center"&gt;GAC&lt;/p&gt;&lt;/td&gt; &lt;td valign="top" width="74"&gt; &lt;p align="center"&gt;Windows 7&lt;/p&gt;&lt;/td&gt; &lt;td valign="top" width="88"&gt; &lt;p align="center"&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;Failure&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" width="80"&gt; &lt;p align="center"&gt;Person A&lt;/p&gt;&lt;/td&gt; &lt;td valign="top" width="93"&gt; &lt;p align="center"&gt;IIS Express&lt;/p&gt;&lt;/td&gt; &lt;td valign="top" width="101"&gt; &lt;p align="center"&gt;GAC&lt;/p&gt;&lt;/td&gt; &lt;td valign="top" width="74"&gt; &lt;p align="center"&gt;Windows 7&lt;/p&gt;&lt;/td&gt; &lt;td valign="top" width="88"&gt; &lt;p align="center"&gt;&lt;strong&gt;&lt;font color="#00ff00"&gt;Success&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" width="80"&gt; &lt;p align="center"&gt;Person B&lt;/p&gt;&lt;/td&gt; &lt;td valign="top" width="93"&gt; &lt;p align="center"&gt;IIS&lt;/p&gt;&lt;/td&gt; &lt;td valign="top" width="101"&gt; &lt;p align="center"&gt;GAC&lt;/p&gt;&lt;/td&gt; &lt;td valign="top" width="74"&gt; &lt;p align="center"&gt;Vista&lt;/p&gt;&lt;/td&gt; &lt;td valign="top" width="88"&gt; &lt;p align="center"&gt;&lt;strong&gt;&lt;font color="#00ff00"&gt;Success&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;From this table, I saw that my web server differed from Person A's, but matched Person B's so I didn't think the web server difference mattered. Similarly, my OS differed from Person B's yet matched Person A's. Again, OS didn't seem to matter.  &lt;p&gt;Something else was missing from my list of variables. Was my root web.config different? Nope. Were we using the same build. Yep. Ugh, I couldn't figure it out and even sent mail to the team to not worry about the problem. It had to be a case of "Fails On My Machine"*.  &lt;p&gt;But then it hit me. I hadn't considered OS bitness. Adding that, I got: &lt;/p&gt; &lt;table border="1" cellspacing="0" cellpadding="2" width="478"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td valign="top" width="78"&gt; &lt;p align="center"&gt;&amp;nbsp;&lt;/p&gt;&lt;/td&gt; &lt;td valign="top" width="92"&gt; &lt;p align="center"&gt;&lt;strong&gt;Web Server&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt; &lt;td valign="top" width="95"&gt; &lt;p align="center"&gt;&lt;strong&gt;Dll’s location&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt; &lt;td valign="top" width="70"&gt; &lt;p align="center"&gt;&lt;strong&gt;OS&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt; &lt;td valign="top" width="51"&gt; &lt;p align="center"&gt;&lt;strong&gt;&lt;font style="background-color: #ffff00"&gt;Bitness&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt; &lt;td valign="top" width="90"&gt; &lt;p align="center"&gt;&lt;strong&gt;Result&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" width="78"&gt; &lt;p align="center"&gt;Me&lt;/p&gt;&lt;/td&gt; &lt;td valign="top" width="92"&gt; &lt;p align="center"&gt;IIS&lt;/p&gt;&lt;/td&gt; &lt;td valign="top" width="95"&gt; &lt;p align="center"&gt;GAC&lt;/p&gt;&lt;/td&gt; &lt;td valign="top" width="70"&gt; &lt;p align="center"&gt;Windows 7&lt;/p&gt;&lt;/td&gt; &lt;td valign="top" width="51"&gt; &lt;p align="center"&gt;64-bit&lt;/p&gt;&lt;/td&gt; &lt;td valign="top" width="90"&gt; &lt;p align="center"&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;Failure&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" width="78"&gt; &lt;p align="center"&gt;Person A&lt;/p&gt;&lt;/td&gt; &lt;td valign="top" width="92"&gt; &lt;p align="center"&gt;IIS Express&lt;/p&gt;&lt;/td&gt; &lt;td valign="top" width="95"&gt; &lt;p align="center"&gt;GAC&lt;/p&gt;&lt;/td&gt; &lt;td valign="top" width="70"&gt; &lt;p align="center"&gt;Windows 7&lt;/p&gt;&lt;/td&gt; &lt;td valign="top" width="51"&gt; &lt;p align="center"&gt;64-bit&lt;/p&gt;&lt;/td&gt; &lt;td valign="top" width="90"&gt; &lt;p align="center"&gt;&lt;strong&gt;&lt;font color="#00ff00"&gt;Success&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" width="78"&gt; &lt;p align="center"&gt;Person B&lt;/p&gt;&lt;/td&gt; &lt;td valign="top" width="92"&gt; &lt;p align="center"&gt;IIS&lt;/p&gt;&lt;/td&gt; &lt;td valign="top" width="95"&gt; &lt;p align="center"&gt;GAC&lt;/p&gt;&lt;/td&gt; &lt;td valign="top" width="70"&gt; &lt;p align="center"&gt;Vista&lt;/p&gt;&lt;/td&gt; &lt;td valign="top" width="51"&gt; &lt;p align="center"&gt;32-bit&lt;/p&gt;&lt;/td&gt; &lt;td valign="top" width="90"&gt; &lt;p align="center"&gt;&lt;strong&gt;&lt;font color="#00ff00"&gt;Success&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;Now I saw that while Person B had the same web server, our OS's bitness differed. That was the key. The issue only reproduced on 64-bit machines.  &lt;p&gt;But hang on. If that were true, then Person A should have gotten a failure. Even though they were running a different web server, IIS Express compared to my IIS, it would have run as a 64-bit process and mimicked my setup. Why the difference in result?  &lt;p&gt;I made a bad assumption. Turns out, IIS Express runs as a 32-bit process on a 64-bit OS. That's why Person A didn't see the failure. It only occurred when the web server ran as a 64-bit process.  &lt;p&gt;Problem solved. Bug filed&lt;strong&gt;**&lt;/strong&gt;.  &lt;p&gt;Key points for me:  &lt;ul&gt; &lt;li&gt;The &lt;a href="http://www.testingtoasters.com/p/qualities-of-successful-tester.html"&gt;tenacious quality&lt;/a&gt; I've previously mentioned came into play again. Sadly, I wavered a bit on this quality at the start of this investigation.&lt;/li&gt;&lt;/ul&gt; &lt;ul&gt; &lt;li&gt;"Fails on My Machine"&lt;strong&gt;*&lt;/strong&gt; mysteries must be investigated. Don't quickly convince yourself that there's simply something screwed up with your box. Dig into it. I've added a quality related to this to my &lt;a href="http://www.testingtoasters.com/p/qualities-of-successful-tester.html"&gt;Qualities of a Successful Tester&lt;/a&gt; page.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Happy testing!  &lt;p&gt;&lt;font size="1"&gt;&lt;strong&gt;*&lt;/strong&gt;Folks at work slap a "Works on My Machine" graphic disclaimer on new bits to indicate it worked for them, but there’s no guarantee the bits will work for you. I'm going to flip that around and use "Fails on My Machine" to describe bits that fail on your machine but work on everyone else’s.&lt;/font&gt;  &lt;p&gt;&lt;font size="1"&gt;&lt;strong&gt;**&lt;/strong&gt;Sorry folks. You will get a Security Exception when viewing "online" package feeds in our new package management admin UI when running in partial trust and 64-bit IIS. My deepest apologies. I hope we can get this resolved soon.&lt;/font&gt;&lt;/p&gt;  &lt;img src="http://feeds.feedburner.com/~r/TestingToasters/~4/NIRHZX1a4P4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.testingtoasters.com/feeds/9124417695374656370/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.testingtoasters.com/2011/01/fails-on-my-machine.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/9124417695374656370?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/9124417695374656370?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TestingToasters/~3/NIRHZX1a4P4/fails-on-my-machine.html" title="Fails On My Machine" /><author><name>Mark Berryman</name><uri>http://www.blogger.com/profile/13905061216954268804</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_ffCx4LN58Fg/TGQi28CvgRI/AAAAAAAAAAM/NNfs4UhQkM8/S220/Me.JPG" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.testingtoasters.com/2011/01/fails-on-my-machine.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0ICR3gyeSp7ImA9Wx9XFEs.&quot;"><id>tag:blogger.com,1999:blog-8623130854307760074.post-5014411384313999803</id><published>2011-01-07T21:46:00.001-08:00</published><updated>2011-01-07T21:46:06.691-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-01-07T21:46:06.691-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Testing" /><title>Qualities of a Successful Tester</title><content type="html">&lt;p&gt;Over the past seven years at Microsoft, I've seen some testers be amazingly successful and others not nearly as successful. What makes the difference? I thought I'd start 2011 trying to capture a distinguishing set of qualities that might account for this. By no means am I claiming that I possess all of these. I'm just calling out what I've noticed over the years. Some items are not test specific, but I'll try to frame them in testing related contexts so they're not generic statements. Items are also not listed in any sort of priority order. &lt;/p&gt; &lt;p&gt;&lt;strong&gt;Collaborates with others&lt;/strong&gt;&lt;br&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;You need to collaborate and more often than general day-to-day interactions. You need a network of folks that trust you and will gladly help you as needed. Leveraging their expertise amplifies your abilities.&lt;br&gt;&lt;br&gt;As a tester, for example, you should feel comfortable barging into a developers office for help on understanding a feature or to debate a bug resolution. You should feel comfortable barging into a PM's office to complain about a poor spec or to question the need for a feature. You should feel comfortable barging into your fellow tester's office for feedback on your test strategy. &lt;br&gt;&lt;br&gt;Make sure this collaboration isn't one way. Encourage others to come to you for the same assistance. &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Knows their customer&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;This knowledge will allow you to impact feature design beyond identifying poor variable names (that was me early on). You'll also help your team fix the right set of bugs, because you understand the scenarios that are critical to your customer. Similarly, you'll make better testing tradeoffs. Consider being asked to test your feature across a large set of configurations and the cost of doing so, exceeds your resources. Fortunately, you know the most common customer configurations and can intelligently prune the set. &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Views Test, Dev, and PM as one team&lt;br&gt;&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Avoid an "us" vs. "them" mentality. Think single team where a failure by one is a failure by all. This will influence the way you view the role of the tester. You'll discover opportunities to add value beyond traditional test activities (e.g., small feature implementation or bug fixes) and the other disciplines will be more willing to assist with testing tasks. &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Learns from mistakes&lt;br&gt;&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;You will make mistakes. Don't hide them. Instead, confess and learn. That's probably easier said then done. Make a concentrated effort to learn from your mistakes (e.g., in a team meeting, discuss a bug you missed).&lt;br&gt;&lt;br&gt;Learn from other's mistakes as well. Having a trusted network (previously mentioned) of teammates makes this much easier as you'll have a friendly discussion regarding these mistakes. &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Never rushes testing&lt;br&gt;&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Testing well requires the right amount of time. Never rush it as that only leads to mistakes (e.g. improper bug fix verification). Take your time. The bugs will wait. &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Tenacious&lt;/strong&gt;&lt;br&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Some bugs take hours to nail down Keep at it. It's probably worth it. &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Keeps calm&lt;/strong&gt;&lt;br&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Fire drills happen more often than we'd like. Remain calm. They can be a source of amazing testing inefficiency because people are testing in a panic. Take a step back, analyze the situation, and then act. See my previous point about not rushing testing as well. You'll likely feel compelled to do this. &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Attention to detail&lt;/strong&gt;&lt;br&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;This one's a personal favorite because of the disparity I see between interview candidates. Given the same web page, ten people will define ten significantly different sets of tests. Some will have a test for every page element while others will miss entire sections of the page. Pay close attention to your work or risk missing bugs. &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Speaks up&lt;/strong&gt;&lt;br&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;When you disagree, speak up. Not enough time allotted for adequate testing? Say so, and be prepared to justify your claim. Pushback without justification is pointless. Silence is agreement. &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Creates quality bug reports&lt;/strong&gt;&lt;br&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Clear - The bug report is quickly understood. Folks are not left scratching their heads from reading a poorly worded bug title. The repro steps are easily followed by someone other than the finder. Etc. &lt;br&gt;&lt;br&gt;Accurate - The bug reports contents are accurate. Repro steps reflect the exact actions taken. The severity rating (if you have such a field) matches the bug. &lt;br&gt;&lt;br&gt;Complete - If repro files are needed, they're provided. This could be a small code sample or a virtual machine. Think about making the developer's life easier. &lt;br&gt;&lt;br&gt;Explains customer impact - Bugs that correctly explain he customer impact are less likely to be improperly rejected for fixing. Of course to do this, you need to know your customer. See previous regarding point. &lt;br&gt;&lt;br&gt;Sometimes written, sometimes spoken - Don't default to filing every issue in your bug tracking system. Discussing the bug in person with a developer might be more efficient. If you're using your bug tracking system to sort through bug details, something's likely wrong. &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Uses a toolbox&lt;/strong&gt;&lt;br&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Your toolbox should include a set of test tools, techniques and people that you collectively leverage to test. &lt;br&gt;&lt;br&gt;Tools - Not a test automation tool. Yes, that's important for catching regressions, but I'm referring to tools that assist actual testing. Maybe that's a simple stress client, model-based tool or data generation tool. &lt;br&gt;&lt;br&gt;Techniques - You need different testing techniques. An "Exploratory Testing" approach might be appropriate or a scripted deep dive might be better. Know when to use which. &lt;br&gt;&lt;br&gt;People - Your teammates are your friends. Some will have more domain knowledge than you in an area you're testing. I run for help when localization testing is needed. It's not my area of expertise. Neither is JavaScript. One caveat. Don't let these folks become a crutch. Learn from them. &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Able to read code&lt;/strong&gt;&lt;br&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;It's helpful to be able to read product code. If you can't do this, your bug reports might lack a depth of understanding and resemble statements like "I did this and then that happened" as opposed to "I did this and that happened because we failed to check for null". The latter could be helpful to the developer and further build your network of trusted teammates (again, see previous point).&lt;br&gt;&lt;br&gt;If you can't read code, there's likely a bucket of bugs you'll miss because they're either non-trivial to uncover through normal product interaction (e.g., race condition or failure to handle a specific exception). &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Passion&lt;/strong&gt;&lt;br&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Ah, passion. The buzzword that's required to be successful at anything. I believe it's true though, and I see the need for passion in two areas.&lt;br&gt;&lt;br&gt;One, you need to be passionate about the product you test. Is there another product that's more interesting to you? If so, why not move? If not, you'll probably actively pursue building your domain knowledge around your product, customers and maybe even competitors. See my previous comments on why I think this is beneficial.&lt;br&gt;&lt;br&gt;Second, there's passion for the craft of testing. If you're not excited by your daily work, you're either in the wrong role, wrong team or doing the wrong testing work. Fix this. Strive to be a better tester every day. Teach others about testing and learn from them. Bottom line - love what you do and have fun. &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Okay, that's it for a first cut. This list is replicated on &lt;a href="http://www.testingtoasters.com/p/qualities-of-successful-tester.html"&gt;Qualities of a Successful Tester&lt;/a&gt;, and I will make updates to that page going forward.&lt;/p&gt; &lt;p&gt;Happy New Year and happy testing!&lt;/p&gt;  &lt;img src="http://feeds.feedburner.com/~r/TestingToasters/~4/FAvDYoovuys" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.testingtoasters.com/feeds/5014411384313999803/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.testingtoasters.com/2011/01/qualities-of-successful-tester.html#comment-form" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/5014411384313999803?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/5014411384313999803?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TestingToasters/~3/FAvDYoovuys/qualities-of-successful-tester.html" title="Qualities of a Successful Tester" /><author><name>Mark Berryman</name><uri>http://www.blogger.com/profile/13905061216954268804</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_ffCx4LN58Fg/TGQi28CvgRI/AAAAAAAAAAM/NNfs4UhQkM8/S220/Me.JPG" /></author><thr:total>3</thr:total><feedburner:origLink>http://www.testingtoasters.com/2011/01/qualities-of-successful-tester.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DE4AQn88eSp7ImA9Wx9QFkU.&quot;"><id>tag:blogger.com,1999:blog-8623130854307760074.post-573236992484146716</id><published>2010-12-29T21:29:00.001-08:00</published><updated>2010-12-29T21:29:03.171-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-12-29T21:29:03.171-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Testing" /><title>Buggy Distractions</title><content type="html">&lt;p&gt;It’s a tester’s natural tendency to run to their bug tracking tool as soon as they find a bug, but sometimes that’s not the wisest course of action.&amp;nbsp; It’s possible that the bug you’re seeing is just the tip of the iceberg and underneath is a more serious issue.&amp;nbsp; By filing that initial bug report, you might be distracted away from doing a deeper investigation of the issue.&lt;/p&gt; &lt;p&gt;Let me share a real world example.&amp;nbsp; &lt;/p&gt; &lt;p&gt;We’re currently working on a new syntax for ASP.NET and we want this new syntax to “light up” (e.g., keywords should be highlighted correctly) in Visual Studio editor just like classic ASP.NET syntax.&amp;nbsp; A few months ago, we noticed that syntax highlighting disappeared if you renamed the file extension that was currently open in the editor.&amp;nbsp; The workaround, close and re-open the file, seemed simple, and this user scenario seemed unlikely so we passed on fixing the bug at that time.&lt;/p&gt; &lt;p&gt;Fast forward to a few weeks ago.&amp;nbsp; The same issue is reported again but this time we decide it &lt;strong&gt;&lt;em&gt;must be fixed&lt;/em&gt;&lt;/strong&gt;.&amp;nbsp; What?&amp;nbsp; That’s the same bug we raised a long time ago.&amp;nbsp; Why the urgency all of a sudden?&lt;/p&gt; &lt;p&gt;It turns out the problem also occurs if you simply rename the file.&amp;nbsp; Not just the extension.&amp;nbsp; Ah, now &lt;strong&gt;&lt;em&gt;that’s&lt;/em&gt;&lt;/strong&gt; a common user scenario that needs to be fixed.&lt;/p&gt; &lt;p&gt;So why didn’t we catch that variation of the bug the first time around?&amp;nbsp; I think it’s because we ran into the initial problem (file extension rename), reported the issue and then diverted our attention to the next test scenario.&amp;nbsp; The first way the bug manifested itself simply distracted us from doing a deeper investigation.&amp;nbsp; Had we thought about the issue for a few minutes, I’m almost certain we could have identified the more serious user scenario.&amp;nbsp; Argh.&lt;/p&gt; &lt;p&gt;Lesson learned.&lt;/p&gt; &lt;p&gt;Happy testing!&lt;/p&gt;  &lt;img src="http://feeds.feedburner.com/~r/TestingToasters/~4/htbhspMD4kc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.testingtoasters.com/feeds/573236992484146716/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.testingtoasters.com/2010/12/buggy-distractions.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/573236992484146716?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/573236992484146716?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TestingToasters/~3/htbhspMD4kc/buggy-distractions.html" title="Buggy Distractions" /><author><name>Mark Berryman</name><uri>http://www.blogger.com/profile/13905061216954268804</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_ffCx4LN58Fg/TGQi28CvgRI/AAAAAAAAAAM/NNfs4UhQkM8/S220/Me.JPG" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.testingtoasters.com/2010/12/buggy-distractions.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUMCRn8-fip7ImA9Wx9RFUk.&quot;"><id>tag:blogger.com,1999:blog-8623130854307760074.post-3115531214803449353</id><published>2010-12-16T16:57:00.001-08:00</published><updated>2010-12-16T16:57:47.156-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-12-16T16:57:47.156-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Testing" /><title>Spec? I Don’t Need No Stinking Spec</title><content type="html">&lt;p&gt;Whenever I’m asked to test a new feature, one of the first things I do is toss out the spec.&amp;nbsp; I’m not interested in reading it right off the bat.&amp;nbsp; Rather, I’d prefer someone briefly explain the feature to me.&amp;nbsp; Just a high level overview of how it works and the customer scenario it’s solving.&amp;nbsp; Beyond that, I don’t want to know anything else (at least not today).&lt;/p&gt; &lt;p&gt;Why do I take this approach?&amp;nbsp; Simple.&amp;nbsp; I want to make mistakes.&amp;nbsp; I want to emulate the time honored tradition of folks using something before reading through the documentation.&amp;nbsp; I want to “be the customer”.&lt;/p&gt; &lt;p&gt;Reading a spec immediately starts my testing down the “happy path” of product use, and I don’t want to be on that path.&amp;nbsp; I want to get on the exact opposite path and by doing so, I’ll hopefully perform the same actions as the customer.&amp;nbsp; &lt;/p&gt; &lt;p&gt;For example, &lt;/p&gt; &lt;ul&gt; &lt;li&gt;I’ll perform a sequence of operations in an unexpected order.&amp;nbsp; &lt;li&gt;I’ll repeat a redundant operation multiple times.  &lt;li&gt;I’ll pass ridiculous parameter values to an API.&amp;nbsp; &lt;li&gt;I’ll simply screw things up in ways the product team never imagined.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;So why make these same “mistakes”?&amp;nbsp; Two reasons.&amp;nbsp; Making these mistakes will provide me with valuable information in the related areas of error handling and usability.&amp;nbsp; &lt;/p&gt; &lt;p&gt;In terms of error handling, I’ll be able to evaluate how the feature responds to the unexpected.&amp;nbsp; Does it hang or crash?&amp;nbsp; Does it corrupt data?&amp;nbsp; Does it open up a security vulnerability?&amp;nbsp; Or, assuming it “handles” the unexpected, I can now assess “how” it handles it.&amp;nbsp; &lt;/p&gt; &lt;p&gt;The “how” is related to usability.&amp;nbsp; When the customer does something wrong, are they steered back on track with a helpful error message, or are they presented with some obscure error code or something from the &lt;a href="http://www.testingtoasters.com/p/error-message-hall-of-shame.html"&gt;Error Message Hall of Shame&lt;/a&gt;?&amp;nbsp; I hope the feature enables them to get back on track on their own for two reasons.&amp;nbsp; First, this reduces customer dissatisfaction and second, it potentially avoids a costly support call by an angry customer.&lt;/p&gt; &lt;p&gt;So take that spec, &lt;u&gt;&lt;strong&gt;ignore it&lt;/strong&gt;&lt;/u&gt;, and test away.&amp;nbsp; Make mistakes.&amp;nbsp; Make lots and lots of mistakes.&lt;/p&gt; &lt;p&gt;Happy testing!&lt;/p&gt;  &lt;img src="http://feeds.feedburner.com/~r/TestingToasters/~4/8Ms35aVfWpw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.testingtoasters.com/feeds/3115531214803449353/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.testingtoasters.com/2010/12/spec-i-dont-need-no-stinking-spec.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/3115531214803449353?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/3115531214803449353?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TestingToasters/~3/8Ms35aVfWpw/spec-i-dont-need-no-stinking-spec.html" title="Spec? I Don’t Need No Stinking Spec" /><author><name>Mark Berryman</name><uri>http://www.blogger.com/profile/13905061216954268804</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_ffCx4LN58Fg/TGQi28CvgRI/AAAAAAAAAAM/NNfs4UhQkM8/S220/Me.JPG" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.testingtoasters.com/2010/12/spec-i-dont-need-no-stinking-spec.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0IEQXkyeSp7ImA9Wx5UEkQ.&quot;"><id>tag:blogger.com,1999:blog-8623130854307760074.post-9071603635727217337</id><published>2010-10-16T21:58:00.001-07:00</published><updated>2010-10-16T21:58:20.791-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-16T21:58:20.791-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Testing" /><title>Should QA be the Gatekeeper?</title><content type="html">&lt;p&gt;&lt;strong&gt;&lt;font size="3" face="Calibri"&gt;Definition of GATEKEEPER&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="3"&gt;&lt;font face="Calibri"&gt;1: one that tends or guards a gate &lt;br&gt;&lt;font color="#ff0000"&gt;&lt;font color="#000000"&gt;2:&lt;/font&gt; &lt;strong&gt;a person who controls access&lt;/strong&gt; &lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;In your team, who decides when it’s time to release a product?&amp;nbsp; Who controls access to the “door of product release”?&amp;nbsp; I’m going to bet it’s QA that’s on the hook for that final signoff indicating testing is “complete” and the product is ready to ship.&amp;nbsp; But should this be QA’s decision?&amp;nbsp; I don’t think so, and our group has had some lively discussions recently regarding this and it seems that others might agree.&amp;nbsp; Yet I bet most groups still see QA playing this traditional role and this can put QA in a bad position.&lt;/p&gt; &lt;p&gt;First, as the gatekeeper, you get the ultimate “say so” regarding whether or not a product is ready to ship and with great power comes great responsibility.&amp;nbsp; Ship a product that has a bug found by your customers – QA made a mistake.&amp;nbsp; They said the product was ready to ship so if something was missed, the screwed up.&amp;nbsp; Getting into this type of blame game leads to a further downward spiral whereby QA enters &lt;a href="http://en.wikipedia.org/wiki/Cover_your_ass"&gt;CYA&lt;/a&gt; mode.&amp;nbsp; Now QA does everything under the sun to prevent a bug from slipping through.&amp;nbsp; That small feature that took PM and dev one week to design and code will now take QA two months to test.&amp;nbsp; Every test scenario must be run and then re-run if there’s a code change.&amp;nbsp; Every test scenario must have regression automation and must be tested across twenty different configurations.&amp;nbsp; There’s no way QA is going to miss a bug now, because if they’re going to fill their role as the gatekeeper, they’ve got to get everything right and that takes time.&amp;nbsp; A lot of time.&lt;/p&gt; &lt;p&gt;Now doing everything possible to find bugs is a good thing, but it comes at a cost.&amp;nbsp; Time and resources are limited which means QA’s work needs to fit into the schedule and if that doesn’t work for feature X, then QA isn’t approving it.&amp;nbsp; “No!”.&amp;nbsp; We’re not doing that feature.&amp;nbsp; Getting into the habit of saying “no” outright because testing a feature doesn’t fit into QA’s schedule creates an unhealthy tension between the disciplines.&amp;nbsp; The others soon start viewing QA as a roadblock to product development because they’re always saying “no” even if the feature makes fantastic business sense.&lt;/p&gt; &lt;p&gt;So how about something different?&amp;nbsp; What if instead of saying “no” when testing activities don’t fit into the schedule, QA is viewed as an organization that simply provides data and an assessment of a product’s quality.&amp;nbsp; That doesn’t require a fixed amount of time.&amp;nbsp; Give us two days to test and we’ll give you whatever data we can product using those two days, but we won’t make a call at the end regarding a product’s readiness to ship.&amp;nbsp; That’s a management decision.&amp;nbsp; Taking this stance has the added benefit of allowing the team to make tradeoffs with QA’s time.&amp;nbsp; Want to cram another feature in two weeks before release?&amp;nbsp; Sure, we can do that but it’s coming at the cost of testing some other feature.&amp;nbsp; QA is no longer saying “no” right off the bat.&amp;nbsp; Instead, we’re now ready to discuss tradeoffs to make it happen and in the end, customer’s get a better product and QA is no longer viewed as the group that prevents features from being implemented.&lt;/p&gt; &lt;p&gt;QA provides data.&amp;nbsp; Management makes the release call.&amp;nbsp; That’s the way it should be, and I’m happy to see my group moving in that direction.&lt;/p&gt;  &lt;img src="http://feeds.feedburner.com/~r/TestingToasters/~4/9mQes7II4VM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.testingtoasters.com/feeds/9071603635727217337/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.testingtoasters.com/2010/10/should-qa-be-gatekeeper.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/9071603635727217337?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/9071603635727217337?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TestingToasters/~3/9mQes7II4VM/should-qa-be-gatekeeper.html" title="Should QA be the Gatekeeper?" /><author><name>Mark Berryman</name><uri>http://www.blogger.com/profile/13905061216954268804</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_ffCx4LN58Fg/TGQi28CvgRI/AAAAAAAAAAM/NNfs4UhQkM8/S220/Me.JPG" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.testingtoasters.com/2010/10/should-qa-be-gatekeeper.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0AFQXY7fyp7ImA9Wx5WFkk.&quot;"><id>tag:blogger.com,1999:blog-8623130854307760074.post-3479336686958661240</id><published>2010-09-27T19:41:00.001-07:00</published><updated>2010-09-27T19:41:50.807-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-09-27T19:41:50.807-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Testing" /><title>Error Messages - What’s Not To Love?</title><content type="html">&lt;p&gt;I was trying to run Windows Update the other day and it failed with:&lt;/p&gt; &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_ffCx4LN58Fg/TKFV53dVVQI/AAAAAAAAACo/yXV0jZynsPM/s1600-h/UnhelpfulErrorMessage2%5B12%5D.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="UnhelpfulErrorMessage2" border="0" alt="UnhelpfulErrorMessage2" src="http://lh6.ggpht.com/_ffCx4LN58Fg/TKFV6eUbehI/AAAAAAAAACs/JXDjYW3sQI4/UnhelpfulErrorMessage2_thumb%5B8%5D.jpg?imgmax=800" width="378" height="143"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;Umm, an unknown error.&amp;nbsp; Okay, what to do next?&amp;nbsp; Well, there’s an error code and I’m computer savvy enough to punch that in to my favorite search engine.&amp;nbsp; Fail. I can’t copy/paste the contents of the dialog.&amp;nbsp; I need to type in this cryptic code manually and need to get it right.&amp;nbsp; Wait, there’s a link to “Get help with this error”.&amp;nbsp; I’ll give that a try instead.&amp;nbsp; Ah, some success.&amp;nbsp; I get a page with error codes and I see mine which basically says to retry later.&amp;nbsp; Okay, I can do that.&amp;nbsp; At least I have some hope of resolving this problem.&lt;/p&gt; &lt;p&gt;I rate this error dialog as “fair”.&amp;nbsp; I’m able to figure out the next step to take to solve the problem.&amp;nbsp; Grandma on the other hand.&amp;nbsp; Maybe not.&amp;nbsp; It would have been better if copy/paste had worked, but the UI didn’t allow it.&amp;nbsp; The “Get help” link was also nice and I can understood how this is a good design decision since the link’s target is probably easily updateable content.&amp;nbsp; Better to have this over static content baked into the product.&amp;nbsp; Still, is this something that grandma is going to figure out or will she be sending an email to the support department or worse, simply skip applying updates to her system?&amp;nbsp; Maybe it would have better to directly tell folks to try again in a few minutes &lt;u&gt;and&lt;/u&gt; provide the link for additional help.&lt;/p&gt; &lt;p&gt;Anyway, the point of this post is to get you thinking about the contents and usability of error messages.&amp;nbsp; They’re all over the place and poor ones can lead to user frustration and dissatisfaction with your product.&amp;nbsp; Personally, I find nothing more frustrating than a cryptic error message which offers me no guidance on what to do next and when I encounter such messages, I have to wonder if folks could have tried a bit harder to help me out.&amp;nbsp; Thought being a tester, I can envision the conversation in triage regarding the poor error message.&amp;nbsp; The bug was deemed “low priority” and fell off the radar as time ran out (error message….phwwwtttt!!).&amp;nbsp; Or, the bug was quickly rejected as being low value.&amp;nbsp; Too bad, so sad…for your users.&lt;/p&gt; &lt;p&gt;Here’s another one I hit when using a tool to create web sites (&lt;em&gt;&lt;font size="1"&gt;app name redacted&lt;/font&gt;&lt;/em&gt;)::&lt;/p&gt; &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_ffCx4LN58Fg/TKFV6zgK7NI/AAAAAAAAACw/aa7s1U2jLfQ/s1600-h/UnhelpfulErrorMessage%5B2%5D.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="UnhelpfulErrorMessage" border="0" alt="UnhelpfulErrorMessage" src="http://lh5.ggpht.com/_ffCx4LN58Fg/TKFV7fyaqCI/AAAAAAAAAC0/F4L-duH_9_8/UnhelpfulErrorMessage_thumb.jpg?imgmax=800" width="200" height="159"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Uh, what’s invalid?&amp;nbsp; Site name too long?&amp;nbsp; Bad characters in the name?&amp;nbsp; Duplicate name?&amp;nbsp; Who knows?&amp;nbsp; Not getting any help here.&amp;nbsp; I’m guessing at the problem.&amp;nbsp; Not a good user experience.&amp;nbsp; Fortunately, it won’t look like this in the final product because we realize our users deserve better.&lt;/p&gt; &lt;p&gt;As an exemplary tester, you need to call out poor error messages and push for meaningful ones that help users get back on track.&amp;nbsp; When evaluating an error message, ask yourself - &lt;em&gt;“Is the message telling the user what to do next?”.&lt;/em&gt;&amp;nbsp; If the answer is “no”, think about how it could change to provide that guidance.&amp;nbsp; If you get pushback on making the change, play the “reduced product support” costs card.&amp;nbsp; Would you rather have grandma take the next step on her own or call your PSS (Product Support Services)?&lt;/p&gt; &lt;p&gt;Okay, so you’re convinced that error messages need to lead users to the “next step”.&amp;nbsp; Good.&amp;nbsp; But wait, there’s a potential pitfall lurking for you dear tester.&amp;nbsp; Simply put, you might not be a good candidate for spotting these issues.&amp;nbsp; Outside of blatantly obvious cases, picking up on poor error messages can be tricky since you’re used to seeing them in the feature your testing and you have context that can skew your view on the quality of an error message.&amp;nbsp; So take a step back, grab someone who isn’t familiar with your feature and have them take a look.&amp;nbsp; If they can’t understand what’s gone wrong and what to do next, your users are most likely hosed.&lt;/p&gt;  &lt;img src="http://feeds.feedburner.com/~r/TestingToasters/~4/8OhqtU-cSRU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.testingtoasters.com/feeds/3479336686958661240/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.testingtoasters.com/2010/09/error-messages-whats-not-to-love.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/3479336686958661240?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/3479336686958661240?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TestingToasters/~3/8OhqtU-cSRU/error-messages-whats-not-to-love.html" title="Error Messages - What’s Not To Love?" /><author><name>Mark Berryman</name><uri>http://www.blogger.com/profile/13905061216954268804</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_ffCx4LN58Fg/TGQi28CvgRI/AAAAAAAAAAM/NNfs4UhQkM8/S220/Me.JPG" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/_ffCx4LN58Fg/TKFV6eUbehI/AAAAAAAAACs/JXDjYW3sQI4/s72-c/UnhelpfulErrorMessage2_thumb%5B8%5D.jpg?imgmax=800" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://www.testingtoasters.com/2010/09/error-messages-whats-not-to-love.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkcCSHkzfCp7ImA9Wx5XEU4.&quot;"><id>tag:blogger.com,1999:blog-8623130854307760074.post-2971923419301551191</id><published>2010-09-10T08:54:00.001-07:00</published><updated>2010-09-10T08:54:29.784-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-09-10T08:54:29.784-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Tools" /><category scheme="http://www.blogger.com/atom/ns#" term="Testing" /><title>If A Picture Is Worth A Thousand Words…</title><content type="html">&lt;p&gt;&lt;font size="2"&gt;Then an HD video must be worth a bit more than that.&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2"&gt;I’ve always been a fan of using screenshots wisely in bug reports to help convey an issue.&amp;nbsp; I say “wisely” here because I’ve seen some cases where they’ve been misapplied. For example, taking a screen shot of a stack trace isn’t a good idea.&amp;nbsp; It’s not searchable.&amp;nbsp; You’re better off pasting the entire stack in the bug report.&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2"&gt;Anyway, I’ve been trying to go one better than just a screenshot, and I’m now experimenting with recording videos (no audio yet) of my ET sessions.&amp;nbsp; While I normally take detailed notes as I’m conducting my ET sessions, there are occasions where I hit an issue that either isn’t easy to describe in text or it’s not trivially reproducible (the bane of testing).&amp;nbsp; For those non-reproducible cases, I end up adding a sad comments in my notes to the effect of “Such and such happened, but I can’t easily repro it.&amp;nbsp; Good luck with that one.”.&amp;nbsp; With a video in hand, I have concrete proof of the issue a bit more hope that something captured in the video makes the repro possible.&amp;nbsp; &lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2"&gt;I’ve played around with capturing videos of bugs in the past using free software, but it hasn’t been a great experience.&amp;nbsp; Either the UI or performance is poor.&amp;nbsp; These days, I’ve put a much higher value on my time so plunking down a few hundred bucks (especially if they’re Microsoft’s dollars) to buy some professional commercial software is the way to go.&amp;nbsp; &lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2"&gt;Currently, I’m using &lt;/font&gt;&lt;a href="http://www.techsmith.com/camtasia.asp"&gt;&lt;font size="2"&gt;Camtasia Studio&lt;/font&gt;&lt;/a&gt;&lt;font size="2"&gt; to capture the video.&amp;nbsp; It’s trivial to use, fast and not &lt;strong&gt;&lt;em&gt;that &lt;/em&gt;&lt;/strong&gt;expensive - $299 for a single license (30 day free trial).&amp;nbsp; When I compare the amount of time it saves me multiplied the amount I’m paid per hour, it’s a good deal and I’m glad my manager agrees.&amp;nbsp; Now in my testing notes, I’ve got little video clips interspersed for certain issues.&amp;nbsp; These are especially helpful for issues involving a UI.&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2"&gt;If you think recoding your testing sessions might save you time as well, but you’re worried management won’t fork over the cash to buy a license, download the trial version, create some bug video examples and explain how having these saved you time and helped your team nail one more tricky bug.&amp;nbsp; I’m sure management will see your point quickly.&amp;nbsp; Well, at least I hope they do.&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2"&gt;Lights.&amp;nbsp; Camera.&amp;nbsp; Action.&amp;nbsp; Bugs.&lt;/font&gt;&lt;/p&gt;  &lt;img src="http://feeds.feedburner.com/~r/TestingToasters/~4/xPFJAl_Gwxw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.testingtoasters.com/feeds/2971923419301551191/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.testingtoasters.com/2010/09/if-picture-is-worth-thousand-words.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/2971923419301551191?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/2971923419301551191?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TestingToasters/~3/xPFJAl_Gwxw/if-picture-is-worth-thousand-words.html" title="If A Picture Is Worth A Thousand Words…" /><author><name>Mark Berryman</name><uri>http://www.blogger.com/profile/13905061216954268804</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_ffCx4LN58Fg/TGQi28CvgRI/AAAAAAAAAAM/NNfs4UhQkM8/S220/Me.JPG" /></author><thr:total>2</thr:total><feedburner:origLink>http://www.testingtoasters.com/2010/09/if-picture-is-worth-thousand-words.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkcNQH8zcCp7ImA9Wx5QGUQ.&quot;"><id>tag:blogger.com,1999:blog-8623130854307760074.post-1153188229465086519</id><published>2010-09-08T19:08:00.001-07:00</published><updated>2010-09-08T19:08:11.188-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-09-08T19:08:11.188-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Testing" /><title>When Reinventing The Wheel, Avoid Making It A Square</title><content type="html">&lt;p align="left"&gt;&lt;font size="2"&gt;&lt;a href="http://weblogs.asp.net/jimwang/"&gt;Jim&lt;/a&gt; and I were code reviewing a set of API’s the other day that involved database operations.&amp;nbsp; These API’s were basically a conversion of code written years ago for an older version of our framework.&amp;nbsp; While looking at the new version, we noticed some issues.&amp;nbsp; For example, we had an API doing two dependent database operations that should have been in a transaction but weren’t.&amp;nbsp; We compared the new code to the original version and found that in the original version, the operations were done in a transaction.&amp;nbsp; I knew this was important because I had tested the original version and remember us hitting the need to do these operations in transactions.&lt;/font&gt;&lt;/p&gt; &lt;p align="left"&gt;&lt;font size="2"&gt;Anyway, there were other similar issues with the code which led us to the conclusion that errors were being made because instead of directly porting the code, we were trying to rewrite it without carefully considering some of the design decisions made in the original implementation.&amp;nbsp; Initially, that was surprising yet not unrealistic since the original version was written over five years ago by a developer who is no longer with our group.&amp;nbsp; In some ways, we were reinventing the wheel and making some of the same mistakes along the way as we did the first time around.&amp;nbsp; &lt;/font&gt;&lt;/p&gt; &lt;p align="left"&gt;&lt;font size="2"&gt;&lt;strong&gt;Point #1:&lt;/strong&gt;&amp;nbsp; When testing a new feature, determine if it’s been implemented before in some manner and compare the implementations (design, behavior and past bugs) to see if the same mistakes are being repeated.&amp;nbsp; You&amp;nbsp; might need to ask some “old timers” on the team for help if deep historical knowledge of the product is going to be required.&amp;nbsp; To do even better, determine when this is happening in the design phase of a new feature and raise the issues before a single line of code has been written.&lt;/font&gt;&lt;/p&gt; &lt;p align="left"&gt;&lt;font size="2"&gt;Moving along, we started to systematically walk through each API, comparing the versions and noting each difference that needed to be addressed.&amp;nbsp; After we got a handful of these, it dawned on us that this wasn’t the most efficient way to approach fixing the larger issue so we instead chose to go with filing a single bug indicating a developer code review of the two versions was needed.&amp;nbsp; That was certainly a lot more efficient than filing individual bugs for every issue and thankfully, our team doesn’t use a “bugs opened” metric to evaluate tester performance.&amp;nbsp; You can see how in this case it would have led to less efficient behavior.&amp;nbsp; Plus, directing the developers to do a more detailed overall code review of these API’s helps push quality upstream.&lt;/font&gt;&lt;/p&gt; &lt;p align="left"&gt;&lt;font size="2"&gt;&lt;strong&gt;Point #2:&lt;/strong&gt;&amp;nbsp; Evaluating tester performance based on the number of bugs opened can lead to less than optimal results.&amp;nbsp; I won’t belabor this point.&amp;nbsp; It’s been beaten to death by others.&lt;/font&gt;&lt;/p&gt; &lt;p align="left"&gt;&lt;font size="2"&gt;&lt;strong&gt;Point #3:&lt;/strong&gt;&amp;nbsp; If you hit a bug farm in your feature, consider alternate ways of efficiently getting the issues addressed besides filing a bunch of bugs for every single problem.&amp;nbsp; For example, you could raise the general issues to the developer and ask them to review their code and make fixes.&amp;nbsp; Or, you might even sit with the developer, walk them through the issues, watch them make the fixes and discuss test scenarios before any new code is checked in.&amp;nbsp; IMO, this would be a bit of the holy grail of testing with respect to pushing quality upstream.&lt;/font&gt;&lt;font size="2"&gt;&lt;/p&gt;&lt;/font&gt; &lt;p align="left"&gt;&lt;font size="2"&gt;Okay, so that’s what I learned (or re-learned) earlier this week.&amp;nbsp; As always, never stop striving for improved testing efficiency and effectiveness.&lt;/font&gt;&lt;/p&gt;  &lt;img src="http://feeds.feedburner.com/~r/TestingToasters/~4/Y-74B5nS86g" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.testingtoasters.com/feeds/1153188229465086519/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.testingtoasters.com/2010/09/when-reinventing-wheel-avoid-making-it.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/1153188229465086519?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8623130854307760074/posts/default/1153188229465086519?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TestingToasters/~3/Y-74B5nS86g/when-reinventing-wheel-avoid-making-it.html" title="When Reinventing The Wheel, Avoid Making It A Square" /><author><name>Mark Berryman</name><uri>http://www.blogger.com/profile/13905061216954268804</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_ffCx4LN58Fg/TGQi28CvgRI/AAAAAAAAAAM/NNfs4UhQkM8/S220/Me.JPG" /></author><thr:total>1</thr:total><feedburner:origLink>http://www.testingtoasters.com/2010/09/when-reinventing-wheel-avoid-making-it.html</feedburner:origLink></entry></feed>
