The (Some) Fallacies of Test First Development


Written on November 5, 2009 – 7:06 pm | by admin

I should first clarify that I would never come out against the idea of writing tests for your code. I find testing to be a wonderful way to aid refactoring, fight regression, and build developmental confidence in a piece of software. Lately I have tried to provide significant test coverage for projects I work on. My problem is with buzz word fanatics, suits, zealous developers, and tangentially related technical staff who question myself or my team in our decision to not require test first methods as part of our normal development procedure.

Fallacy #1: Test first development is proper unit testing.

Unit testing serves two primary purposes. It allows you to have a fast and efficient way to verify that code you have written is working properly and it provides a mechanism to guard against regression. Bugs that are found are easier to keep fixed and business requirements are easier to maintain as a project ages and grows. There is nothing in either of these purposes that dictate when a test should be written. If anything writing tests after you have your implementation in place fits just as well if not better with these two goals.

Fallacy #2: Test first development will improve your work flow and make it easier for you to focus on the task at hand, providing you with a more efficient and effective coding session.

I tend to write my code more like Bob Ross will paint a portrait. I know what I want to end up with and I have a palette of the tools I need to get there. I would love to say that I always have a proof of concept and that write-one-to-throw-away is the only way to go but the reality of deadlines and business requirements means that this is not always possible. When I sit down to code I am not sure that method 'a' is going to return 'x' and method 'b' is going to return 'y'. All I know is that I have a large module that needs to do something and I have an idea how to get it there. In order to get there I need to put some code on the page and work with it and modern languages afford me that luxury. We are long past the era of punch cards and 2 am university time shares with one chance to get your code correct. Writing unit tests at this point is potentially a waste of time because I have not yet decided how all of the units fit together. You can argue that I should know these items or that I should use my tests to figure it out before I start coding but I write software because I enjoy it and the act of development is a creative and evolving process. Testing first has shown itself (to me) to be detrimental to this part of the process. For me it causes hyper focus on trivial components and interrupts my thought process when an implementation change causes major test refactoring. Test first also causes me to write tests for features that do not make it in to the final implementation because I thought I might need them when I started. I can see where forcing test first may help inexperienced or junior level developers but I do not think it should be considered a process requirement. In the end a good, experienced coder should decide what works best for them. In this case I choose general regression focused testing over test first development.

Fallacy #3: You should always shoot for 100% code coverage and this is a good reason to test first because you won't write any untested code.

We should be smarter than this. A good developer should be able to decide which areas of the code are likely to be fragile and what should be heavily tested. In fact, by definition, 100% coverage does not actually mean what it seems to imply. 100% coverage only means that a test suite encounters every line of code in your application. It should be obvious that this is a pretty useless metric. If an editor reads every line of a novel does that mean that the editor made sure all of the i's were dotted? So what we really want is 100% functionality coverage and this means that you are at the mercy of how far ahead of the process you can think, how many edge cases you can imagine and what bugs you have seen in the past. Unless you are willing to spend a considerable amount of time dreaming up things to test you will not likely be anywhere near 100% of "useful" coverage. I'd further argue that striving for 100% coverage (by its definition) is a waste of time. I find that the 100% coverage mentality tends to lead to insignificant and even useless tests so using it as an argument for test first development is tenuous at best.

Fallacy #4: If you are having a hard time writing tests first than you are not doing it right.

I am not going to even justify this overtly arrogant statement with an extended argument. The fact of the matter is that the "right" way to do test first may not work with a person's development flow, style, or approach to coding. If their personal approach to writing code provides solid and relatively error free code with a useful test suite than who are you to tell them they are doing it wrong?

The bottom line is that "when the tests get written" is a matter of personal preference. An intelligent and experienced coder should decide for himself what works for the given requirements. At no point should a business requirement dictate that all programmers write their tests first. Sometimes I write my tests first and sometimes I write them last, I do not suffer from delusions of grandeur but I am a good programmer and the answer to "when do I write my tests?" does not change that. So write your tests first, second, third or parallel if that works for you and stop giving me the gas face every time I state that I do not always do things your way.

