On July 25th Dr. Randy Pausch PhD, lost the fight against the Pancreatic Cancer. The brilliant mind behind "The Last Lecture" was 47 years old. Before leaving Randy left an amazing legacy on the "Last Lecture".

The "Last Lecture" has even more hits than the all time famous "Stay foolish, stay young" talk given by Steve Jobs at Stanford university. The talk is about achieving your childhood dreams, about how to live your life in order to always have fun.

The talk began with "What would you say if you knew you were going to die and had a chance to sum up everything that was most important to you?" and after that all his wisdom got revealed.

I knew his lecture since it was recommended on the Wired magazine that I love, those sitting around saw me almost crying while I was watching it. It’s a lesson learnt by one of the most gifted people I ever seen.

Besides all the fashion and post-mortem merchandising that will appear now that he is gone, I sincerely recommend you to go to YouTube.com and watch the video.  Also the Carnegie Mellon Univesity set up a memorial page for Dr. Pausch and a great article about his legacy.

I’ve shared it couple of months ago on our internal distribution lists, but now I’m doing it publicly so everyone can learn something from one of the greatest minds of the 21st Century.

thanks,
~johnny

Almost form the beginning of my blog,  I started writing about Test-Driven-Development [1] [2] [3] [4] [5] that now was renamed by the Agile Gang  as Behavior Driven Design. That new name is kind of cool and fancy (Oh these agilists always looking for new adepts) but there’s a truth and a strong rationale behind what they call BBD.

I wrote this post after a long time practicing TDD, this Truths and Myths are based on my personal experience and the knowledge acquired with time. You might disagree with some, you will love others, but this post is an exercise for my self trying to dump all what I’ve learnt in these years practicing TDD.

I’ve divided the post in three parts:

  • Myths. These are the things I heard while working as consultant, stuff that showed up while discussing with colleges or things that came up while discussing with friends.
  • Truths. These are almost the same as above but mostly positive things that demonstrate that there’s value on applying this practice.
  • My TDD Zen Garden. This are tips and tools that I used while doing TDD, they’re not mandatory or maybe part of the official practice. There I’m just sharing my personal tips and thoughts.

5 Myths about TDD/BDD

Myth 1: “Tests are for testers”

That’s my favorite one, when people don’t understand TDD or are just too lazy to write the tests they claim for the “Test is for testers”. Although the name has the word test, it doesn’t necessarily means that your testing as a tester would do it.

Myth 2: “Oh buddy, if I wrote them it’ll take me twice”

Ok some people think about writing the tests first as some kind of time consuming, useless, non-sense activity. Those that think like that are often the ones that never thought or read about Re-work  there are some great papers from Watts Humphrey and CMU-SEI Crew about this. If you had the tests to validate and verify your work, you’re one step closer to avoid rework.

Myth 3: “I’m bug free , I had 100% Code Coverage”

This might be controversial,  but after doing some deep thinking on this and listening to Scott Hanselman podcasts, I realized that 100% Code Coverage isn’t the best. Code Coverage is a negative metric, it’s about where we should focus are testing intentions based on what we’ve left uncover. As far as I researched, there’s no tool to measure code coverage by paths (this can be fairly accomplished by hand). So 100% isn’t bug free.

Myth 4: “If I apply incremental design techniques based on TDD, I end up just with a huge test method”

That’s more than a Myth, that’s a mistake, when doing TDD it’s always a matter of starting to cross tests from the lists. People often think that as the method to be tested evolves the original test evolves with it. Well, for me it’s that as you move forward you add new tests. So your fixture becomes a living, and breathing component documentation.

Myth 5: “Doing TDD covers our team from doing functional testing”

That’s something that I heard too much, in this case the Myth or assumption is not about people using it wrong, this is about misunderstanding its power. TDD as I titled this post is about letting the design to emerge by expression on a bunch of lines of code our intention for that component. Also the testability for components (the new buzz word) will help us to understand coupling (WARNING! this also might led you to over engineering).

5 Truths about TDD/BDD

Truth 1: “The TDD motivation is about writing clean code that works”

By writing the code needed just to make the test passes you are ensuring that your code fulfils just the test requirements and also that there isn’t dead code, unwanted code or other sort of code horrors.

Truth 2: “TDD outcome is a living breathing documentation for the component”

That’s one of my favorites things about Test Driven Development while you’re writing the tests your expressing the rationale behind those lines and more than that the intended use. When a new developer arrives to a project, if you can hand out a couple of fixtures for him to look at, you’ll probably get him up on speed faster than it would take if he just have to read the code.

Truth 3: “By applying TDD you end up with well factored code”

