Archive for the ‘Testing’ Category
-
Best Links of the Week – Mar 27th 2010
More good links to share with others.
- Ouija Board Estimation\Seance Sizing – a new method for estimation that relies on team, not the undead.
- Is the Agile Community Being Unreasonable? – InfoQ takes a look at the friction between the PMBOK and Agile principles.
- Toyotas’ Journey from Waterfall to Lean Software Development – Henrick Kniberg takes a visit to Toyota and peaks under the hood to see how a Lean company develops software. What he finds will surprise you!
- Defining the Last Responsible Moment - Karl Scotland puts some meat on this fuzzy Lean concept by looking at the cost vs benefit of delay.
- Managing vs. Coaching vs. Mentoring - Jurgen Appelo makes the distinction between these three concepts.
- The Problems With Acceptance Testing – thoughtful entry by Jim Shore reevaluating the importance of automated acceptance testing on Agile projects.
- Alternatives to Acceptance Testing – more from Jim Shore on what can be used in place of automated acceptance testing.
- More on Automated Acceptance Testing - George Dinwiddie adds his perspective to the topic of automated acceptance testing.
- The Path to Frequent Deployments – a report from Kent Beck, author of Extreme Programming, on how to increase development speed by moving from annual to quarterly to monthly to weekly and finally to daily deployments.
- How to Be a Great Tech Leader – Richard Kasperowski talks about the technical elements needed to succeed when running an Agile project.
-
Best Links of the Week – New Year Edition
New Year links, a little late, but ready for your review.
- Defense Procurement Goes Agile – a summary from the Agile Process Leadership Network’s (APLN) October 2009 meeting describing how the DoD is moving away from waterfall to an iterative, incremental processes.
- Mixing it up with Agile & PMI – Orange County PM, Donna Reed, makes the claim that to be a successful Agile PM one needs to “move away from ACTIVITY-BASED project management toward VALUE-BASED project management.”
- Starting Scrum: What Would be the Logical Position of a Classic PM – SM or PO? – a Google groups discussion posed by a member with some excellent commentary.
- Synchronize Rather than Overlap Sprints - Mike Cohn explains why aligning Sprint end dates within one or two days of each other is a much better way to coordinate multiple Scrum teams.
- Agile Antipattern: Changing the Definition of Done – Bob Hartman discusses how the pressure to meet deadlines is simply “deficit spending” on your project with a bill that will get paid off sooner than you think.
- Welfare CSM Day 3: Experimental Mobiles & Rainforest Birds – interesting experience report about a different type of Certified ScrumMaster trainer; be sure to read the comments for additional insights and reflections by the other participants.
- UI Test Automation Tools are Snake Oil – an opinionated piece from Michael Feathers on the value of that expensive UI test tool gathering dust in your organization.
-
The problem with most TDD trainings is…
… they are too short.
Mark Levison has posted an interesting article, Making TDD Stick, on InfoQ that covers some of my observations about how to sustain test-driven development (TDD) in an organization. I have found the best way to teach TDD is to mentor\pair with an individual one-on-one until they “get it” (about 4 to 6 weeks).
Unfortunately, one-on-one mentoring is not feasible or economic as bigger organizations try to improve their quality with TDD. There are just not that many self-proclaimed TDD experts out there. To solve this scarcity issue, often times big companies bring in a TDD expert to provide classroom training for the 40 or so developers deficient in this skill. Once the trainer has been scheduled, the participants are rounded up, sit in a one or two day class, the consultant gets their check and then nothing happens!
I have not seen the model of flying in a training for a one or two day training ever work. Why? People do not know what to do after the trainer leaves. TDD is hard and makes highly skilled (and highly paid) professionals feel like morons. After a day of flailing about in their IDE, most developers jettison the whole thing and walk away with the idea that TDD only works on “toy projects”. Not surprising since that is all they saw in their training – an easy-to-understand and easy-to-teach example that fits within the confines of a day. Little guidance or no guidance is provided on how to apply the TDD concepts back at your desk.
What is my alternative? Make the class longer – about two to three weeks.
- Week One – Basic TDD training (up to 1 day) followed by 4 days of practical application.
- Week Two – Advanced TDD concepts (up to 1 day) followed by 4 days of practical application.
- Week Three (optional) – Five days of practical application and mentoring.
At the end of each day, I gather all the team members together for an afternoon show-and-tell of all the tests they wrote. Everyone is required to show at least one test. The purpose of the discussion is to learn where people are having trouble, who needs help from the trainer, what is working for the developers and allow people to express their frustrations. The daily retrospective amplifies the learning and allows the teams members (or the trainer) to make mentoring connections among themselves. At least you now have a fighting chance to make TDD succeed instead of people suffering alone at their desk hating life.
-
Extract Method – The Most Important Refactoring EVER
Coming off my last rant, I thought it might be valuable to the community if I were to blog on the various refactorings I felt software developers should be using if they consider themselves professionals. To that end, I am going to borrow the refactoring patterns from Martin Fowler’s book, but provide up-to-date examples in C# code. To start the series off, I will start with the one refactoring ever developer should know and love – Extract Method.
How Do I Find It?: You have a code fragment that can be grouped together.
What Do I Do Once I Found It?: Turn the fragment into a method whose name explains the purpose of the method.
Fear not if you have never heard of this refactoring. It is so fundamental that many developers execute this pattern as a matter-of-course, but did not know the name for it; well, now you do – it is called Extract Method. IMO, mastering this refactoring is the key to understanding the later refactorings, like Extract Class, which we will discuss next week.
So, how do you located code that is a candidate for this refactoring? Here are some guidelines I use:
- Long methods -> methods that exceed 20 lines are a good candidate for this refactoring since they are normally doing more than one thing.
- Code comments -> comments are normally a visual marker that the next lines are conceptual similar and this refactoring is about grouping conceptual similar things in methods.
I randomly searched through our source code repository at work and in a mere 24.4 seconds I found this sample code from a utility class (Util.cs). It is a nice method that does a useful thing (removes extra decimal points from a string – who knew you needed to do that, but why not?), and it needs some help based on my guidelines above:
44 static public string RemoveExtraDecimalPoint(string text) 45 { 46 string returnString = ""; 47 int countDecimal = 0; 48 49 foreach (char character in text) 50 { 51 if (character == '.') 52 { 53 countDecimal++; 54 } 55 } 56 57 if (countDecimal > 1) 58 { 59 bool first = true; 60 foreach (char character in text) 61 { 62 returnString += character.ToString(); 63 int length = returnString.Length; 64 if (character == '.') 65 { 66 if (first == true) 67 { 68 first = false; 69 } 70 else 71 { 72 returnString = returnString.Remove(returnString.Length - 1, 1); 73 } 74 } 75 } 76 } 77 else 78 { 79 returnString = text; 80 } 81 82 return returnString; 83 }What makes this a good candidate for Extract Method is this method us 39 lines long – WAY too long for a method if our target is to create method from 5 to 10 lines long (which is the target of this refactoring). Remember, one of the main goals of Extract Method is to create small methods with intention revealing method names that read like comments. Our main focus will be to turn this long method in to a series of method calls which tell the reader what happens inside RemoveExtraDecimalPoint.
The first step after identifying a candidate method for Extract Method is to check the unit tests for this method and make sure they run. Surprise, surprise – this method has no tests!! Just a polite reminder – never, ever refactor code without having either an automated unit test or integration test confirming you did not break anything. That is called hacking. Yes, there will be times you have to “hack” something in, but while learning how to refactor is not it. Writing a unit test after-the-fact is called a characterization test. Here is one of my unit tests (I actually wrote five tests) that will serve as my safety net during the refactoring:
22 [TestMethod] 23 public void RemoveExtraDecimalPointTest() 24 { 25 // setup 26 27 // execute 28 string test = Utils.RemoveExtraDecimalPoint("23..45.0."); 29 30 // verify 31 Assert.AreEqual("23.450", test, "Extra decimal points not removed."); 32 33 // teardown 34 }My very first Extract Method refactoring will focus on line 47 in the original sample code. The code below shows the new method call I made for this refactoring:
44 static public string RemoveExtraDecimalPoint(string text) 45 { 46 string returnString = ""; 47 int countDecimal = Utils.CountDecimalsInString(text); 48 49 if (countDecimal > 1) 50 {The Extract Method refactoring product a method 10 lines long and has an intention revealing name.
77 private static int CountDecimalsInString(string text) 78 { 79 int countDecimal = 0; 80 foreach (char character in text) 81 { 82 if (character == '.') 83 { 84 countDecimal++; 85 } 86 } 86 return countDecimal; 87 }We run all our tests, everything passes, we are fine! Time to move on to find another chunk of code to extract. Next we take a look at line 59 from the original code and use Extract Method to make the following new method.
89 private static string ParseExtraDecimalPoints(string text) 90 { 91 string returnString = ""; 92 bool first = true; 93 94 foreach (char character in text) 95 { 96 returnString += character.ToString(); 97 if (character == '.') 98 { 99 if (first == true) 100 { 101 first = false; 101 } 102 else 103 { 104 returnString = returnString.Remove(returnString.Length - 1, 1); 105 } 106 } 107 } 108 return returnString; 109 }Again: run all the test, everything passes, we are fine! Notice that our extracted method is a little long (20 lines), but conceptually all the code in ParseExtraDecimalPoints is related, so we are OK. Remember, we are more interested in finding related code than following a rule of “10 lines or less”. Even if all you can pull out is a 200 line method, then that is cool – it is a first start once you pull one chunk out, you can begin to see the smaller chunks embedded in there.
But what does the refactored method look like? I highlighted the addition of the two static methods – CountDecimalsInString and ParseExtraDecimalPoints – to make it easier to see our changes.
44 static public string RemoveExtraDecimalPoint(string text) 45 { 46 string returnString = ""; 47 int countDecimal = Utils.CountDecimalsInString(text); 48 49 if (countDecimal > 1) 50 { 51 returnString = Utils.ParseExtraDecimalPoints(text); 52 } 53 else 54 { 55 returnString = text; 56 } 57 58 return returnString; 59 }Upon examination, we see the refactored version of RemoveExtraDecimalPoint is only 15 lines long and does just two things: counts decimal points and parses code to remove extra decimal points. Oh, that is real easy to understand as opposed to trying to read the original 39 lines of code (take a look if you don’t believe me) with all the loops, conditionals and white space and trying to figure things out.
And that is the point of the Extract Method refactoring.
-
Fake Objects
I was writing some tests today around some legacy code (its about 2 weeks old and not written with TDD) and wanted to make sure that some method was called when the parent method was invoked. Unfortunately, I was having some problems with getting RhinoMocks working. Since I was getting frustrated with some “stupid” tool and not making any progress, I decided to go back to first principles to look for a simpler way to write my test.
This was the code I was working with and I wanted to write a test that proved line 28 was called:
22 public virtual void AcceptMessage(IBusMessage message) 23 { 24 if (!Power) 25 { 26 return; 27 } 28 ProcessMessage(message); 29 }If you look at the rest of the code, this method comes from an abstract base class and the method in question (line 28) is abstract, protected AND void, so just calling it and looking at the return value is not a strategy I can use. To write the other tests I had written earlier in the day I had used the Fake Object concept just so I can get the object in the testing harness. Keep in mind, I am not trying to fake any collaborator, just test the base class since it does real things I want to make sure happen (or get updated) as the design evolves (you might be thinking this is a dumb place to start with a test, but you have to start somewhere).
Since I have complete control over my fake object and the method I want to make sure is abstract, I can insert a sensing variable in my fake object and set its state when the method (ProcessMethod) is called, like so:
10 public bool MessageProcessed = false; 11 12 protected override void ProcessMessage(IBusMessage message) 13 { 14 MessageProcessed = true; 15 }Here is my test:
63 [TestMethod] 64 public void AcceptMessageWithPowerTest() 65 { 66 // setup 67 FakeDevice test = new FakeDevice(); 68 test.Power = true; 69 70 IBusMessage message = new BusMessage(); 71 72 // exercise 73 test.AcceptMessage(message); 74 75 // verify 76 Assert.IsTrue(test.MessageProcessed, "Process message not called."); 77 78 // clean-up 79 }OK, kinda like using a sledgehammer to hit a carpet nail, but it got me unstuck and back to a green bar. Now, maybe I can spend sometime with RhinoMocks and figure out the easier way to do this.
-
“Unit testing never took off”
… said Agitar CEO Jerry Rudisin from SD Times.
“The practice works, but it hasn’t taken off as a mainstream practice.”
In 2008, I find this quote surprising and saddening that we still do not have software developers recognizing the need for automated unit testing. Sure, a lot of people now talk a good game about unit testing (how can they not since it is talked about so much), but they don’t really buy it. I see it with the teams I work with today and teams I worked with in the past. When I was interviewing at SAIC, I specifically asked the team if they did unit testing (it was my minimal qualification for the job) and I got nods from everyone at the table. Little did I know that we were talking about completely different things: I was talking about Michael Feathers’s definition of unit testing and they were talking about a more classic definition of unit testing. It was an immediate mismatch of expectations and goes back to an earlier post on being precise in language.
So how do we bridge the gap and help people understand the value of automated unit testing? I think the first step is to help people understand that testing is really a design activity. Writing automated unit tests is defining your API so that it may be consumed by its very first client, the test harness. I have always believed (and found through practice), that if your application is hard to test, the design is likely overly complex. Tests that are hard to set-up, or exercise, normally mean the classes are too tightly coupled. Or put another way, the classes know too much about the internal workings of other classes and your design concepts are not properly encapsulated, i.e. you have leaky abstractions.
I understand it is hard to change the way we code, especially if we have habits that have helped us be successful for many years. However, what really has helped me crystallize the importance of writing automated unit tests and practicing TDD is a quote I heard from Alan Shalloway, and I am paraphrasing here:
“I am putting the bugs into the system. There are no people, or gremlins, coming in at night sprinkling bugs while I am gone. It is me, so I need to do practices that stop me from putting more bugs into the system and TDD is what works for me.” [emphasis added]
So, I guess the first thing that needs to happen is not learning testing is a design activity, but accepting responsibility we are responsible for the low quality and wanting to make things better. Without that, unit testing will never take off.
Frequent Topics
Agile Agile SD Certified ScrumMaster Class Design Coaching Collaboration Communication Conferences Daily Scrum Design Excellence Design for Six Sigma Extreme Programming Games Innovation Games Lean Legacy Code Links of the Week Measures Movies Pair Programming Personal Planning PMI Practices Presentations Product Owner Quality Refactoring Retrospectives Rugby Scrum ScrumMaster SIMSOC Spain Team Test-Driven Development Testing Tools Training Transitions Travel Voice of the Customer
Calendar
NetPromoter Score
No progress bars found
Recent Comments
- Kenneth van Rumste on Scrum Roles Defined
- Carlton on Scrum Roles Defined
- Kenneth van Rumste on Scrum Roles Defined
User Groups
Archives
- May 2012 (1)
- April 2012 (2)
- March 2012 (2)
- October 2011 (2)
- August 2011 (1)
- May 2011 (1)
- February 2011 (1)
- January 2011 (5)
- December 2010 (1)
- November 2010 (3)
- October 2010 (6)
- September 2010 (5)
- August 2010 (4)
- July 2010 (6)
- June 2010 (2)
- May 2010 (2)
- April 2010 (5)
- March 2010 (3)
- February 2010 (5)
- January 2010 (7)
- December 2009 (8)
- November 2009 (2)
- October 2009 (6)
- September 2009 (9)
- August 2009 (7)
- July 2009 (4)
- June 2009 (3)
- May 2009 (3)
- April 2009 (5)
- March 2009 (6)
- February 2009 (6)
- January 2009 (7)
- December 2008 (10)
- November 2008 (11)
- October 2008 (10)
- September 2008 (4)
- August 2008 (5)
- July 2008 (5)
- June 2008 (8)
- May 2008 (5)
- April 2008 (3)