MIT + Please Contribute License


Written on October 21, 2009 – 10:30 pm | by admin

We all love open source. Most of the tools I use and platforms I develop on are part of some open source initiative. With that said I think that many people are missing the point and coming to the table with unreasonable and sometimes arrogant expectations of OS maintainers.

Last week I was lurking in irc in a channel devoted to a project that one of my business partners maintains. A new user popped in to ask a question about whether or not a certain feature was going to be included. My friend responded that it was very low on his list of priorities and that he was going to try to add that specific feature in a future release but that it was unlikely to happen soon. This leech replied with a snide remark ending with a statement along the lines of "I guess your project is low on my list of priorities then". What did he expect? My friend should drop everything to implement this feature that he doesn't need just because someone asked for it? This person is missing the point. OS projects start out because someone has an itch to scratch. They release it when they think it may scratch someone else's itch and they allow others to contribute so that the project can grow to fit the needs of others. The bottom line is that anyone who shows up complaining arrogantly that an OS project is not adding a specific feature is way out of line and in my opinion doesn't deserve the rights to use the project in the first place.

It is for this reason that I submit a new licensing modifier. You would apply this to whatever your standard OS license is but you would append the "Please Contribute" clause. This would state that the cost of unlimited use and redistribution of the source is that you have to do something to help the project grow. This could include but not be limited to blogging about it, submitting a patch or a well documented bug report or helping others learn about the project. All of these things can be demonstrated or documented and advertising this licensing style may help people understand that a consumer of an OS library is not a 'client' of the maintainer. If you think the project is cool enough to be used in your application or work environment but think it is missing features than you should contribute.

(( you.goya && you.contribute) || you.stfu) == true).

Tags:

Testing your Google API connectors in development


Written on October 19, 2009 – 1:49 am | by admin

