Railo, Testing, and Stogies

Thursday, July 31, 2008

Last night, Gert Franz from Railo visited our Baltimore Adobe User Group. First, thanks to Gert for spending so much time with us. Next, thanks to Nic Tunney for leading the group, as always. Finally, extra special thanks to Bob Clingan for setting it all up. So, real quick: Railo is impressive. It's damn near unbelievable that such a small team of people could create a product so solid and forward thinking. Some of my favorite things:
  • Virtual file system. Treating an ftp site or an S3 instance as just another resource? BADASS.
  • Railo's notion of contexts. Each app is an isolated thing. We've been working around that problem with CF for a long time. With railo, it's simply not a problem
  • cfvideo is really, really cool. Now, I know that a lot of people don't want to see this in CF. And I know it won't be in the open source version of Railo. Still.... watching the kinds of sweet things Gert demoed, I can see its value
And there's so much more but I don't want to blabber. Two other things: I asked Gert if they expected to keep up the same pace of development when it goes open source. One thing he said was that the first thing they do when they get a bug is write a test. They fix the bug, prove it's fixed with the test, and keep that test around forever. We try like hell to do this with MXUnit, by the way. Anyway, he said that he believes part of the reason they can move forward with features is that they just don't have a whole lot of bugs. I took it to mean that their use of TDD contributes to that quality. So... mad props, Gert! Finally, the coolest thing of all: the Davidoff site runs on Railo. For those not in the know, Davidoff are a luxury cigar. In fact, I'm so cheap I've never had one. But still... I thought that was rad. Here's what I came away with: up until now, my only experience with Railo has been working to get MXUnit running on it successfully. But now, after last night's presentation, I'm definitely going to see if I can get some of our apps at work running on it. I'm particularly interested in looking at the performance. When OBD came out, there was nothing about it that made me consider for even a second approaching the subject where I work. With Railo, though, I see definite potential and consider it worth my time to pursue this investigation. And it's not just because I got a free t-shirt.

Coldbox and the CFEclipse Frameworks explorer

Wednesday, July 30, 2008

