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!!!
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!!!
0 Comments:
Post a Comment
<< Home