I've done a lot of automated testing with JUnitand StrutsTestCase, but have wanted to explore other areas like mocking and continuous integration. So I decided to try out a Java mocking framework. I read a few blogs and decided to give Mockito a try. It's definitely an easy setup - just copy one jar file into your project (or add it to the build path in Eclipse). I then went through this tutorial to get a feel for it.
Never having done mocking before, it took me a little while to get use to the syntax and how it worked. I definitely need to spend more time with it on a real project to get the full feel of it. Having glanced at other mocking frameworks like EasyMock, it seems Mockito is a bit more streamlined and clean. For instance, there's no need to call replay to start the mock. But they look quite similar. Did I read Mockito came from EasyMock?
One of the challenges with mocking in an existing project is that the code must written in expectation of doing mocking. It's not simple to just slide in some tests. To do mocking, the code needs to use dependency injection (so the mocked objects can be injected) and use interfaces. One of the systems I'm working on right now is a Struts MVC application. It has nice layers with actions and DAOs, so it was straight-forward to use JUnit to test the DAOs and StrutsTest for the actions. But I'm trying to find a way to apply mocking to it and can't - data source objects are instantiated within the DAOs and are concrete classes. I may be able to refactor the code but that becomes a much larger effort. This is a good reason why you need to think about testing as you start developing an application.
Thursday, April 22, 2010
Pixar, Innovation and Agile
Have I mentioned I love Pixar?
It started off with Toy Story, their first full-length theatrical film and the first such film completely computer-generated. Their movies have such heart and great stories and characters. Many of their films have a deeper meaning for me - Ratatouille (I love to cook), Cars (The summer after its release my son and I took a week long vacation in my Mini Cooper convertible along Route 66), and Up (My son and I went to an Up pre-release event at the Pixar studios in Emeryville, CA.), are just a few examples of this.
I've also been an investor in Pixar, initially buying shares shortly after their IPO in 1995, and on and off afterwards until their merger with Disney. It was a great run, and in some ways I wish they had stayed an independent, public company.
But for the past number of years my interest and excitement in the company has come from their innovative culture.
A number of articles and even books have been written on their culture. It is very open, creative, collaborative, and from the performance of their films, very successful. The artists at Pixar work hard, have fun and really enjoy being there.
But this type of culture does not only pertain to the entertainment or animation industry. I have often thought about how software and technology companies could benefit from following a similar culture and management style.
A recent McKinsey Quarterly article (registration required) interviewed Brad Bird regarding his views on stimulating innovation. The ideas of collaboration, morale, open and frequent reviews of products, and being "good enough" all relate well to the Agile development methodology for software. I plan on writing a few blog posts on software innovation using this article as inspiration.
It started off with Toy Story, their first full-length theatrical film and the first such film completely computer-generated. Their movies have such heart and great stories and characters. Many of their films have a deeper meaning for me - Ratatouille (I love to cook), Cars (The summer after its release my son and I took a week long vacation in my Mini Cooper convertible along Route 66), and Up (My son and I went to an Up pre-release event at the Pixar studios in Emeryville, CA.), are just a few examples of this.
I've also been an investor in Pixar, initially buying shares shortly after their IPO in 1995, and on and off afterwards until their merger with Disney. It was a great run, and in some ways I wish they had stayed an independent, public company.
But for the past number of years my interest and excitement in the company has come from their innovative culture.
A number of articles and even books have been written on their culture. It is very open, creative, collaborative, and from the performance of their films, very successful. The artists at Pixar work hard, have fun and really enjoy being there.
But this type of culture does not only pertain to the entertainment or animation industry. I have often thought about how software and technology companies could benefit from following a similar culture and management style.
A recent McKinsey Quarterly article (registration required) interviewed Brad Bird regarding his views on stimulating innovation. The ideas of collaboration, morale, open and frequent reviews of products, and being "good enough" all relate well to the Agile development methodology for software. I plan on writing a few blog posts on software innovation using this article as inspiration.
Friday, March 26, 2010
How NOT to backup a UNIX system
I'm a fan of Pixar. Not a casual fan, mind you. More like a fanatic, watch every movie multiple times, plus every piece of bonus material and director commentary, read every article, follow every artist and animator on Twitter kind of fan. When I have spare time I even work on the Pixar Wikia site.
So of course I bought the new Toy Story/Toy Story 2 Blu-rays when they came out this past Tuesday (and saved $10 each since I had previous copies of the movies on DVD!). One of the great bonus features on the discs are the "Studio Stories": cute, short stories told by the artists and animators reminiscing about some of the funny moments during the production of the films.
How does this relate to the title of this post? One of the Studio Stories on the Toy Story 2 disc is called "The Movie Vanishes". Oren Jacob and Galyn Susman tell the story of how someone ran the "rm -rf *" command on the UNIX server holding the Toy Story 2 film. For you non-UNIX folks, this command removes all the files on the system. In this case it included large parts of the still-under-construction film! Fortunately they were able to recover the data, but I can imagine how much panic there must have been!
This story reminded me one of my early experiences as a UNIX administrator. It was around 1986 and I was at U S WEST, where they were beginning to "mechanize" the engineering department - i.e. provide PCs to all staff and introduce email, word processing and other office automation tools. We were working with Power 6/32 mini computers from CCI, using commands like "cu" for remote communication (which would occasionally crash the system) and protocols like SLIP and UUCP.
One of my tasks was to create a backup process for the mini computers. I wrote a shell script using "find" and "cpio" to copy the different partitions to their backup counterparts (like /usr to /usrback, /home to /homeback). This script was to create a "full" backup of each partition. To do this the script had to first remove everything in the backup partition. For some reason I couldn't just use newfs, so I used "rm -r" to clean the partition.
So now the script is written, I add it to cron to run overnight (it would take hours to run) and go home. I come in the next day to see the results of my effort and what do I find? A crashed system with most of its files gone! After a couple of days of investigation I discovered my error. The script was looping through a list of partitions to backup. Within the loop I first removed all the data from the backup directory, then copied the source directory to the backup. The logic was something like this:
for dir in usr home var
do
rm -r /$dirback
find /$dir -print | cpio -pvd /$dirback # Don't remember the options to cpio
done
See the mistake? Pretty obvious but it took me a while to figure it out. While /$dir was defined (say /usr), I thought /$dirback would be converted to /usrback. What, no? Ah, so that's what "{" and "}" are used for! I thought the interpreter was smarter than that and know I meant "/${dir}back". So instead of removing everything under /usrback, I was actually doing a recursive remove from "/"!
So rather than spending the day being congratulated for my superb programming skills, I spent it reloading the OS (back then the system crashed quite often, usually requiring us to re-install, so I was fairly adept at doing it).
And do you know what the worse, most embarrassing, part of it was? I just couldn't understand how my backup script could wipe out the entire system. So after spending the day reinstalling, I was dumb enough to add my script to cron and try again. I came in the next morning with the system in the same state as the previous morning. At that point I had to admit it must have something to do with my script and went researching. Nothing more to say but FAIL.
Saturday, March 20, 2010
Project with JBoss and Richfaces
Well, I am starting a project using JBoss 5 with Seam and Richfaces tag library for the first time. I have been working with JSF using the Tomahawk tag library on a past project. Both of these projects use Hibernate. I am going to blog what I learn and the struggles I will likely have. All of these are done on a Windows platform. I've spent many years working on a Unix platform and use a Mac for home use. Sure glad for cygwin. I use the rxvt terminal and all the standard Unix commands (grep, tail, find, etc.) that makes a Windows box more Unix and command line friendly. I do like my Eclipse IDE and Tortoise for Subversion. I have been fighting an issue with Hibernate and will likely blog on the solution to that also.
Wednesday, March 17, 2010
Getting cfcUnit working
It's really uncomfortable now to modify or write new code without being able to unit test it. So I became very excited when I saw there is a xUnit test framework for ColdFusion called cfcUnit. I immediately went to work installing it. This wasn't quite as easy as I hoped, although most of this was my own fault (which I explain below). This post will detail how I got it installed and working.
First, a little about my environment. I'm running Windows XP and a developer version of the Cold Fusion 9 app server. I fortunately have admin rights to my box so I have full access to the wwwroot directory.
To summarize, it really was quite straight-forward to get cfcUnit working. Except for the extra directory layer in the cfcunit distribution, installing MachII and cfcUnit went as expected. I would skip installing the skeleton application.
First, a little about my environment. I'm running Windows XP and a developer version of the Cold Fusion 9 app server. I fortunately have admin rights to my box so I have full access to the wwwroot directory.
- The cfcUnit Download page states that it only requires ColdFusion MX 6.1 to run. But on the Getting Started Documentation page it states cfcUnit is dependent on the Mach-II application framework.
- Download MachII and unzip it into wwwroot. The version I downloaded is 1.8.0. After unzipping, the top-level directory should be MachII.
- I wanted to verify my MachII installation was successful. Sure, I could've just tried cfcUnit but on the Mach-II installation wiki page it mentioned there is a skeleton sample application that can be used to test the installation. It turns out this isn't necessary at all and was the cause of most of my problems. MachII worked straight away, just like they state on the website, but I had a couple of issues with the skeleton application.
- Download the application from the Mach-II installation wiki page and unzip into the wwwroot directory. Note the zip file contains a duplicate skeleton hierarchy (i.e. skeleton/skeleton). To get this to work make sure you remove one layer of this, i.e. the Application.cfc file should be directly under wwwroot/skeleton.
- I couldn't find any documentation on how to use the application on the Mach-II website but there's a README file in the distribution. This says to test the application access this url: http://path_to_server/skeleton/index.cfm?event=showHome (i.e. http://localhost:8500/skeleton/index.cfm?event=showHome). But when I tried this I received the following error message: Could not find the included template /CHANGEME/views/exception.cfm.
- To fix this error, modify the skeleton/config/mach-ii.xml file. Change the value of the applicationRoot property from "/CHANGEME" to "/skeleton".
- I tried to go to the above URL again. It failed again, but this time with a different error message from Mach-II, so this must mean I'm making progress! The error was: Event-handler for event 'showHome' in module '' is not defined.
- There are 2 choices to fix this. The simplest one is to just go to /skeleton, rather than /skeleton/index.cfm?event=showHome. If you've done things right you'll get a "Skeleton Installation Success!" message. The second fix is to add an event handler for the showHome event. This is fairly simple - edit the skeleton/config/mach-ii.xml file again and search for the EVENT-HANDLERS section. Duplicate the code for the home event-handler and change the event name from "home" to "showHome". Now using the original skeleton URL should also work.
- Now it's time to install cfcUnit. Download the zip file from the SourceForge site and unzip it into your wwwroot directory. Note, the zipfile has an extra directory layer like the skeleton application - you should have the cfcunit and org sub-directories directly in your wwwroot directory.
- To test, go to http://path_to_server/cfcunit/. You should be shown a dialog box asking you to enter a test to run, as shown on the cfcUnit Getting Started page. Enter "org.cfcunit.tests.AllTests" and click on "Run Test". You should see all the tests succeed.
To summarize, it really was quite straight-forward to get cfcUnit working. Except for the extra directory layer in the cfcunit distribution, installing MachII and cfcUnit went as expected. I would skip installing the skeleton application.
Available assertions in cfcUnit
The documentation for cfcUnit is a little light. One of the first things I tried after going through the Getting Started with cfcUnit page on the cfcUnit site was doing an assertEquals. When I ran my test I got the error "Variable ASSERTEQUALS is undefined". So where's the list of available assertions? I couldn't find it so I went to the code. In org/cfcunit/framework/Assert.cfc I found the following available assertions:
Update: After coming up with this list I found this site that contains the assertions, many with descriptions. Why I didn't find it earlier??
- assertArrayContainsNumber
- assertArrayContainsString
- assertComplexValue
- assertComponent
- assertContainsString
- assertEqualsArray
- assertEqualsBoolean
- assertEqualsNumber
- assertEqualsQuery
- assertEqualsString
- assertEqualsStruct
- assertFalse
- assertNotNull
- assertNotNullComponent
- assertNotRegexMatch
- assertNotSameComponent
- assertNotSameStruct
- assertNull
- assertNullComponent
- assertObject
- assertRegexMatch
- assertSameComponent
- assertSameStruct
- assertSimpleValue
- assertTrue
Update: After coming up with this list I found this site that contains the assertions, many with descriptions. Why I didn't find it earlier??
Tuesday, March 16, 2010
Good times with Cold Fusion
My current position has me enhancing a number of applications, many of them written in Cold Fusion. I'll be honest, I'm very new to CF and wasn't all that excited about learning it until I discovered some cool frameworks like cfcUnit and ColdSpring. It makes sense there would be these types of frameworks since CF is built on top of Java, it just took me a while to discover them! I hope to do some posts on my experiences with these frameworks.
Subscribe to:
Posts (Atom)