Good question, I'm glad you asked...
Actually, I asked myself during my long a** commute, which gave me a lot of time to reflect.
The weird thing about TDD is that there is no design.
You don't design tests. You write them, one at a time.
This is something that makes TDD difficult. Even after I understood the basics, it was still a challenge to stay with it. I had to stop thinking about how to solve the problem and focus only on how to test the solution.
It's not that I don't think about designs at all, but I'll only design up until the point I know I'll be able to start my first test. This design is focused on high level interactions and the goals of my solution.
When the TDD light bulb went off above my head, my thinking changed to this:
What can I do to make this test as easy as possible to write?
Thats it. Kinda lame looking at it now, but really, thats it. When I focused on testing and that alone, that's all that remained.
If you have difficulty dispelling design noise, pretend you are Harry Potter and have your very own pensieve (that would be pretty cool, no?). Put the thoughts in the pensive. They will be there when you have the focus they deserve (In real life this works well with index cards)
Unless it is a new user story, I throw it out. I don't worry about it, because if I need it, it will happen.
But what if I forget? Are my user stories satisfied? Are my acceptance tests passing? I guess I don't need it.
But I need to refactor my code! Well, I should be doing this all the time! If I didn't have a chance for whatever reason, next time I am in the test, it will be so painful, I'll refactor. I trust myself and my team. When this happens a lot, I need to think about what done means (this is another topic)
How do I make tests easier to write?
When I can't make a test without getting frustrated or overwhelmed with what-ifs or setups, I introduce a mock and encapsulate the behavior. Using that mock just made my life a whole lot easier.
Did I just drive the creation of a new interface? Is there a new interaction that didn't exist because it was the easiest thing? Will my class be more simple because its not doing something too complicated? Will the new class be cohesive because it was created for a specific purpose?
Wow, not only am I creating a new design as I go, but all other things happen because I'm trying to make my life easier.
Anyone else see the beauty here?
Or the power?
When I have a very complicated problem, I break it up organically by test driving. Each part not only makes sense, but is easier to implement because I am able to focus on small pieces. I have instant gratification that each worked on its own, as it was created, without any integration.
Sweet bonus, the solution doesn't do anything extra and I didn't go on any tangents because I didn't want to write extra tests.
Extra sweet -- I spoke to coworkers, took a lunch break, wrote a blog post and had NO fear my momentum or focus would be lost.
Writing tests is more difficult than writing code, but when I focus on making my tests as easy as possible to write, it keeps me in the test, drives my design and simplifies my thinking.
Thursday, May 31, 2007
Tuesday, May 29, 2007
Xna Feature Request
Kris is soliciting votes for an xna feature -- GameServiceContainer.GetService<T>
(i.e. Make GetService support Generics!)
Follow the link and click "vote now".
Use your MSDN/Live credentials to log in.
If you get a page not found error, you need to complete registration for Microsoft Connect -- go to the "My Participation" link in the left menu.
(i.e. Make GetService support Generics!)
Follow the link and click "vote now".
Use your MSDN/Live credentials to log in.
If you get a page not found error, you need to complete registration for Microsoft Connect -- go to the "My Participation" link in the left menu.
Monday, May 28, 2007
Pair programming, team ownership and collaboration -- Oh crap!
For me, like many others in our field, talking to people and collaborating wasn't as natural as coding and designing.
I never needed to talk out a design, it would just happen. I loved creating software and I was quite good at it. In a few short years I went from code monkey to architect and project engineer.
In all this time, I never developed a sense of team, community or sharing. I had a hard time communicating my designs; I never thought about them, I just did them. I had difficulty listening.
When I first got to Oxygen, with only pair programming, I was completely frustrated. I was use to excelling and being the hero of the team.
At pairing and communicating I, well, let's just say it didn't come so naturally.
For me, the most difficult part of pairing and code ownership is giving up what's best for you and substituting it with what is best for the team. This is a concept that is very important for the entire team's productivity and happiness.
In our world we have a lot of brilliant developers, with a lot of brilliant ideas. Our designs are more of an art than a science and with any art, it is a personal expression. This is why collaboration, sharing and pairing is so difficult -- in our minds our design is always really good.
And for each individual that is true.
But for someone else, a solution that brings you great success may bring them great frustration and pain.
What is the solution? How can we all agree? In what ways can we share our knowledge?
I'm not sure... but I think about it a lot.
While differing opinions can bring the best ideas, spending an entire pairing session (or worse days, weeks, forever) bickering about differing opinions is much worse than not bringing your ideas to the next level.
In pairing, when you have two opinions, the best option is to choose an opinion and run with it. If its not the right solution, it will be obvious right away.
However, sometimes its not a wrong decision, its just not the better solution and the pain of the decision may not be felt at that moment.
Will the frustration of the person be felt in the group? Probably not if they are sometimes heard. If your environment has a few people who are more stubborn than others, you may have some frustrated developers who need to get their way more often.
On any team, with each pair, you will eventually find a groove. How long it takes and the style of your solutions with depend on the individuals of the team. And the style you find may be completely different than what you do on your own.
Whatever gives your team the ability to keep their velocity, happiness and quality high is the best practice.
I never needed to talk out a design, it would just happen. I loved creating software and I was quite good at it. In a few short years I went from code monkey to architect and project engineer.
In all this time, I never developed a sense of team, community or sharing. I had a hard time communicating my designs; I never thought about them, I just did them. I had difficulty listening.
When I first got to Oxygen, with only pair programming, I was completely frustrated. I was use to excelling and being the hero of the team.
At pairing and communicating I, well, let's just say it didn't come so naturally.
For me, the most difficult part of pairing and code ownership is giving up what's best for you and substituting it with what is best for the team. This is a concept that is very important for the entire team's productivity and happiness.
In our world we have a lot of brilliant developers, with a lot of brilliant ideas. Our designs are more of an art than a science and with any art, it is a personal expression. This is why collaboration, sharing and pairing is so difficult -- in our minds our design is always really good.
And for each individual that is true.
But for someone else, a solution that brings you great success may bring them great frustration and pain.
What is the solution? How can we all agree? In what ways can we share our knowledge?
I'm not sure... but I think about it a lot.
While differing opinions can bring the best ideas, spending an entire pairing session (or worse days, weeks, forever) bickering about differing opinions is much worse than not bringing your ideas to the next level.
In pairing, when you have two opinions, the best option is to choose an opinion and run with it. If its not the right solution, it will be obvious right away.
However, sometimes its not a wrong decision, its just not the better solution and the pain of the decision may not be felt at that moment.
Will the frustration of the person be felt in the group? Probably not if they are sometimes heard. If your environment has a few people who are more stubborn than others, you may have some frustrated developers who need to get their way more often.
On any team, with each pair, you will eventually find a groove. How long it takes and the style of your solutions with depend on the individuals of the team. And the style you find may be completely different than what you do on your own.
Whatever gives your team the ability to keep their velocity, happiness and quality high is the best practice.
Sunday, May 27, 2007
TDD, What a bitch
Whenever I talk to someone who is interested in learning TDD I let them know that it is a very difficult concept to put into practice. It takes a lot of discipline and significant changes in the way you think and code.
Nobody mentioned this to me before I started. Everyone spoke of TDD like magic -- it changes your design, its the best thing ever, its so simple, all you need to do is write your tests before your class, you'll love it... (Ignore the man behind the curtain!)
After a few days of trying, I began to think something was very wrong. I wasn't quite the developing genius I thought...
That couldn't be true!
Like any reasonable person in my situation -- overstressed, too many responsibilities, tight deadlines, stakeholders bothering you, etc... I continued to pound my head against what seemed to be a steel wall of TDD that just wouldn't fit.
My head (now bleeding and bruised) was focused on how to solve the problem instead of how to test the solution. I didn't know it at the time, but until I changed this behavior, I would always be fighting my instincts and not gaining the benefits.
Fast forward two months and I was still, well, sucking, but not as bad. I had some test coverage, I wrote some classes test first, but I did not test drive every class, it seemed like too much work. I also didn't understand mocks, at all, and gave up on writing my own mock classes after about a day, so no interaction testing and lots of coupling.
It was very frustrating to have 1/3 of my tests fail if I was working on a common entity or if a bug showed up. Also, because I was coupling all my classes together I wasn't seeing the full benefits of test driving.
My focus was just as bad as coding before. If I needed a new behavior, I'd have to code. This meant testing the other class, which may cascade into other tests. Thinking about it, I think my focus was worse. Sometimes I could write a stub for the new behavior, but say I was creating a method that returned a boolean that had different responses that I needed to test... And there is the setup to get it into each state. And thats just a boolean assuming there's no interactions...
My thinking was in the same place it was a few months earlier. The only difference was I could write a unit test before I wrote code. But I wasn't test driving design. I had the design in my head. I was writing the unit tests for the classes and interactions I already decided I needed.
Fast forward two months: New job, new project, fresh start, woo hoo!
With this project, I was determined to understand TDD. A lot of bright people that I respected were saying great stuff and I was going to get it.
My first step was to understand nMock.
I knew using real classes in my tests was killing my focus, but I didn't yet know how much it affected my design. I read the nMock web page, explaining the api, about 500 times... "Okay," I said to myself. "You can use an interface before its implemented and verify its been called."
It sounded so simple, it read so simple, yet it made NO sense to me.
My delight in using mocks (once I figured out how to use them) was focused on several things -- I could focus on the test I was writing, my tests weren't failing because of another class and my tests were a lot simpler because I didn't need to put in knowledge about other classes to verify or assert behavior in the CUT. Implementations of interfaces used in tests didn't affect the tests anymore.
After a few weeks of nMock, what I began to notice was that my design, code, thinking, and mind was changing.
A lot.
I only made a class after it was being used as an interface in another class. That class' only public methods were in that interface. I never debugged my application. I almost never debugged my tests. My test coverage was over 90%. My design evolved through the tests.
I was test driving. Finally!
Making tests was so focused and had immediate results I was addicted. At some point, something happened in my brain and this great thing called TDD finally came in. I didn't want to write in the CUT first, because it wasn't how I was thinking. It seemed like more work.
I was in the test.
Nobody mentioned this to me before I started. Everyone spoke of TDD like magic -- it changes your design, its the best thing ever, its so simple, all you need to do is write your tests before your class, you'll love it... (Ignore the man behind the curtain!)
After a few days of trying, I began to think something was very wrong. I wasn't quite the developing genius I thought...
That couldn't be true!
Like any reasonable person in my situation -- overstressed, too many responsibilities, tight deadlines, stakeholders bothering you, etc... I continued to pound my head against what seemed to be a steel wall of TDD that just wouldn't fit.
My head (now bleeding and bruised) was focused on how to solve the problem instead of how to test the solution. I didn't know it at the time, but until I changed this behavior, I would always be fighting my instincts and not gaining the benefits.
Fast forward two months and I was still, well, sucking, but not as bad. I had some test coverage, I wrote some classes test first, but I did not test drive every class, it seemed like too much work. I also didn't understand mocks, at all, and gave up on writing my own mock classes after about a day, so no interaction testing and lots of coupling.
It was very frustrating to have 1/3 of my tests fail if I was working on a common entity or if a bug showed up. Also, because I was coupling all my classes together I wasn't seeing the full benefits of test driving.
My focus was just as bad as coding before. If I needed a new behavior, I'd have to code. This meant testing the other class, which may cascade into other tests. Thinking about it, I think my focus was worse. Sometimes I could write a stub for the new behavior, but say I was creating a method that returned a boolean that had different responses that I needed to test... And there is the setup to get it into each state. And thats just a boolean assuming there's no interactions...
My thinking was in the same place it was a few months earlier. The only difference was I could write a unit test before I wrote code. But I wasn't test driving design. I had the design in my head. I was writing the unit tests for the classes and interactions I already decided I needed.
Fast forward two months: New job, new project, fresh start, woo hoo!
With this project, I was determined to understand TDD. A lot of bright people that I respected were saying great stuff and I was going to get it.
My first step was to understand nMock.
I knew using real classes in my tests was killing my focus, but I didn't yet know how much it affected my design. I read the nMock web page, explaining the api, about 500 times... "Okay," I said to myself. "You can use an interface before its implemented and verify its been called."
It sounded so simple, it read so simple, yet it made NO sense to me.
My delight in using mocks (once I figured out how to use them) was focused on several things -- I could focus on the test I was writing, my tests weren't failing because of another class and my tests were a lot simpler because I didn't need to put in knowledge about other classes to verify or assert behavior in the CUT. Implementations of interfaces used in tests didn't affect the tests anymore.
After a few weeks of nMock, what I began to notice was that my design, code, thinking, and mind was changing.
A lot.
I only made a class after it was being used as an interface in another class. That class' only public methods were in that interface. I never debugged my application. I almost never debugged my tests. My test coverage was over 90%. My design evolved through the tests.
I was test driving. Finally!
Making tests was so focused and had immediate results I was addicted. At some point, something happened in my brain and this great thing called TDD finally came in. I didn't want to write in the CUT first, because it wasn't how I was thinking. It seemed like more work.
I was in the test.
Friday, May 18, 2007
Hot Agilista Update
Hot Agilista #2 (that's me) is in her hotel room writing a blog entry. Meanwhile Hot Agilista #1 (thats Oksana) packs her things for the journey home.
Things I learned at devteach:
PS although not documented by our paparazzi, our BoF was everyone's devteach highlight!
Things I learned at devteach:
- Oksana and I are Boffers, not Speakers
- Ayende's mind never stops. Its not surprising, but its been great to spend so much time with him here. He could probably fill a book
- Scott Bellware likes to torture people by taking them to questionable restaurants.
- JP Boodhoo is very disciplined and plays Gears of War!
- ActiveNick and I are going to have fun playing Gears of War with JP!
- Oksana rocks (I already knew that, but its still true)
- Carl Franklin is quite the musician
- Udi Dahan is surprisingly easy to talk to
- Beth Massi is very cool
- Roy Osherove is very funny.
PS although not documented by our paparazzi, our BoF was everyone's devteach highlight!
Thursday, May 17, 2007
Xbox back online
Someone mentioned today that my xbox was broken and I realized I needed to post about my gaming activity.
An update:
As of two weeks ago it was fixed and until I left for DevTeach I was spending most of my time playing Guitar Hero. What a great game!!
I was so proud of myself for getting through medium with mostly 5 stars (still have a few to go), I decided to try hard... and well, it was freakin' hard!
Much to my surprise I was able to beat several songs. My energy was high and my pride was higher.
Then it happened... Woman on Hard... WTF.
I tried to practice, but those pull offs totally kill me... and even when I get past the initial crazy part, that solo??? Really, they did that to knock you down a bit, let you know hard is hard...
When I get home, I'll return to medium until I have all 5 stars, then I'll try hard again.
An update:
As of two weeks ago it was fixed and until I left for DevTeach I was spending most of my time playing Guitar Hero. What a great game!!
I was so proud of myself for getting through medium with mostly 5 stars (still have a few to go), I decided to try hard... and well, it was freakin' hard!
Much to my surprise I was able to beat several songs. My energy was high and my pride was higher.
Then it happened... Woman on Hard... WTF.
I tried to practice, but those pull offs totally kill me... and even when I get past the initial crazy part, that solo??? Really, they did that to knock you down a bit, let you know hard is hard...
When I get home, I'll return to medium until I have all 5 stars, then I'll try hard again.
Wednesday, May 16, 2007
The Gentle Art of Pair Programming -- the Short, Short Version
Oksana and I held a birds of a feather session on Pair Programming this afternoon and after a late start, we had big turn out.
The audience was excellent and enthusiastic. Thank you for your questions and interest!
For those of you who didn't get enough of us, we'll be presenting a full tutorial at Agile 2007 in August -- more details to follow.
The audience was excellent and enthusiastic. Thank you for your questions and interest!
For those of you who didn't get enough of us, we'll be presenting a full tutorial at Agile 2007 in August -- more details to follow.
Hello from DevTeach
DevTeach is well underway in Montreal and the agile track, has been getting a great turn out. I'm really glad to see an interest in agile; I hope people take something back with them.
While the presentations are good, the best part of any conference is the conversations. DevTeach is no exception.
Session Highlights:
1. JP Boodhoo's sessions on refactoring and enterprise patterns -- JP is an enthusiastic speaker and I like his style. Longer sessions would have been great for both these classes. JP even tolerated all my questions, which takes great patience.
2. Jerry Miller's session on Rules of Agile Design -- I agree with everything he had to say (except calling them laws :P)
3. Scott Bellware's session on Behavioral Driven Development -- do we need to rethink our naming conventions again? I really enjoyed how Scott took us through the evolution of an interesting, but understandable example.
There are a few sessions I would have liked:
1. Analysis Services in Sql Server or something about MDX
2. Introduction to Inversion of Control
3. Commands and Bindings in Xaml
4. The Gentle Art of Pair Programming (the full thing!)
Oksana and I are buying Ayende, the creator of Rhino Mocks, for a beer later, so that should be fun!
While the presentations are good, the best part of any conference is the conversations. DevTeach is no exception.
Session Highlights:
1. JP Boodhoo's sessions on refactoring and enterprise patterns -- JP is an enthusiastic speaker and I like his style. Longer sessions would have been great for both these classes. JP even tolerated all my questions, which takes great patience.
2. Jerry Miller's session on Rules of Agile Design -- I agree with everything he had to say (except calling them laws :P)
3. Scott Bellware's session on Behavioral Driven Development -- do we need to rethink our naming conventions again? I really enjoyed how Scott took us through the evolution of an interesting, but understandable example.
There are a few sessions I would have liked:
1. Analysis Services in Sql Server or something about MDX
2. Introduction to Inversion of Control
3. Commands and Bindings in Xaml
4. The Gentle Art of Pair Programming (the full thing!)
Oksana and I are buying Ayende, the creator of Rhino Mocks, for a beer later, so that should be fun!
Subscribe to:
Posts (Atom)