I just tried installing CFEclipse 3.2 beta again, and I see that coldbox still isn't supported in the Frameworks explorer. So I'm like, "hey, I remember Mark saying that the frameworks explorer was a framework for exploring frameworks", so I decided to dig into the XML and see if I could get it going. So I'm poking around in the cfeclipse code, just getting familiar with what's going on, and I fire up a debug session, and I add a coldbox project, and I set the coldbox.xml.cfm file as a config file, and I open up the explorer, and there's all these rad icons in there. So I'm like, WTF? So I open up the frameworks config directory, and lo and behold, there's coldbox right in there already. Now, the file timestamps indicate that this was in there before 1.3.2 was released, so I'm not sure what might have happened that this stuff didn't make it into the build. Nonetheless, that saved me a lot of time because all the work was done. However, this didn't solve the central problem, because if the stuff ain't in the distribution, how do I get it in my current CFEclipse install? Here's what you do: 1) download the attached file and unzip it into your eclipse\plugins\org.cfeclipse.cfml.frameworks_1.0.3 directory OR, if you want to get it from source: 1) check out the cfeclipse frameworks directory from SVN. If you want to save yourself the headaches, just read this (http://trac.cfeclipse.org/cfeclipse/wiki/CheckingOutCFEclipse) and do the team project set thing. it's a snap. 2) that will get all the cfeclipse code into your workspace. NOT your current plugins directory... your workspace. 3) go into your workspace, navigate to the frameworks project, and copy the config and icons directories into another temp location 4) remove the .svn stuff from there 5) now, take those directories and copy them into your eclipse\plugins\org.cfeclipse.cfml.frameworks_1.0.3 directory 6) restart eclipse. 7) find a coldbox project, find the coldbox.xml.cfm file, right click, set as config file, and bam. Done! Now, looking at how frameworks explorer works, I gotta tell you: it is unbelievably cool. Mad props to you, Mark Drew, for this gem. esher, out!org.cfeclipse.cfml.frameworks_1.0.3.zip

It's not you, Arturo...

Tuesday, July 29, 2008

A little over a year ago, I sprung 5 bucks on an Arturo Fuente. Until then, I'd never spent that much on a stogie. It was a life-altering cigar. Literally. I've spent more money on Fuentes since then than I ever would've spent on stogies had I stuck with my 1.20/stick cheapo La Fincas. Not life altering in the same way that marriage or children are, not even close. But still... Fuentes have been my staple stogie, a friend I return to time and again. Since then, I've bought boxes of Monte Cristos, smoked kickass Cohibas, Ashtons, and all manner of brands in between. I won 3 monster Gurkha "shaggy" cigars at an event at Cross Street Tobacco in Federal Hill, stickering at 15/stick, and they were magnificent. To the hunchbacked guys huddled over their rolling tables in the forests of Nicaragua and Honduras, a hearty "Thank you!" My wife and kids are out of town this week, at my in-laws. I couldn't go b/c of work, but I miss them terribly. So I decided to while away the time with good beers (Dogfish), programming, and cigars. My wife and daughters come home tomorrow (Thank God!), so I decided to spend the last night of my short-lived quasi-bachelorhood with a new stogie. I'm sorry, Arturo. It's not you. I still love you. But damn... Onyx Maduro, you .... *gasp*.... complete me. (super ghey reference, I know) Lord, what a stogie. A 2-hour smoke, burnt down to the very nub, and excellent all the way. Most stogies start to suck after an hour or so. They get hot, tarrish, nasty. But this one, jeeeeesh. I'm in awe. I married my bride at 4 on a Saturday afternoon. My firstborn, Alexis, was born at 10:15 on a Saturday Night. My dear little Sidney was born in the wee hours on a Thursday. Those nights are reserved in the "Best Saturday and Thursday nights of my life". Tonight, thanks to you Onyx, gets the Wednesday slot.

MXUnit 1.0.1 is now available!


MXUnit 1.0.1 is now available for download. This is a small patch release and includes:
  • var scope fixes
  • injectMethod functionality for simple mocking
That last one deserves some mention. Mock frameworks like Brian Kotek's ColdMock and Mike Steele's CFEasyMock are excellent tools for mocking collaborators. However, sometimes you want to spoof/override a function in your object under test for the purposes of testing some other function inside that same object. Say you have a function that hits the DB and you'd rather it not. Or you have a function that returns a query and you need to force it to return specific data rather than rely on the state of the database. If those functions are inside your object under test, a mock framework might not be much help here. That's why injectMethod was introduced... to solve the problem of mocking functions inside the object under test. A full write-up is available here. By way of history, this functionality came out of a previous post on mocking. I'll be providing a follow-up to that post, in the days to come, to show how that specific unit test changes as a result of injectMethod. Happy testing.

Code and Preso: Database Test Patterns for Unit Testing

Tuesday, July 22, 2008

Last week's presentation at http://coldfusionmeetup.com was wrought with difficulties, but hopefully some of the concepts came across the frazzled wire ok and folks found a thing or two useful.

The code and presentation materials are available here: http://github.com/virtix/zoo/tree/master

Click the "download" button and  you'll be given an option to download either a zip or tar. I've added Mike Rankin's code illustrating how to use SQL Server 2005 snapshots inside of MXUnit to keep your local database sandbox in a known state for testing. This is a great utility for those on SQL 05!

best,
-bill

New MXUnit goodies and a few backwards compatibility busters

Friday, July 11, 2008

There are a few small enhancements in the 1.0 mxunit release i wanted to talk about... and one change that will break some of your tests. 1) definitely check out the cfeclipse directory in the download. it's got snippets, a dictionary file, and instructions for both. for you ANT fans, there's a copy.xml file in there that should make bringing the snippets and keyCombos into your existing stuff a snap. 2) we don't encourage the (over)use of makePublic(), but it's nice in a pinch. One thing I never liked about it was that when you used it, the "public" version of your private function had a different name. For example, "doSomething" got turned into "_doSomething". That has been changed so that the name defaults to be the same as the function you're making public. If you have existing code that uses makePublic(), IT WILL BREAK!. Simply remove the underscore from the function call and all is well 3) if you were using any of the assertEmpty.... functions in the "MXUnitAssertionExtensions" component, they now behave exactly the opposite of how they did previously. Now, they do what they claim to do, i.e. assert something is empty. We had it backwards before. Blame it on the beer, scotch, stogies, and kids. 4) there's a new injectMethod() function in TestCase. For now, ignore it. I have a little more tweaking to do before it works properly for lightweight mocking. We'll be putting out a patch for it within the next few days, after we hear from other issues that people have. 5) the plugin and framework should now work with open bluedragon. If you have any problems with OBD and mxunit, please let us know. As for railo, I tried it as soon as it released, there was a bug in railo (because we were doing some dumb stuff that exposed the bug), and railo fixed it but i haven't given it another shot. I'm fairly certain that at this point mxunit will not work with railo... at least, the plugin probably won't. on a side note, i am extremely impressed with railo's responsiveness! extremely. I posted this "issue" one day and i think it was fixed the next. Like my daddy used to say, I didn't know whether to shit or go blind. Regardless, it's because of their responsiveness that we will indeed be making a hearty effort to get mxunit fully working with railo very shortly. 6) the ant task has been updated and now respects the "excludes" attribute. for me this was a big deal. thanks bill! So, any issues with the new release, please post it to the mxunit group or file a bug report at the googlecode site. thanks!

MXUnit 1.0 Now Available!


