Sunday, July 30, 2006

Thank you Paul and John Paul!

You know it's been a while since I had one of those days where I truly had a great time writing code. Could be all the Java I've been working on these days, or maybe a few other reasons, but I've been feeling a little bogged down lately and it sure was nice to have a fun time coding again. So why was yesterday so nice you may ask? Well I'm back to some contracting work that I was working on last year on a well designed system written in ColdFusion, for one thing. And it's been quite easy to jump right back in to the system, which in itself is a testament to good design. But what made yesterday even that much better than the breath of fresh air which is working with ColdFusion was a little gift that Paul Kenney sent me the other day. I know, Sean has already told you about the wonderful new cfcUnit with Ant integration, brought to you via John Paul Ashenfelter, but I simply must sing it's praises again! Now I am a huge believer in TDD or Test Driven Development. JUnit is a big part of my development cycle these days, and I do try to use cfcUnit as much as I can. But to be honest, unit testing in cf has been pretty far behind Java, and the main reason is the fact that I want to test while I'm coding, immediately. Having to deploy (unless you work locally out of a web root), and then go to the cfUnit test runner app, and then load my test case there, well, it's not exactly the greatest. But it is worth it, so I do it. Until now...

So I finally deployed the new version of cfcUnit and stuck the ant-cfcunit.jar somewhere easy, in an ant-cfcunit directory in my home folder, btw, put together a quick build script and, well a few minor glitches, but 15 minutes of tinkering later... cfcUnit tests! Right there in eclipse! And some nice simple output in the console! This is freaking great! (Can you tell I'm excited, btw?) But really, I'm working on very broad changes to the model in this app, top level logic changes that will effectively make changes all over the codebase. So I want to pretty much work in isolation right in test cases before I put these components into the model and check them inside the app logic. What I want to do is work in complete isolation of the rest of the app, and test at a very fine grained level. The great think about being able to do this right in eclipse is, all I have to do is start the cf server, but I never have to leave the editor. Even though running tests from the test runner app is still outside of the application, this just feels so much more natural, and, well, I guess more like JUnit. So thank you so much Paul and John Paul, much kudos to you!

Since it would be helpful of course to show how this is done, here we go. As I said, I deployed the new, soon to be released cfcUnit to my app server, and put the ant-cfcunit.jar in /Users/Chris/ant-cfcunit/. My build.xml file looks like so:

<project name="tests" basedir="." default="VerboseTest">

  <property name="home" location="/Users/chris/">
  <property name="hostname" value="localhost">

  <taskdef name="cfcUnit"
      classname="org.cfcunit.ant.CFCUnitTask"
      classpath="${home}/ant-cfcunit/ant-cfcunit.jar">

  <target name="VerboseTest">
    <cfcunit hostname="${hostname}"
            testcase="org.foo.unitTests.AllTests"
            verbose="true"
            haltonfailure="true"
            haltonerror="true"
            showstacktrace="true"/>
  </target>

  <target name="SimpleTest">
    <cfcunit hostname="${hostname}" testcase="org.foo.unitTests.AllTests"
            verbose="false"/>
  </target>

</project>


Next, open up the and view, load the build button and hit the little play button, and watch her go! You can see I have the verbose version set as the default, and can change to a simple version if I need. Also, I have set up a test suite, and each time I change a cfc, I write a test case and add it to the suite. So there you have it, now go and test!

Saturday, July 15, 2006

mysql quick-tip

I just ran into an issue with rebuilding a mysql database for development, moving the database from a windows server to a linux one. By default windows mysql converts tables names to lowercase, when I imported the database onto my linux server all the filenames for the tables are also of course going to be lowercase. Unfortunately all of the app's queries refer to the tables with camel-case, probably the intention in the first place. Problem is, now my linux mysql instance cannot find any of these tables, because the filenames are lowercase. So how do we fix this? Well, luckily we can start mysql with the flag 'lower_case_table_names', set it to true and mysql will now force tables name to lowercase just like in windows:

[chris@myFC4box ~]$ sudo mysqld_safe --lower_case_table_names=1 --user=mysql

Hope that helps if anyone else gets in this bind!

Monday, July 10, 2006

Pointcuts, even more fun with regex!

Ok, so maybe 'fun' isn't the right word, but I have to say that I though it was pretty damn cool the first time I swapped out a pointcut for a regex one (yesterday)! Incase you're already wondering what the heck I'm blabbering on about, currently ColdSpring has a pretty simplistic pointcut model, you can only really define them as globs, strings which can contain the '*' wild-card. Simple, yes, but in that simplicity lies tremendous power, which is what I find so fascinating about AOP in the first places. So currently we can match all the set or get methods in an object by defining a pointcut with the mappedName 'set*' or 'get*', and just for a refresher, we would do that by creating an advisor like so (here we are providing a cachingAdvice):

<bean id="cachingAdvisor"
    class="coldspring.aop.support.NamedMethodPointcutAdvisor">
    <property name="advice">
      <ref bean="cachingAdvice" />
    </property>
    <property name="mappedNames">
      <value>get*,set*
    </property>
</bean>


Here we are defining a NamedMethodPointcutAdvisor and providing it a list for mapped names, get* and set*. Side note, the <list> element in ColdSpring refers to a CF Array, following the Java DTD, to use a CF List provide a string list as a <value>. Behind the scenes, ColdSpring will create a NamedMethodPointcut, and provide it with the mappedNames value. This pointcut is what the framework will use to preform the method matching in order to identify the methods that you would like to add, in this case, the cachingAdvice to. So this is all very good, but what if what we want to do is add caching to all the methods EXCEPT the getters and setters. Ahhh, enter the RegexMethodPointcutAdvisor, which as you would probably guess, will create a RegexMethodPointcut. So lets see how that will look, with a pretty complex regex pattern to match all methods except the setters:

<bean id="cachingAdvisor"
    class="coldspring.aop.support.RegexMethodPointcutAdvisor">
    <property name="advice">
      <ref bean="catalogCachingAdvice" />
    </property>
    <property name="pattern">
      <value>^((?!get).)*$
    </property>
</bean>


So as you can see, we are defining a very similar advisor, but this time we provide a property called 'pattern' which will be our regex pattern. This one's a bit complex as we need to use negative back referencing, which honestly is a bit confusing to me, but google is your friend! But the great part is now we can define methods to exclude from matching, which is tremendously powerful. Want to look for getters and setters? Use this pattern ^((?![g|s]et).)*$ and you should be fine.

The two new components, RegexMethodPointcutAdvisor and RegexMethodPointcut are available via cvs. Happy AOP'n!

Sunday, July 02, 2006

CFUnited wrap up, Unit Testing and RHH…

I just got back from a nice long ride to clear my head and shake out few neural passageways that seemed to have somehow become clogged with alcohol and lack of sleep, so I figured I would share my thoughts on the festivities of the past week. CFUnited was fantastic and I had a really, really good time, maybe even too good, I’m TIRED! As far as sessions go, I think my 2 favorites were Adam Wayne Lehman (aka. Adam Way)’s talk on security and Dave’s talk on ColdSpring. OK, I know it sounds very partial, right? But Dave was truly amazing; he’s a top-notch speaker and came prepared with an enormous amount of information, which was very well put together. He took his time with the material, and was even able to answer questions while going through the session and still make it through all his slides without rushing. Somehow or another he was able to squash a talk about AOP into 15 minutes and 1 slide and still have it make perfect sense. Dave’s a valuable member of our community and great leader for the ColdSpring project in general. While we’re on the subject of value, I don’t think a single person of any skill level didn’t learn something at Adam’s session on securing CF applications. Adam has a unique experience dealing with security issues in a very tight environment (Department of State), and went through an amazing amount of information, from designing baseline installation documents, to securing your OS (even Windows), to working with CF’s sandbox security. He went on to discuss how to attempt to prevent DoS attacks, and the importance on keeping on top of not only ColdFusion, but also JRun security patches, as well as using the setting in Application.cfm/cfc. Just kidding, it doesn’t exist. Put your documentation away. Unfortunately right as he was discussing a bunch of different cross site scripting attacks, my wife called twice, and I had to leave, so I hope to be able to catch that session again at some future conference. Other sessions worth noting were Paul Kenney and John Paul Ashenfelter’s pre-conference session on Unit testing, and John Paul’s session on Agile development process, which generated quite a stir at the conference. I heard many people talking about the session, even though I missed it. Of course, Sean’s sessions were great, but I have already seen them both, so for me they didn’t garner up as much excitement as the aforementioned. Don’t take that as any recommendation against seeing Sean speak, because you would be doing yourself a great disservice.

OK, so aside from the sessions, I think one of the most important things I saw at the conference was the prevalence of discussions about unit testing. I talked with many people about how and why we should be unit testing our code. One thing that I repeatedly kept talking to people about however, was trying to write unit tests as early as possible, and not only because it is harder to write tests after your complete large pieces of application code (as you may inadvertently skip functionality that should be tested). In order to be able to write unit tests against individual objects in your model, those objects need to be as self-sufficient as possible, or they are not testable. This is a central concept in what is know as Test Driven Development, where testability is actually designed right into your components. It only takes a second to realize that when components are designed for testability, they become more cohesive and more loosely coupled. For example, lets say we are working on a DAO, and we access form variables in our queries. Well, this DAO is now completely un-testable because it is dependent on the form scope, which means it can only be tested in a running application. How about a service component that retrieves data from a Mach II or ModelGlue event object? Again, we can’t effectively write unit tests for that service because it is dependent on those frameworks. In Dave’s ColdSpring session, he discussed the problems associated with what he called a ‘brittle domain model’ where components are too dependent on other components to get their job done. These types of components are also much harder to unit tests, because you need to create a complex web of objects just to run a test. One of the other big problems with testing complex, dependent model components is, what you end up creating as a test case, is really a q/a type test on use cases. You are testing how a large dependency chain works in what you feel is the real world of your application. But when a small thing needs to change and begins to alter functionality deep down in your domain model, you have very little in place to reflect and catch those problems. As a case in point, within the past month on two separate occasions I made some changes to model objects that made my unit tests fail. I now tend to build unit tests for every single object, and then more unit tests for groups of objects returned as services from Spring. I then build all of those unit tests into one big test suite that I can run when I make some changes, and I can tie them into my build process. Anyway, back to my point, when I made the initial changes, I had introduced some issues that caused problems in other parts of my model. Now the thing is, I would have never caught these problems until q/a, which would have really sucked. One of these issues in fact would have only caused problems some of the time, making it really hard to test and find. However, these changes failed in the unit tests. You’re probably wondering how that could be, and here’s the thing. The components held themselves up when tested together, as services, because they supported each other (and ended up being a little brittle, I suppose), but the tests written against the components themselves actually tested the objects in ways that my application doesn’t necessarily function, making them really effective. The end result was I was able to fix both problems within minutes of running my test suite, but who knows how long debugging would have taken during q/a. Even though it definitely takes extra effort up front, I would strongly suggest looking into unit testing as early as possible, and also do some general research on test driven development, or TDD, there’s some great stuff out there.

Oh, one last thing about that, as I have discussed, TDD lends itself very nicely to developing more cohesive and looser coupled model components, which just so happens to play very nicely with ColdSpring, which encourages the same thing by decoupling your model components from their dependencies. Wait, you may be thinking, if I decouple my model components from their dependencies, how do I put them together to test them? Well, it only takes 2 lines of code in setup in a test case to load a beanFactory, and just one more to retrieve a bean. As I had also mentioned before, try to test components by themselves as well as with all their dependencies resolved by ColdSpring, it really helps show their weaknesses!

Happy testing! And oh yeah, RHH!!!