Some people think about all the decoupling stuff associated to TDD as some kind of black art or magic. Truth to be told, this principle applies painless and it’s harder to realize that you’re doing it than doing it. While you are expressing the intention and how the object should be have you’re defining almost ad-hoc what it shouldn’t do. Writing tests is determining responsibilities for components and when you define those, you’re already decoupling your objects.

Truth 4: “Doing TDD increases the motivation”

While setting micro-goals to yourself and accomplishing them you start to fell better, think of it as 3 years projects, with thousands of man hours to be invested. How do you get the fell of moving forward and don’t fall on the depression of writing code that is going nowhere. Well by simply setting a test for your code, you start to fell confident about what you’re doing and that gets you the feeling of progress as the green lights for your test cases are on.

Truth 5: “There’s no silver bullet”

This might be the most discouraging truth I’d ever written but the true doesn’t hurt. You may get all the benefits of doing TDD but you still need peer reviews, code reviews, analyze your code against formal computer science metrics of complexity and coupling, and all that stuff. I felt like you maybe be feeling when I read the same title on the Mythical Man Month, I thought about that book about the great software engineering problem solver but Mr. Brooks Jr. was pretty clear and I’m agree, there’s no silver bullet and TDD is just another great practice to use in the fight against the bug count and defect ratio.

My TDD Zen Garden

These ten tips are what I call my TDD Zen Garden, they consist in 10 things that use, think about or realized while practicing TDD for about +4 years. As I said on my last Truth (”there’s no silver bullet”) these are just practices, and I encourage you to challenge them, try to defeat and destroy them, because at that point you’ll have something to teach the rest of the world or just me, and that idea fight is really enriching.

Tip 1: “Write tiny and focused test methods that check only one aspect of your code”

If you method can’t be tested with 2 or 3 assertions, that’s code smells. The rationale behind this is to write method with less responsibilities and generate a well factored code.  A single method might take 2 or 3 test cases to test the alternative paths but a well written method will just need one to test it’s core functionality.

Tip 2: “Avoid fragile assertions on human readable text such as error or flash messages”

Try to write your tests (and your code) in order that it can be checked without doing strange things, like converting case or stuff like that. Tests are used to verify and validate that the code does what it needs to do. Think of it as an equation, don’t try to test things that might become messy.

Tip 3: “Use Code Coverage Tools”

Although all the things I said about Code Coverage percentage being a negative metric, it’s useful to know what aren’t you testing. Some people might think that when you find a line that isn’t tested what you should do is to write a test that passes over that line. My approach is a little bit different, if I find something that isn’t covered I just go and delete it. If that was something that I really need it will appear again when the time is right.

Tip 4: “Keep the test logic inside the test method”

As we discussed previously on this post, test are living and breathing documentation for the component. Do not try to refractor it in order to reuse, test methods aren’t intended to be productive code, they’re documentation and development support. Do no save space or try to reduce its numbers of lines, keep it tight, make it atomic and reduce its dependencies. That will make it more readable for people.

Tip 5: “Use mocking frameworks”

This is because mocks (pieces of code used to simulate another component) are just for testing proposes. People often fall in writing huge mocks, that often do too much and even worse they end up testing them.

Mock Frameworks, are useful because all the interaction logic stills inside the test method and as I said before the more information you give inside the test case the better. I clearly don’t have any favorite one, but MoQ and Rhino Mocks are two that I often use and mostly recommend.

Tip 6: “Don’t rely on context data for your tests results”

I often heard that some test are failing because of data that needs to be on the database isn’t there. I prefer to do the insertion and deletion and everything that needs to be done on the test method I don’t rely on existing data because that will you to a fragile assertion (See tip #2 for more info).

Tip 7: “Use Transactions instead of Tests Databases”

People often create bunches of databases to test against, I personally prefer to wrap my whole test inside a transaction. That let’s me play around without screwing up the database and even better I don’t fall on relying on Context Data for my tests. (See tip#6 for more info).

[TestMethod]
public void MyTestMethod()
{
    using(TransactionScope ts = new TransactionScope())
    {
        //write all the test logic here.
    }
}

When the using scope finishes, it will automatically rollback the transaction.

Tip 8: “Make your test cases atomic”

Do not rely on other tests to be running in order to write your test, do not make any tests dependant to other. Write you tests as if they were intended to run on isolation. This will help you troubleshoot a problem when some test fails.

Tip 9: “Do not hesitate on long tests names”

I’ll continue insisting that test are living and breathing documentation of the project, so avoid naming your tests as ShouldThrowException or something that doesn’t provide an insight of what’s going on to the reader.

[TestMethod]
public void ShouldThrowExceptionWhenInvalidCustomerNameIsPassed()
{
}

The name depicted above is an example on how I like tests method to be named.

Tip 10: “Be consistent, methodical, and patient”

It happens event to the best developers and TDD practitioners that at some point of time they go nuts and think about throwing all the fixtures and crack code as fast as they can in order to see their new creation moving. Be patient, consistent and methodical, follow always the process. Software isn’t just built and thrown away, people will have to maintain your baby so please be considered and be thoughtful and polite when your self because at some point (even the best developer) you will have to troubleshoot your code.

thanks,

~johnny

During Tech Ed 08’ I’ve chance to attend the Dynamic Languages - Births of the Feather session, I’m a big C# and I thought at that point that nothing can make me change C#, because it’s elegant, has language features that I love (interfaces and attributes) but I figured out that is something else under the sun.

Compiled languages has been working for a while, but as every compiled piece it’s targeted to run on a specific platform, there were some intents to get the applications to be built to an intermediate language to allow portability at some point in time. People may often think that this came for free, nobody could be faster than our beloved C/C++, but in terms of tradeoffs if you guarantee me portability I’ll definitely buy in.  Doing a quick recap over these ideas, is there anything wrong with this? Why I’m looking at DLR or dynamic stuff that was out there for a while? Let’s consider PHP which is the most leveraged language in terms of web applications. Why now?

I see static compiled languages as an assumption that your world is static, your business problems can be classified and everything is already defined. Software + Services, DSL and other new trends are claiming for flexibility, customization and extension. This means that static world was nice for a while and might be useful in tons of cases but now it’s time to talk about our new old friends the dynamic languages.

What’s a dynamic language?

Dynamic language is a term used to describe a class of high level programming languages that execute at runtime many common behaviors that other languages might perform during compilation, if at all. These behaviors could include extension of the program, by adding new code, by extending objects and definitions, or by modifying the type system, all during program execution. These behaviors can be emulated in nearly any language of sufficient complexity, but dynamic languages provide direct tools to make use of them.

Why dynamic languages?

That’s a complicated political question, as I introduced this post, my personal opinion is that world is moving fast, people need software, developers need to be productive and software needs to be prepared for runtime changing, and mutation. Some computer science orthodox, friend of C++ or C# fan might be thinking about it as “you young padwan just want to crack code and get ready to enjoy your star trek episode”. That’s is fairly true,  but there’s true in something like “I want to write code that runs on my mac, can be developed on Windows using my Visual Studio and hosted on openSuse” , seems as an ambitious desire, but it’s how the world is behaving right now.

Will this be the end of C# and our beloved friend C++?, absolutely not I think that this is a top level mind change, we need C# as much as we need C++ and static languages for some aspects of our product that won’t mutate over time. We want dynamic languages to be the top of the stack, write the business logic, UI and process that might change, where its involved pieces might mutate.

We (developers) want to ship software fast, we want to be ready for changes, but we won’t forsake our lessons learnt as TDD. So the answer might be let’s getting started with something that evolves as your product evolves, and have a coding fun.

What’s the DLR and why I love it?

From the beginning, Microsoft’s .NET framework was designed to support a broad range of different programming languages on a Common Language Runtime (CLR).  The CLR provides shared services to these languages ranging from a world-class Garbage Collector and JIT to a sandboxed security model to tools integration for debugging and profiling.  Sharing these features has two huge benefits for languages on the CLR.  First, it’s easier to implement a language because lots of difficult engineering work is already done for you.  Second, and more importantly, these languages can seamlessly work together and share libraries and frameworks so that each language can build on the work of the others.

DLR (Dynamic Language Runtime) is layer over the CLR that let dynamic languages share the robust platform under hood for .Net Languages from dynamic lanaguages (like Iron Python, Iron Ruby,  Managed Javascript) that will let the developers to have a world class execution environment without leaving the CLR.

clip_image002

Is this it? Not really, DLR also is for dynamic languages what CLR is for static compiled ones, it’s a platform that can be leveraged to write your own language.

Why I love the DLR? It’s an easy question; DLR let me use dynamic languages with runtime language services of the world-class static language. In this way I can get my code fast and productively written on a dynamic language but running with the shields and lessons learnt used for static languages.

Why  IronRuby?

  • IronRuby is ruby for .net. I love ruby :)
  • Ruby syntax is one of the most productive, human readable syntax I’ve ever seen.
  • Has an almost 100% compatibility with C-Pure Ruby implementation (used in Mac, Linux and windows too).
  • Tool set, allows me to do all the stuff I learnt like TDD.

Conclusions

Dynamic Languages are back or never left, but my point is that we like them and since we have capabilities like the one provided by the CLR, we are now ready to start writing some dynamic language based application. I love it, but it’s not always one size fits all, I think we still need to think if our app is the case for a dynamic language.

Stay tuned, I’ll be posting more on this, like: TDD and IronRuby, using rake, consuming .net assemblies from it and much more.

thanks,
~johnny