It’s been bothering me for quite some time not being able to explain the people out there why they need to write unit tests. The most common responses that I got were “this is a waste of time” and “my application has no bugs”. Unfortunately, this overconfidence and cutting corners is hurting the developers (and the industry).
I compiled this short list of why I write unit tests:
Don’t let your customers discover embarassing bugs. Write tests to cover a multitude of scenarios and catch these bugs before they get into production.
Test complex scenarios quickly, without having to manually reproduce them in the application.
By testing often, you don’t break the application as you go. You can’t always know the indirect implications of what you’re writing, especially if you didn’t write the original application.
By testing early, you don’t write unnecessary code but only the strict necessary. This makes the codebase smaller and more maintainable. It also saves on development time.
You do not have to debug the same code twice. Once you have a test to account for a possible bug, you’ll pick up any wrong turns quickly.
You ensure readability. A unit test makes the purpose of your code easier to understand.
You ensure maintainability. Unit-testing forces you to better encapsulate functionality, thus making it easier to maintain and add new features.
Refactor without worries. Run the tests to make sure everything still functions as intended.
Save time on testing. You can test the entire application at the speed of your CPU.
Feel safer. How many times were you afraid to add a new feature or change something in your application’s core? No more!
Bonus: know exactly what is broken. Instead of hunting for an obscure bug, let the tests tell you what’s wrong and why. Example: the application will tell you when you add an item to a cart but the cart still appears empty. It will also tell you what item you tried to add for the cart to break.
You may have different reasons, so share them in your comments.
If you use Doctrine, then you probably know how lazy loading can hurt your performance. I carefully craft every query to everything that I need in one shot, but only what I need. One thing that evaded me at first was the i18n part.
Model Relationships
I am pleased with the way Doctrine + symfony magically creates all my models and database tables with i18n support. All my relationship names are explicitly defined in the schema.yml file. So, if I want to get all products in a transaction, I can access it via $transaction->Products. When crafting a query, I would say ->leftJoin(‘t.Products’) to make sure to load all the products at the same time as the transaction, potentially saving hundreds of queries later.
I18n
Since the i18n relationship is defined in a special way in schema.yml, without specifying a relationship name, I wasn’t sure how to write my Left Join. I looked up the Base[ClassName].class.php file but did not find anything useful. After analyzing all the parent classes, I found it: Translation. It might have seem obvious since the tables are names product_translation, but that element eluded me and I did not find anything in the documentation at the time regarding this.
Other uses
Now that I can get my product names with ->leftJoin(‘p.Translation’), I cut the number of queries in at least two. Knowing the Translation relationship can have other uses, like counting the number of translations in your code and warning the user about missing translations (no product name in French!). I can also use the Translation relationship to make my search-engine friendly URLs multilingual. I can write about this last one in another post if I get such a request.
The uses for the Translation relationship are infinite!
Most of the Web applications that I build are multilingual. Since I use the symfony framework often, I rely on the XLIFF standard.
The error
I used to ask my clients to send me a Word document with the translated text. This is the format that they are most comfortable with. An error occurred recently when I copied the text directly from the document to an XLIFF file. For some reason, I could only see the original, English values.
The cause and solution
I would have probably not found the error had I not validated the XML translation file. It gave me a parsing error right in the middle of various strings. They looked fine until I turned on the special characters. Apparently, some special, invisible characters generated a parsing error and broke my application. I sanitized my strings and voilà!
Good practices
Since that incident, I always turn on the special characters in my text editor so that I may pick up any glitches earlier. Also, I no longer ask clients to supply a Word document, but rather a plain text document created with Notepad. To some more technical clients, I even supply the XML with empty <target> tags that they may fill in. That makes less work for me, gives satisfaction to the clients, because they feel empowered, and prevents any parsing errors.
I downloaded great icons from http://iconaholic.com but could not convert them to PNG. The info dialog said that it was a Unix Executable. After reading multiple posts on the Web, I finally mashed them up into a viable solution. No additional software is necessary.
Select the file or the application that has the icon you need. Open the info dialog by selecting Get Info from the File menu (Cmd+I). You will see the desired icon at the top-left of the dialog. Click it and it will be outlined in blue. Now copy it (Cmd+C). Open the Preview application and choose New From Clipboard from the File menu (Cmd+N). You can navigate to the desired icon size and select Save As from the File menu (Cmd+Shift+S). Select the desired file format and save!
Thanks to all the participating communities, I was able to produce the following ConFoo video. It talks about what to expect from the 2010 conference. I hope you have as much fun watching it as I had making it.
Recent comments