The web application we're currently building is using JSF. I confess that nothing I've heard about JSF appealed to me, but with an open mind I've been getting my hands dirty with the actual coding. Most of my prejudices were indeed confirmed. However, relying on pre-built components is very nice, specifically we're using JBoss's richfaces. The last web application I worked on was very UI-centric, and much of its development involved integrating and customizing the Dojo widget library -- very tedious work. That I'm no longer required to do so is a benefit of JSF I'm enjoying.
This recent post on "The server side" sums up nicely my impressions of JSF (I especially like the term "Old School HTTP wranglers"). I'd add to it by saying that traditional page design workflow isn't as straight-forward with JSF. With action-based web frameworks, it was rather easy for a HTML designer with some technical acumen to directly edit JSPs to implement a look and feel. Not so with JSF -- you're farther away from the final HTML. Its the components you include on the page that generate DIV tags and so forth. Having accrued 10+ years experience working with HTML, I find this the most frustrating aspect of JSF. We've been given a series of HTML Mockups from a design firm, and integrating has proved to be very challenging. I wonder if JSF merely shifts work efforts from HTML editing to Component customization.
I'm still not sold on JSF, but may be singing a different tune once we start implementing fancy AJAX and UI controls.
Saturday, October 27, 2007
Monday, September 17, 2007
Redefining the Integration Test
Recently I had been discussing with another developer the distinction between "integration test" and "unit test", and he echoed the same wisdom heard elsewhere. An integration test is any time a test case requires outside resources (i.e. external database, other servers, etc) in order to execute. This is the same definition proffered by a No Fluff Just Stuff conference I had attended a while ago. While I agree that this has been a good rule of thumb, I feel as if it may be time to reexamine this position.
The problem these days its so easy to spin-up resources from within one's test case that I'm not sure that's a fair unit/integration litmus test. Presently, I count libraries like Unitils, DbUnit, and Hypersonic as tools in my testing arsenal. The latter is an in-memory database, and by leveraging it within my test case I eliminate the need to have, for example, MySQL running during test execution.
In many of my tests, I've swapped out use of MySQL with Hypersonic, allowing my test case to be truly autonomous. Using the classic test definition, I've made my test case go from integration to unit test. Merely by changing the spring context file to point to an actual running database, Presto! -- its an integration test again. There's something amiss with the test definition, I feel, when traversing between the two types of test is so easily made.
I'm compelled then to reflect on what unit testing means to me. One of my core beliefs is that unit testing is about isolation -- truly testing only that code which is executed within a class. Take your typical DAO method (excuse the formatting):
public Widget getWidgetByLabel(String label) {
}
When I put on my unit-testing peering specks, I see very little logic to test here. This is a happy conclusion -- having too much logic within one's DAO is not a good thing. My unit test for this method would merely insure:
Therefore, I think I'm revising my personal litmus test. Only when a test case is truly testing in isolation will I consider it a unit test. If a test case involves logic in other classes and libraries, I shall regard these as integration tests, even if it requires no outside resources.
The problem these days its so easy to spin-up resources from within one's test case that I'm not sure that's a fair unit/integration litmus test. Presently, I count libraries like Unitils, DbUnit, and Hypersonic as tools in my testing arsenal. The latter is an in-memory database, and by leveraging it within my test case I eliminate the need to have, for example, MySQL running during test execution.
In many of my tests, I've swapped out use of MySQL with Hypersonic, allowing my test case to be truly autonomous. Using the classic test definition, I've made my test case go from integration to unit test. Merely by changing the spring context file to point to an actual running database, Presto! -- its an integration test again. There's something amiss with the test definition, I feel, when traversing between the two types of test is so easily made.
I'm compelled then to reflect on what unit testing means to me. One of my core beliefs is that unit testing is about isolation -- truly testing only that code which is executed within a class. Take your typical DAO method (excuse the formatting):
public Widget getWidgetByLabel(String label) {
List results = hibernateTemplate.find("select w from Widget w where w.label=?", label);
if(results.isEmpty()) {
throw new WidgetNotFoundException("No widget exists with the label:" + label);
}
return (Widget) results.get(0); // ignoring too many results for now.
}
When I put on my unit-testing peering specks, I see very little logic to test here. This is a happy conclusion -- having too much logic within one's DAO is not a good thing. My unit test for this method would merely insure:
- The proper arguments are passed to the hibernateTemplate.find() method.
- An empty List will trigger an exception.
- A non-empty List will make the method return the first object in the list.
Therefore, I think I'm revising my personal litmus test. Only when a test case is truly testing in isolation will I consider it a unit test. If a test case involves logic in other classes and libraries, I shall regard these as integration tests, even if it requires no outside resources.
Sunday, September 16, 2007
Bamboo Disappointment
Being a big fan of Atlassian's Confluence and Jira, it was with much anticipation that installed Bamboo, the continuous integration (CI) engine they've released. Perhaps these high expectations led to my ultimate disappointment with Bamboo, but truly the features I've come to expect in a commercial CI product are nowhere to be found.
No concept of inherited project structure.
If you have 20 modules you would like to build, defining behavior and properties for each is a daunting task. QuickBuild and AntHillPro both allow for a hierarchal organization of modules, so that a child may inherit properties (like environmental variables, build targets, etc) of its parent. In Bamboo, when creating a "Plan", I can clone an existing module, but that's it. Should I have the need to change a property for all plans, I'll be forced to configure each through the web GUI. A tedious process -- even with Cruisecontrol I could search & replace config.xml in a text editor to make wholesale changes.
Alien nomenclature
In Bamboo, you have top-level "projects", and beneath them you have "plans", which represent the modules being built. I've never used the word "plan" before when describing a module's build, and frankly the limited options offered by Bamboo to govern build behavior makes it a dubious word choice.
No passing of properties
It is sometimes desirable to direct a CI engine to pass arbitrary properties to one's build process, and vice versa. I don't mean "static" environmental variables, rather I refer to dynamic properties like "version number". No such functionality is present in Bamboo. Luntbuild and Quickbuild both allow for this using OGNL expressions.
No concept of build promotion
Most commercial CI products have evolved to include "Application Lifecycle Management", so you may describe how a build can go from being development-status to gold. Implicit in this is a workflow allowing QA to promote and release builds. None of this is even hinted at in Bamboo -- it does not even tag your build.
Summary
Features that Bamboo stresses seem misplaced. You'll see much mention of its heralded "Build Telemetry", on the product's site. Through this feature, you can generate nice graphs and statistics about one's build. But honestly, I've regarded charts and graphs in CI engines as a feature present because they're easy to add. While its fun to see how often one's build has been broken, I've never seen a lasting need for such statistics.
These are merely the shortcomings I've experienced, but I'm sure there are others -- like remote builds (where the CI Engine is deployed to multiple servers) for which I've no immediate need, but will no doubt be experienced by others. Its hard to see what advantages Bamboo offers beyond a free product like Luntbuild besides a pleasing user interface. Indeed, Luntbuild's features like OGNL expressions and Eclipse plugin makes it, in my opinion, more feature-rich than Bamboo.
My favorite build server remains QuickBuild. It was with tremendous ease that I was able to control and manage many modules at once. To be fair, though, its been awhile since I've looked at AntHill Pro or TeamCity from JetBrains, both products that looked promising when I reviewed early versions.
No concept of inherited project structure.
If you have 20 modules you would like to build, defining behavior and properties for each is a daunting task. QuickBuild and AntHillPro both allow for a hierarchal organization of modules, so that a child may inherit properties (like environmental variables, build targets, etc) of its parent. In Bamboo, when creating a "Plan", I can clone an existing module, but that's it. Should I have the need to change a property for all plans, I'll be forced to configure each through the web GUI. A tedious process -- even with Cruisecontrol I could search & replace config.xml in a text editor to make wholesale changes.
Alien nomenclature
In Bamboo, you have top-level "projects", and beneath them you have "plans", which represent the modules being built. I've never used the word "plan" before when describing a module's build, and frankly the limited options offered by Bamboo to govern build behavior makes it a dubious word choice.
No passing of properties
It is sometimes desirable to direct a CI engine to pass arbitrary properties to one's build process, and vice versa. I don't mean "static" environmental variables, rather I refer to dynamic properties like "version number". No such functionality is present in Bamboo. Luntbuild and Quickbuild both allow for this using OGNL expressions.
No concept of build promotion
Most commercial CI products have evolved to include "Application Lifecycle Management", so you may describe how a build can go from being development-status to gold. Implicit in this is a workflow allowing QA to promote and release builds. None of this is even hinted at in Bamboo -- it does not even tag your build.
Summary
Features that Bamboo stresses seem misplaced. You'll see much mention of its heralded "Build Telemetry", on the product's site. Through this feature, you can generate nice graphs and statistics about one's build. But honestly, I've regarded charts and graphs in CI engines as a feature present because they're easy to add. While its fun to see how often one's build has been broken, I've never seen a lasting need for such statistics.
These are merely the shortcomings I've experienced, but I'm sure there are others -- like remote builds (where the CI Engine is deployed to multiple servers) for which I've no immediate need, but will no doubt be experienced by others. Its hard to see what advantages Bamboo offers beyond a free product like Luntbuild besides a pleasing user interface. Indeed, Luntbuild's features like OGNL expressions and Eclipse plugin makes it, in my opinion, more feature-rich than Bamboo.
My favorite build server remains QuickBuild. It was with tremendous ease that I was able to control and manage many modules at once. To be fair, though, its been awhile since I've looked at AntHill Pro or TeamCity from JetBrains, both products that looked promising when I reviewed early versions.
Sunday, August 19, 2007
Starting New Job
Next week I start my new job. I'm excited to get started.
Having worked from home for the past 6 months, I'm sure there will be some adjustments I'll have to make. Certainly my pajamas are probably no longer considered acceptable work attire. Although there were aspects of working from home I thoroughly enjoyed, there was a loss of team spirit which I'm looking forward to having again.
What really excites me, though, is jumping into some new code, especially since the code with which I had been working left much to be desired. I'm embarrassed to admit that despite Java5's age, I've not yet been on a project which uses it. Naturally I've boned up on Generics, Enums, etc, but no amount of reading replaces the familiarity I gain from using something day-in and day-out.
Having worked from home for the past 6 months, I'm sure there will be some adjustments I'll have to make. Certainly my pajamas are probably no longer considered acceptable work attire. Although there were aspects of working from home I thoroughly enjoyed, there was a loss of team spirit which I'm looking forward to having again.
What really excites me, though, is jumping into some new code, especially since the code with which I had been working left much to be desired. I'm embarrassed to admit that despite Java5's age, I've not yet been on a project which uses it. Naturally I've boned up on Generics, Enums, etc, but no amount of reading replaces the familiarity I gain from using something day-in and day-out.
Thursday, August 2, 2007
Yawlp
Awhile ago, I decided it would be immoral of me to deprive the sphere o'blogs my erudite, insightful voice of reason. But it took time for this idea to be realized, chiefly due to my inability to create a blog title that I thought would accurately describe my online essence. Finally I said to hell with it -- I'd never find the perfect title (I lack my brother's talent for catchy, pithy names). So I choose the apt, but not perfect, title "Rich Inner Life". With dismay I found it was not available, and therefore christened this blog "Poor Inner Life." Like, y'know, to be ironic.
Subscribe to:
Posts (Atom)