I often find myself needing to interface with google and their suite of applications. It may be obvious but I thought I would share my method of configuring my environment so I can actually connect to the google servers with the same api key that I use on production. First you need to make sure you use a wildcarded domain when setting up your key. Do not put a www before your domain name (http://yourdomain.etl). The next thing you need to do is make changes to your hosts file to point something like development.yourdomain.etl to your local machine. It should look something like this

127.0.0.1 localhost local.yourdomain.com

On a linux or MacOs Machine you will find this fine located under /etc/hosts and on windows its easiest to just search for it but it should be in /windows/system. Now when you go to local.yourdomain.etl in your browser it will point to your local machine and your google api keys will work while in development. If you are working with rails or some other framework that runs your server on a particular port than you can just append the port to the domain just as you would append it to an ip address.

Tags:

Thoughts on deploying ruby apps without capistrano


Written on October 4, 2009 – 4:03 am | by admin

I recently left the ruby deployment team for  large managed rails-based hosting provider. We used capistrano for our deployment needs. Once we had successfully configured an application and its dependencies we would hand over a very robust capistrano recipe to the end user and it turns out that almost all of our clients, regardless of skill level, tended to stick with the scripts we provided to manage their deployments. I mention this because I want to state that I think capistrano and solutions like it (Vlad deployment recipes etc..) are wonderful tools, they serve a very necessary purpose and I'd be hard pressed to argue against their value. With that said I can now say that I have not used capistrano or any other cap-like solution for any of my personal deployment needs  for a long time and I find that my deployments are simpler, faster and much less error prone than ever.

I wanted to subtitle this article "Why I removed my training wheels" but I thought better of mocking something that is really a very cool ruby tool written by folks that I really respect.  We often try to mold our framework or language of choice around our needs by writing domain specific languages and awkward helper methods to bridge disparate technologies. I've heard many people say things like "Why wouldn't you want to write everything in language x instead of languages y and z". This is more common than ever with the elegance that ruby brings to the table but I think it causes unnecessary abstraction and over reliance on a single platform.

And when it comes down to administration of a production application, how many hands do you really want in your cookie jar? Seriously, how many of the developers on your team can handle a proper production deployment and have the necessary skills that would be needed to recover from a deployment that goes horribly wrong? The person responsible for your deployments should be ready to jump in to your production box and fend off any gremlins that may have crept up during late night mogwai feedings. This person should have no real need for capistrano as they should have an open connection to the deployment location during the deployment for the sake of immediate response to disaster and active monitoring of your recent changes. If you are already connected to the server, why would you have a need to run tasks from your development environment to remotely effect your production application?  Taking this argument one step further I would say that providing a repository resident recipe that can potentially allow any of your developers to easily deploy new source code is at best a bad idea and at worst a security risk. Maybe you are on one of the few teams that use key based authentication and leave your recipe out of the source tree but a deployment method that requires you to run server resident scripts is much easier to secure and to ensure that only the proper people have access.

I realize that the reality of the matter is that most ruby teams are still very small and most of the early adopters have had no choice but to become savvy at the command line and in the nuances of deployment but as our community grows I am meeting more and more people with little or no experience in the types of skills needed to manage deployments ( I was once one of them). Teams made up of these folks will certainly want to start out with tools like capistrano but I feel that any project manager has a responsibility to bring a system administrator or deployment expert onto the team before it is too late or hire a company like my former employer to manage their hosting and administrative tasks for them.

This could easily become a longer post and I think I will revisit this topic very soon. In the mean time I will discuss my current deployment methods of choice.

Instead of spending a half hour configuring a new capistrano recipe I find that it is much more useful and flexible to create server resident bash functions that provide the necessary functionality.  Of course I will reuse previous scripts to speed up the process of bootstrapping a new enviornment but a typical solution would be a bash function called deploy that has in the best case scenario three lines in it.

  1. Check out the latest revision from the source repository to a local cache
  2. rsync this revision to the current application directory
  3. symlink any shared assets and configurations
  4. restart your mongrels/thins/passenger

Of course you may make the argument that this solution is not very scaleable across many application servers but it is simple enough to add the necessary lines to initiate deployments across many app servers. One option is a function  that will execute the deploy function on each remote server from any of servers in the environment ( ssh user@hostname "deploy" )  This is really what capistrano does anyways, the difference is that none of code that capistrano runs is actually resident on your server and there are some limitations to what can be done remotely.

Also note that while very few, if any,  of the applications we write in the ruby world will ever  be run on windows based servers there is a growing community of  Windows based developers out there who have to overcome the hurdles of getting capistrano or other remote administration tools to play nice on their development machines.  Server resident recipes whether they are in Bash, Ruby or a dsl like Capistrano eliminate the need for a cross platform tool assuming you are not worried about Windows server hosting and if you are then you have bigger problems then efficient ruby deployments. The bottom line is that server based solutions will scale better across a large development team, in my experience they run much faster and they put you where you need to be during a deployment, On the server, in the trenches, waiting for the  fit to hit the shan.

I'm hoping to detail the deployment process that I currently use (perfected in the trenches by my good friend Wayne Seguin) soon.

Tags: , , ,

What nginx + passenger means to the rails framework


Written on April 29, 2009 – 6:50 pm | by admin

I work for <insert large managed hosting provider specializing in rails deployment here> and I had the good fortune of getting to play with nginx + passenger before its recent release. This gave me some time to think about how completely it integrates into my deployment stack many weeks before it was publicly released. I've also been doing a lot of theorizing about what it means for the ruby development frameworks.

The release of Apache Passenger was met with tepid response  amongst  colleagues at my aforementioned employer. This was because of the dependence on Apache which we do not support nor care to include in our stack. What this meant is that hosting companies, many of whom are dropping the ball and being slow to respond to this technology are now able to provide easy to maintain rails/rack/merb (I know, all really the same thing now)  solutions for shared hosting platforms.  The fact that many of them are not yet using passenger is mind boggling to me but that is a rant for another post.

So for almost a year, large hosting companies with entrenched Apache solutions had the opportunity to take over a good portion of the rails hosting revenues currently being paid to managed or self managed rails friendly hosts with  solid rails stacks built on nginx. With how many calls and emails I get every week from people looking for solid Rails devs I feel that this has to be a significant figure. The good news for companies like my employer is that most hosts seemed to have missed out on this opportunity. Nginx + Passenger has arrived and I think that this is big news.

What this means for the future of rails is that as other hosts come around and start providing passenger as part of their Apache install we will see more LAMP, Java and other platform developers willing to give rails a test spin. This means that the ruby community is going to grow via the rails community, the talented codemonkeys on the other side of the fence are going to start moving over some of the ideas that have grown out of their pain and we should see a continued and steady growth and innovation in our corner of the industry.  It also means that the current rails expert companies have time to maintain their status as premium rails hosts by adapting to passenger and properly integrating it in to their stack before there is major competition from other hosts. So the companies that drive ruby development are going to continue to do so. The companies that don't have rails experience have no excuse to not get in to the game now.  Your major rails clients will eventually outgrow you and come to us but you have no reason not to give them an inexpensive platform to start on.

This future works in  favor of all involved. It allows startups to leverage ruby for their needs and find inexpensive "point and click" hosting providers for their incubation periods. It allows major Apache based hosts to get into the ruby game without much effort on their part and it allows the "expert" rails companies embracing nginx to start talking about further innovation and stop talking about the pain of managing deployments.

Tags:

My take on the Mac OS vs. Windows argument


Written on April 14, 2009 – 2:17 pm | by admin

I have worked with, networked together, programmed, repaired and played on computers for the better part of the last two decades. While this by no means makes me an old wizard, it does mean that I should have something to say about why I might prefer one platform over another. It has been part of my job since my first IT position to advise people about what technologies they should be using to get the job done and I do have a few things to say on the matter. The bottom line is that it really has nothing to do with
Apple Vs. Microsoft anymore. Mac OS is a desktop client version of Unix. Apple has succeeded in creating what is probably the first commercially successful desktop pc that runs Unix and this means a lot. It is now about Windows Vs. Unix and its cyberpunk cousin Linux.

Security: Unix was born to facilitate hundreds or thousands of users or network connections and had begun to be battle hardened long before Windows decided to release its first networking edition. If you'd like some historical perspective you should read The Cuckoos Egg, by Cliff Stoll.  The truth is that the Unix operating system model was created for the very kind of computing we do today. The protocol we use to transmit data packets back and forth (TCP/IP) was developed on Unix environments for what we now call the Internet. Almost anyone using a computer is accessing a loosely connected group of services that could be hosted anywhere in the world. Windows was created to be a standalone operating system on a single PC and the explosion of the internet has meant that it has been trying to adapt itself to a new use model for almost two decades.

Usability: Apple did not make a better operating system. They took a more functional and secure operating system that already existed and made it more usable. By starting with a solid platform Apple was able to focus on aesthetic and that is really what they are best at. It seems that they already know they have a solid platform so they spend more of their time making it usable and friendly whereas it seems that Microsoft has been concentrating on putting a new coat of paint on the same old user interface elements. I have not seen anything in the windows platform that I would consider an innovative direction in user interaction since going from windows 3.1 to  windows 95 and that was almost 15 years ago. They did have a few bug light* features in vista similar to the expose feature in mac OS X.

Resiliance: Unix is built upon a much simpler and obvious architecture than windows. Look no further than the Windows Registry and you should see my point. Its a pretty good rule of thumb that the less moving parts something has, the less likely it is to break. In this case simpler is better.

Perception: I've spent quite a few years of my life in colleges and universities and I've found that nowadays academics seem to use linux/mac to an overwhelming extent. I've also seen IT managers at some of the more progressive firms say things like  "I expect a pro to use the best tools and that means using Mac OS". I've seen plenty of flikr shots of someone from microsoft doing a presentation from a mac book pro, and while this is by no means proof of anything it does go a long way towards buidling up the perception that Apple makes better computers.

Personally I do not believe that apple makes better computers but they do make computers, microsoft does not. Apple markets its computers and its operating system as a lifestyle and a lifestyle choice. They have made themselves a symbol of an open mind and a thick pocket book and these are not misconceptions. Their computers are high end and It takes an open mind to break out from the norm. Windows was the norm and every time someone switches over they are being open to the idea that there might be something better out there.

Unfortunately this latter point is probably what drives sales and the real importance of a good computing foundation is being lost on most of the folks who buy computers. Windows came from dos and there are quite a few lines of legacy code in there from its grandfather. Mac OS came from Unix and there are quite a few lines of legacy code in there from its grandfather.  Remember that the apple doesn't fall far from the tree.

*things that make you say ooh and ahh but zap you when you get close to them

Tags: , , ,

Bash Primer for Beginners


Written on April 12, 2009 – 4:11 am | by admin

If you are working with OSX or *nix flavored systems and you are not already automating mundane tasks with bash or some other scripting language than you must enjoy repetition.  I migrated over to OS X a few years ago and although I had been integrating Linux and Apple Operating Systems into the Windows networks I was running It wasn't until I finally made the switch for personal use that I saw the light. The power of the various *nix command line interpreters and shell scripting environments makes it tough to ever look back. I'll be adding to this primer over time but I'm basically doing it to remind myself to stop wasting my own valuable time on simple repetitive tasks.

Available Libraries: Inside of your bash scripts you have access to anything you can type at the command line regardless of their underlying language. Commands like 'ls' (list all files in a directory) and 'grep' (regular expression parser) are available to you in your scripts.

Where to put your scripts If you define a set of functions in a file you can load them in to your environment at any time by calling 'source script_name' but you will most likely want to source them in your profile configuration (.profile, .bash_profile, or .bashrc) depending on how your environment is configured. You can store a bunch of scripts in one place with any extension you'd like but sh is common (script_to_run.sh) and add that location to your path variable. You can also run a script from within its directory with

 ./script_to_run.sh param1 param2

Note that you must change the permissions on your script to make it executable.

chmod +x script_name.sh

Shebang Line : Tells the operating system where to find the command interpreter, Make this the first line of your script

#!/bin/bash

Standard Output Send the text 'Hello World' to the screen

echo Hello World

File Output output to file puts the output of the function helloWorld into the file hello.txt the file will be created if it does not exist

 helloWorld > hello.txt  #overwrite file with output
helloWorld >>  hello.txt #append output to file

Variables Standard assignment syntax, prepend with $ to retrieve

#assign like this
VAR=5
#access like this
$VAR

Functions : Simple function syntax you can pass parameters in to this function and they are available as $1, $2, etc...

function helloWorld(){
  #for example 'helloWorld earth' would have the string 'earth'
  #available witihin the function as $1
}

Pipes '|' : The pipe character will take the output of one operation and pass it in to another. The following line will take the output of the ls command and 'pipe' it into the grep command returning only items in the ls output that match the string 'world'

ls -la | grep world

Tags: ,

Show hidden files in finder in OS X


Written on April 11, 2009 – 8:07 pm | by admin

Every once-in-awhile I'll want to be able to view hidden files in the finder. You can google this problem and you'll find a lot of people with the same answer. Pop up your terminal and enter  "defaults write com.apple.finder AppleShowAllFiles True". The issue is that every time I need this I google it again because I just don't do it often enough to remember the syntax.  So I found it useful to create a bash function called showFiles that takes either True or False.

  1. #expects $1 to be either False or True
  2. function showFiles(){
  3.  
  4. defaults write com.apple.finder AppleShowAllFiles $1 && killall Finder
  5.  
  6. }

Now you can do 'showFiles False' or 'showFiles True'. I'll admit there are very few reasons to do this (show all files in finder) if you are proficient at the command line but sometimes I feel like being lazy and now you can be lazy too.

Tags: