Sunday, February 17, 2008
The folks at LosTechies invited me to join their blogging team. I'm not sure why they would want to dilute their blogging talent pool by having me, but I'm honored and I pledge to contribute to the best of my ability. This means that I'm going to have to increase my posting frequency which I've been planning on doing for awhile. Being part of the team is a nice motivator, so I hope they don't kick me off after they get to know me. ;)
If you've subscribed using my FeedBurner RSS, then you don't have to update anything. My new blog URL is http://www.lostechies.com/blogs/rhouston. Many thanks to LosTechies for having me.
Thursday, February 14, 2008
[edited: fixed some typos]
I believe Dan North was the first to use the term BDD (Behavior-Driven Development). In his post , Introducing BDD, he describes the creation of BDD as a methodology to promote good TDD and help avoid it's pitfalls. In another post, What's in a Story?, he states:
Behaviour-driven development is an “outside-in” methodology. It starts at the outside by identifying business outcomes, and then drills down into the feature set that will achieve those outcomes.
Since my last post on BDD, I've been experimenting with this methodology. One of the things I've learned is that this can be applied to high level acceptance tests and all the way down to the unit tests (should I say spec instead of test?). I think the goal is the same at any level; you define the behavior then you implement it.
In Dan's post, Goal-oriented vocabulary - saying what you mean, he talks about using
... goal-oriented vocabulary in your development process as well as your code to help maintain perspective on what you are trying to achieve.
This is very interesting to me and I think it helps me solidify BDD even more. Historically I've written tests around the tasks the objects were trying to perform in the system. I realize now that even though I was writing tests first, I wasn't really letting it drive my development. I was thinking "I need this object to do foo" instead of "I need to do foo, now how do I implement it?". More recently, I have been working to change the way I think by working "outside-in". I'm using the BDD style language as a tool to help me stay on track. One of the things that I've learned is that this takes practice and discipline. Working with a pair is really beneficial here because you can help keep each other out of the weeds.
Colin Jack raised a good question in a recent post on how detailed do you make BDD tests (ugh, I mean specs). He brings up the point that if you make the tests too detailed, you may end up testing the same things at multiple levels. I believe this is ok because the specs (yes! - not tests) are not only a tool to validate your development, but also a tool to guide it. Dan validates to me that BDD is not just a high level testing methodology by saying:
You start at the outside with an automated scenario, and work inwards, discovering services and collaborators as you go, until you’re done.
For awhile now, I've been bothered by some tests being too coupled to their implementation. I've now come to accept that if you use tests to drive your development, you will have some tests that are coupled to implementation at the low levels. I became ok with this once I decided that it's ok to throw tests away. If I'm making a change that is breaking a lot of tests, then I probably need to be writing new tests that are driving that development and deleting the ones that don't make sense anymore. Using BDD and working outside-in, I have more freedom to change implementation at different levels because I have the spec validation at the higher levels.
I'm still discovering BDD and I know that I have a ways to go before I'm confident in saying that I know what it is.
Tuesday, February 12, 2008
I've been a little slow getting around to writing this post, but this past Saturday, Chad Myers and myself hosted the first Austin TDD CodingDojo event. Chad has posted some good information and his thoughts on the event here. He seems a bit disappointed as to how it played out, but for me, I thought the dojo went well. If anything, it showed that TDD takes some practice and discipline. I think everyone at the event got some real value out of it. It would have been great if we would have gotten into a good ping pong pairing rhythm, but we didn't quite get there. We could have done better at crowd control, but hey, there were no loss of limbs and plus we wanted to see where it was going. We did get to cover a lot of ground on several different issues. Some of the things we discussed (sometimes at the same time) were:
- Getting started
- Doing some design up front
- Thinking too far ahead
- Organizing test classes
- Naming of test files, classes and methods
- Stub
- Mocks
- Different syntax styles of NUnit and Rhino Mocks
- Refactoring
- Tools like macros, ReSharper and TestDriven.NET
- Each other's experiences with TDD
- Good TDD books and articles
After doing introductions, having breaks, and saving time at the end for a retrospective, we talked about all those things (and more) in about 2 1/2 hours.
I felt that the event retrospective went well. Everyone gave good honest feedback which we will certainly apply to the next dojo. Click here for the event wiki page where you can find the retrospective notes. We now know how we want the dojo to work and we now have some really good ideas on how to organized it next time.
Thanks to all the folks that helped out and participated! I'm looking forward to the next one!
Saturday, January 12, 2008
I don't know much about BDD (Behavior-Driven Development) but I've been collecting a few clues and it sounds interesting. I always lose that newbie perspective after learning something new, so I thought it would be nice to write a series of posts that document my journey of understanding to what it's all about. Hopefully by the end I'll know what the hell is going on and will have collected enough information to help out some other folks down the road.
I thought I'd start off by googling "BDD". Several of the links were referring to a mental disorder and that made me think that I should point out that this post is not about a mental disorder (or at least I don't think it is).
I know that BDD is related to TDD, so I googled "BDD TDD" and came across a video of Dave Astels giving a talk about BDD. In the video he explains that TDD is really about design and not testing. He states that
"BDD is what you are doing already if you are doing TDD very well."
He also goes on to explain that most people aren't doing it well and that one reason could be that people are working in a distracted mind set because they are looking at it from a testing point of view instead of a design point of view. I have to say that I think in a testing mind set when I'm doing TDD, so I probably fall into that category of folks that are not doing it well. He goes on to explain that xUnit type tools influence us to think in those terms of testing. A way to free yourself up to think differently is to use tools that change the language of tests to be more focused on testing the behavior instead of testing classes. Does that mean that we're really doing the same things as TDD, but just calling it something different and looking at it from a different perspective? I don't think so (unless you're already doing TDD well). I think there is more to it than that.
I recently read Jimmy Bogard's post Converting tests to specs is a bad idea which really made some things click in my head. Jimmy says:
"BDD is much more than naming conventions and the word "should", it's more about starting with a context, then defining behavior outside of any hint of an implementation."
and
"... when writing true BDD-style specs, I don't care about the underlying class or method names. All I care about is the context and specifications, and that's it!"
After reading that, I think I'm starting to get it. I've always felt that my tests have been too close to my implementation because of the friction sometimes faced with refactoring a design. If my tests mirror my design, then I have to refactor the structure of my tests when my design changes which can be a PITA. You can solve a problem several different ways, but your test should be organized and structured according to the behavior of the system instead of a specific implementation.
I'm sure that I'll gain a better understanding of BDD as time goes on and I tend to share that information here.
Thursday, January 10, 2008
Chad Myers and I have finalized the details of the Austin TDD CodingDojo event. Please see Chad's post with the details which can be found here.
Sunday, January 06, 2008
Chad Myers approach me with the idea of hosting/facilitating a CodingDojo-style, Randori-style TDD session and I eagerly agreed to help out. We're still working out some of the details, but please see Chad's announcement here for more information. It should be a great time, so see you there!
Sunday, December 23, 2007
I'm new to BDD (at least the term) and I'm still trying to understand what's its true definition. Regardless, I'm certainly seeing the value in xBehave type testing frameworks which are used in BDD. What I like about the xBehave frameworks is that the test scenarios have a well defined structure and that test narratives can be produced that read like a book. We're considering using RBehave for our UI acceptance tests (Flex using FunFX) and NBehave for our back end acceptance tests.
I need a way to capture the test scenarios so that it can be used for both systems. I also need to do this in a way that's friendly to more people than just developers. I'm experimenting using an InfoPath form which ultimately gives me an XML file of the captured test scenarios. Once I have it in XML, I can code generate test stubs and even import the data into Rally for tracking. After I created the form, I started thinking how nice it would be if the XML could power the tests and eliminate the need for code generation. That's something I might try in the future if this plan plays out. Click here if you would like to download the InfoPath 2007 form.
Sunday, December 09, 2007
It's sometimes difficult to define the boundaries of your aggregate. What can work well for one part of the system, doesn't necessarily work well for another part. I think we all have the desire to make our models perfect, but as with most man made things, nothing is ever perfect. I want to present an case that deals with many-to-many (or two one-to-many) relationships in aggregates and where some complications can form.
Say we're building an online survey engine where administrators can create custom surveys for gathering data. Let me outline some simple rules to set the stage.
- Surveys are made up of questions.
- Many questions are predefined and have business rules which could affect other questions.
- A single question can exist on many surveys.
From these rules we can see that we have two main entities (Survey and Question). When we define our aggregates in the system, we try to look at the way the data is to be used in the system. In our case, we always edit a Question in the context of a Survey. We could create a single aggregate where you have a Survey entity (the aggregate root) which exposes a collection of Question entities. Doing it this way may seem simple, but there are complications.
When we modify a question, we could be changing more than one survey since a question can exists on multiple surveys. That would mean that we're modifying an aggregate outside of our working aggregate instance. This sounds dirty. That may not seem like a big deal since you're just changing text, but what if it was a different type of question (possibly multiple choice) that has business logic that affects other questions? You may make valid changes on one Survey that completely breaks another. You could say that a Survey is responsible for ensuring that any of its Questions are valid on any other Surveys that use those same Questions, but loading other aggregate instances seems dirty too. Plus there could be thousands of Surveys that share many of the same Questions. Loading the Questions in interest outside the context of their Surveys would also break the rules of the aggregate.
To me, this is a complication with many-to-many relationships and using a single aggregate. In cases like this, I'm thinking it's best to have two aggregates. One aggregate would have a Survey entity (the aggregate root) which exposes a collection of SurveyQuestions entities, which have QuestionIDs, but not an object reference to Question entity. The Question entity lives in it's own aggregate. Any changes to a Question that has rules that interact with other Questions on the same survey can be free to load those Questions to apply validation.
Having multiple aggregates is an inconvenience for client code since it really deals with surveys as a whole, but I believe you can overcome that by creating an abstraction around both of these aggregates that allows you to deal with them as a single model. I would be interested in hearing how other folks are dealing with these sorts of complications.
Technorati Tags:
DDD,
Aggregates
Chad has two great posts back to back that are related to professionalism in software development:
Programming is a Noble Profession, Be Proud, Be Strong
Automated Testing is an Ethical Matter, IMHO
Nice job Chad.
Monday, December 03, 2007
I don't know the entire history of how ALT.NET came to be and I'm not sure that it really matters. I was scheduled to go to the conference in Austin, but had a family function that I had to attend that same weekend so I didn't make it. I didn't get on the altnetconf list until late Oct (I think) so for myself, I missed a lot of the discussions. I wasn't in the thick of it all, but I believe that has given me a bit of perspective of how ALT.NET is perceived by everyone else.
First let me say that I consider myself ALT.NET and think that it's great. It's wonderful to have a place to kick ideas around with other people using the non main stream tools and ideas. On the list there has been discussions about what ALT.NET should strive to be. There's even a mission statement (or whatever it's called):
We are a self-organizing, ad-hoc community of developers bound by a desire to improve ourselves, challenge assumptions, and help each other pursue excellence in the practice of software development. Our movement is new. The conversation just started. All are welcome to shape and form the dialog in blogs and lists and face-to-face gatherings both local and global.
I think it's a good statement. It's goals mimic my own and the statement is open and inviting to anyone who wants to participate.
Despite that statement, ALT.NET seems to be carrying around some negative baggage which I don't fully know the origin, but I want it to stop. I like ALT.NET and I think that it adds real value to the community. I don't want it to be labeled as a gang of negative software development rebels that have no respect for anyone that is not ALT.NET. That would be anti-ALT.NET wouldn't it?
Rob Conery had a recent post which describes the ALT.NET community as the "Cool Kids" which I took to mean a shelf-glorified clique. There are some egos in the ALT.NET community, but there are egos in any group. I actually found Rob's post very entertaining (I've never been cool, so being a called a cool kid sounds kind of neat). In the post, Rob is speaking out against the negativity coming out of the group which I can relate. Some of the more vocal members of the ALT.NET community have spoken out against some of the mainstream views put in place by Microsoft. I don't have a problem with this. Others have spoken out in ways which are considered insulting which I certainly don't agree with. I want to point out that the actions and comments of a few individuals don't reflect the whole community. I'm more interested in having discussions which solve problems as I'm sure many others feel the same.
Don't get me wrong, if you disagree with something, speak up. Just do it in a proactive manner. If you consider yourself a leader in the community, then you have a responsibility to act like a leader. If you want people to listen to you, you will have to communicate in a manner that doesn't create a flame war. If ALT.NET is to have a voice and an impact, we need to preserve it's credibility.
Technorati Tags:
ALT.NET,
.NET