I just started working on a new project. As you know, I got agile religion earlier this month, and I am a born-again coder, who wants to test his code as he goes. Also, after doing a few TDD projects, not doing it seems wrong, and it is just not as fun.
So I got a new .Net project, and this time I actually can do it right. I am going to do it right. I set up Moq and NUnit, and off I go to test land. Now All what I have to figure out is how to mock HttpRequest to test an upload method. I research the question. And in most cases, most of the solutions involved Asp.net mvc. I kept trying to find something specific to just plain asp.net, but the information that I got was either very old, or was a tangential mention that in an mvc page about how the solution could also work with regular asp.net pages.
So the pragmatic solution was to move the back end of the project to mvc. Fortunately for me the project only has a couple of pages of code, and translating the behavior from asp.net to mvc was quick. In fact, it seems that it takes a lot less work code to do the same work.
I am not saying that it is not possible to TDD regular asp.net. I am sure it is. But most of the information and resources exist for asp.net mvc, so, if it is possible, it makes a lot more sense to adopt it if one wants to TDD a asp.net project.
A while ago I said that I may come back and enter detail instructions on how to install simple test on drupal 6 on Windows. I forgot about it, and, of course, I need that information now. So here it is, in its detailed glory, how to do this.
1. Download simple test from this link http://drupal.org/project/simpletest
2. Make sure that you have curl installed. Check whether curl has been installed by looking at your phpinfo() page, or running on the command line php -i . If you don't have it installed, install it. On windows, that means going to your php.ini, and uncommenting the line where it says php_curl.dll and potentially moving php_curl.dll to Windows/system32 More information on this link http://www.php.net/manual/en/curl.installation.php read the 28-Dec-2009 07:17 comment by wixelbomb for more details on it.
3. Run the patch on drupal 6 core. Oh, boy, was this fun 2 months ago.
First, information on applying the patch is given here http://drupal.org/patch/apply If you are using windows, that means that the utility that you need must be run in cygwin http://www.cygwin.com/ or you need http://unxutils.sourceforge.net/ . That is actually not that bad. More information specific to windows on http://drupal.org/node/60179
What ended up being hard to figure out where you should run the patch. The answer to this, for simpletest, is your root drupal directory. Since I don't like to type too much, I copied and pasted D6-core-simpletest.patch to root, and ran the following command in cygwin
patch -p0 < D6-core-simpletest.patch
That should be it. Then you can have fun testing.
Looking back at this, I realize now that I didn't fully understand how unit testing is supposed to work. My idea was that you test every function. To be honest, I actually still like my idea a lot, and judging by many of the unit test flame wars threads on different online forums, it seems that a lot of people feel the same way.
I believe that the crux of the problem stems from the principal that says thou shall not test private methods. The catechism answer for why is simple: that code gets tested when you test the public methods. Then the test private method camp asks what is the point of testing in the first place if you are not going to test what are potentially key functions. And most of the orthodox priests will repeat that private methods will be tested with the public methods.
So many pragmatic people just make their private methods public. Some keep it like that. Some turn them back to private before releasing the code.
Yet I remember having an insight during one of my unit test periods in that if you really need to test a set of private methods because they are very important, maybe they should belong to their own class --- ---- (the empty space represents the state of enlightenment that cannot be expressed with words.)
So there was a reason why testing should only happen to public units! If you feel compel to test some key private methods, it is because they probably belong on their own object. The principle helps us with the design!
Now, I thank my orthodox priest sensei for granting me that moment of enlightenment. After all, it feels very good; it makes me feel like I am smarter; and it gives me a moment where I feel connected with the full universe.
On the other hand, my sensei could have told me that to begin with, I would have seen the wisdom of it right away, and would have adopted the practice a lot sooner. Jerk. But then, maybe those monks are full of cattle waste and are just repeating some mantra that everyone learned somewhere else. What makes them think that they can go around doing that when they don't know what they are talking about?
On the other hand, being full of shit and a zen master is very Zen in itself. Oh, wait a minute, I think it is coming, oh... --- ----
I finally got the environment ready to be able to do Test Driven Development in Drupal.
Some quick thoughts:
1. Acquia stack is great to quickly setup a drupal environment. If you want to set up testing, then it sucks big time. Why? Because of what,, ironically, makes Acquia so cool: it has its own environment for drupal not connected with the rest of your computer. Cool because if you are working on windows, you only run the services when you need them. It sucks because when one attempts to run test on the command line or to use drush, it is impossible.
2. It makes programming feel like playing a strategy game. Big win here.
3. Amazing how many times it saves you from what would be very hard to track errors.
4. Running tests on the web interface is sloooooooow. I figured a way to use the time, which is to write the next tests, but I do feel that this is breaking the proper flow.
5. TTD is flow inducing, even with the problems in 4.
Today I grabbed another low hanging fruit. This time it is Selenium. I had played with Selenium recorder a long time ago; I got to use Selenium recently, in a previous iteration of the current project that I am working on. At the time though, I was using Selenium mainly as a way to quickly populate a form before I actually tested it.
Even using Selenium IDE in this manner, just too quickly populate a form for manual testing, it is a huge time saver. Rather than testing every 10 minutes, one can test every couple of minutes.
But today I started moving towards using it for actual testing.
There are some issues that slow down quick adoption of the tool though.
Selenium IDE is quirky in my opinion. It doesn't behave the way I expected it to behave. I expect that the test, after I record it, will be saved. Instead, I have to manually save each case. Also, it would be nice if one could easily move the order of the tests around in a test suite. I found myself in the last few days having to create new suites just to switch the order.
And there is a conceptual switch that has to happen as well. It was only in the last few days that I realized that if the task cannot be completed, that is a test failure, not the equivalent of compilation error.
But even with these small limitations, and using it in this limited capacity, Selenium has already saved me a lot of time, and helped to bring my current project to successfully meet a very tight deadline. It has also been helpful in debugging a hard to find error, and helped to speed up integrating the system on the deployment site.
So you are going to hear a lot more about Selenium here in the near future.
I noticed today that my statement about why I had to adopt best practices was very similar in emotional content to this famous moment in American cinema. Please hum the theme music as you read the text:

"As God is my witness, as God is my witness they're not going to lick me. I'm going to live through this and when it's all over, I'll never let a project become a death march again. No, nor any of my folk. If I have to lie, steal, cheat or kill. As God is my witness, I'll never let a project become a death march again..."
That is what she said. Or something very similar, I don't recall correctly.
In any case, today I aggressively used redmine, the open source project management software, to track every activity that I am doing for my current project. This is part of my efforts not to let my current project become a death march.
Redmine was introduced to me by @GeoDAWG. He set it up for the project that I am using and for the another project. If we had actually kept using redmine in the other project, we would have saved ourselves from a lot of grief.
Strengthening a practice that already exists is low hanging fruit, so I am going to go for it.
What has changed right now is that now I have the strong motivation to keep it up to date. So that is what I did today: I updated tickets, wrote new tickets, and added more items and reorganized the wiki for the project.
Before I thought updating tickets was boring; now I think it is boring, but critical.