A really long time in the making, los hombres at MXUnit.org (http://mxunit.org) are finally distributing the first production release of their open source Unit Test Framework and Eclipse Plugin for ColdFusion Developers.

The big truth is that we want to get this version out because we are chomping at the bit to make MXUnit much more robust and flexible -"We're figuring on biggering and biggering ..." - Dr. Suess

Improvements since RC-1:
* More documentation and tutorials
* Dictionary and snippets for CFEclipse
* assertXPath(...) for testing generated html, xml, and anonymous web pages
* assertSame()/assertNoteSame() - Thanks Mark Mandel!
* HTML runner and remote web runner for test suites
* Test Blaster - recursive test stub generator
* Ant task: errorproperty/failure property, and more ...
* J2EE CFML open source (Railo/OBD) comparability issues addressed - Thanks Adam Haskel!
* And one, maybe two minor bug fixes ;-)

Upcoming Features:
* Selenium Integration
* Annotations for flexibility
* Improved TestSuite constructs
* Test report generation (in lieu of JUnit reports)
* And more ...

Upcoming Events:
* ColdFusion Meetup - "Database-centric Testing w/MXUnit", Thursday, July 17, 2008. 12:00 Noon EDT
* Adobe Max 2008 - "Advanced Patterns for ColdFusion Test Automation", Wednesday, November 19, 9:30 AM  PST

Key Features:
* Easy to see your data with cfoutput, cfdump, and debug()
* Easy to run single test functions
* Easy "directory runner" for running entire directories of tests
* Easy to test private functions in your components
* Ability to switch to message-first style assertions to help ease transition from other frameworks
* A plethora of output formats from which to choose
* Ant Integration
* A team actively improving the framework, making testing easier, and providing abundant documentation

Download the latest version of the framework here: http://mxunit.org/download.cfm and update your MXUnit Eclipse plugin using the following url: http://mxunit.org/update

Special thanks out to Sean Corfield all the folks who really kicked the tires and gave good honest feedback! Keep 'em coming ...

Thanks!
The Guys at MXUnit.org

Using MXUnit to Test SQL Server Database Logic

Tuesday, July 1, 2008

I need a way to test database logic and to persist those tests. In the past, I would open query analyzer type in some batch code, hit F5 and visually inspect the results. If all looked good, I would move it to a stored procedure, view, CF code, or some other object. There are a number of problems with this approach, and the one that bugs me the most is that the work product of this process becomes lost. Though I may have something working in the end, the pieces and what I was thinking at the time are gone, and at my age, that means gone forever.

Enter MXUnit ... using an xUnit framework to test a database? Why not? Ideally, it would be nice to have an xUnit database tool that allowed me to test snippets of batch code. I know there's sqlunit and dbunit that may work, but where I'm at, our db's are tied down pretty tight, but given a cf datasource and MXUnit, I can get pretty far. I can also wrap stored procedures up in tests and print out reports of database test suite runs for the dbas (more on this one later).

Here's a little gem that popped up the other day. Did you know you can define a CURSOR object inside of CFQUERY? I didn't, but here's is part of something I wanted to test:

  
---- Super Simple SQL Date Stuff ----  
DECLARE @fiveMinutesAgo datetime, @rightnow datetime 
SELECT @rightnow = GETDATE() 
SELECT @fiveMinutesAgo = DATEADD (n, -5, @rightnow)
PRINT @rightnow 
PRINT @fiveMinutesAgo
---- End ----

This simply prints the time the batch was run and that time less 5 minutes - mine eyes verify the correctness. Not too bad; certainly not automated; but, it has a smell that is becoming increasingly intolerable for me.

Here's the same thing written as an MXUnit test:

<cffunction name="testCallingDbDateFunctions">
  <cfquery name="q" datasource="logparser"> 
    DECLARE @fiveMinutesAgo datetime, @rightnow datetime  
    SELECT @rightnow = GETDATE()  
    SELECT @fiveMinutesAgo = DATEADD (n, -5, @rightnow)  
    
    DECLARE dbTestCursor CURSOR FOR  
    SELECT @rightnow as nowDate, 
           @fiveMinutesAgo as fiveMinutesAgo;  
    OPEN dbTestCursor;  
    FETCH NEXT FROM dbTestCursor  
    CLOSE dbTestCursor;  
    DEALLOCATE dbTestCursor  
  </cfquery>  

  <cfscript>  
    rightNow = q.nowDate;  
    exepectedDate = dateAdd('n', -5, rightNow);  
    fiveMinutesAgo = createODBCDateTime(q.fiveMinutesAgo);  
    debug(q); 
    assertEquals(exepectedDate,fiveMinutesAgo,
                "If broken, could be a date bug in CF or SQL.");  
  </cfscript>
</cffunction> 

The debug output looks like this:

image

This looks like a lot of code to test such a simple piece of logic, and it is. But, the cool things about this for me, were (1) I can create a CURSOR object within CFQUERY and the name of the query becomes a reference to the CURSOR, and (2) I can use MXUnit and ColdFusion to run and persist database logic tests.

More on database testing soon ...

-bill