Thursday, April 9, 2009

Installing SQL Server 2008 with Visual Studio 2008 SP1

When I brought up my most recent Windows development machine (on Vista Ultimate), I installed Visual Studio 2008 Professional with SP1 embedded. Later, I went to install SQL Server 2008 including the "Management Tools" option so that I could have SQL Profiler and the other tools. That's when the problems started. The installation was blocked failing this rule:

Rule "Previous releases of Microsoft Visual Studio 2008" failed

Imagine my surprise when I found this article indicating that the problem was that I didn't have VS 2008 SP1 installed. I'm sure that I was running SP1, because I was seeing SP1 bugs manifested (requiring hotfixes). These bugs were only present in SP1 as of the time of this writing. It seems that a required registry key or something didn't get set when I installed Visual Studio. I really didn't want to get into hacking on the registry.

Solution



I downloaded the Visual Studio 2008 SP1 installer and ran it. This took quite a while, and I'm now up much later than I planned. However, I can report that this got me past the installation block. I'm not sure if I'll have to reinstall those hotfixes or not...

Happy coding!

Wednesday, March 11, 2009

Standing on the Side of Right

Anyone that has worked with me will tell you that I am passionate about getting things right. I like to fix things that are broken. I like to improve my skills. I like to challenge others around me to improve and I expect them to do the same for me. I rarely miss the opportunity to improve myself or to encourage others to prove. I love teachable moments.

This morning, after reading Alan's thoughtful post on sexual harassment in the IT industry, I wonder where I have missed those teachable moments in the non-technical areas of my career. Though I don't have any women on my current team, I have worked with them in the past at other jobs. Though I have never done anything as egregious as what Alan describes, I hope that I have treated them with respect and dignity. I believe that I have. However, I am sure that I have also missed opportunities to help men around me be respectful, considerate, and just plain decent.

Though the original article was about sexual harassment, this is an issue that transcends gender. Sexual harassment is merely a single form of being a jerk. At my company, like many others, there are rules against being a jerk about certain taboo areas: gender, religion, age... We shouldn't be relying on corporate policy to define decency.

True confession time. I'm an ass. I hope that today I am less of an ass than I was ten years ago. But, truth be told, I still have some ass-like tendencies that pop up when I least expect them. I hate that.

Some of you know me well enough to know my beliefs. I am happy to say that I am a follower of Jesus Christ and that I have trust in Him alone to guide me through this life and the next. If my beliefs are to be consistent with my actions, then I must continue to fail forward in this area of how I treat those around me. To be consistent, I must treat everyone with respect and encourage others to do the same. To be consistent, I must be willing to admit when I am wrong (often). To be consistent, I must build other up rather than tearing them down. To be consistent, I must treat people like... people.

That brings me back to the original topic of this post. We must treat our female peers with the respect that they deserve, and we must insist that others do as well. Look around you. Are you standing up for others? Are you defending the sanctity of the lives around you? Where, dear reader, do you need to improve?

Saturday, January 31, 2009

When Collections Are Configuration - binding Collections in Guice

Classes that create their own internal domain objects and simple objects are typically not a problem for testability. The problem comes when classes are creating their own dependent services internally. Then, you've got a problem cutting the testing seams. Creating these dependent services is what Dependency Injection is best at. Using your IoC container to create everything constitutes container abuse.

However, I will use my IoC container of preference to create populated collections if the contents of those collections are inherently configuration. For instance, assume we have the following class:


public class Validator<T> {
private Collection<Validation<T>> validations;
private ValidationProblemReporter reporter;

public Validator(Collection<Validation<T>> validations,
ValidationProblemReporter reporter) {
this.validations = validations;
this.reporter = reporter;
}

public validate(Collection<T> elements) {
for(Validation<T> validation : validations) {
for(T elements : elements) {
if (!validation.isValid(element)) {
String m = element.toString() + " fails " + validation.toString();
reporter.reportProblem(m);
}
}
}
}
}


we frequently use a validation pattern that calls for a Collection<Validation<T>>. These validations vary from project to project, but the Validator<T> class is the same from project to project. The actual validations used varies depending on the validation requirements of the project and the type of the object that is being validated. Each instance of Validation<T> is pure business logic, and each is properly unit tested.

Determining what to put in the Collection<Validation<T>> is simply a configuration concern. This is where it is easy to use the IoC container. Since Guice is what I typically use, that's what I'll show.

Example: Say, we are dealing with Customer objects that we are importing into the system. These customers are being imported from someone else's system into ours. So, we are not sure if each customer object is valid and we only want to import the objects that are valid. There are multiple ways to bind up the collection of validations, among them are using TypeLiteral and using a marker class. For this, I will show the marker class, but I've also used TypeLiteral.

So, since I want to validate Customer, I create a class like:


public class CustomerValidations extends ArrayList<Validation<Customer>> {
//marker class
}


Now, I'll write a marker for the validator:


public class CustomerValidator extends Validator<Customer> {
@Inject
public CustomerValidator(CustomerValidations validations,
ValidationProblemReporter reporter) {
super(validations, reporter);
}
}


To get Guice to inject the dependencies into the CustomerValidator, we'll need to bind CustomerValidations and ValidationProblemReporter. So, I would have a Guice Module that looks something like:


public MyModule extends AbstractModule {
public void configure() {
bind(ValidationProblemReporter.class).to(ConsoleReporter.class);
bind(CustomerValidations.clas).to(CustomerValidationsProvider.class);
}
}


We'll have to write the provider for the CustomerValidations:


public class CustomerValidationsProvider implements Provider<CustomerValidations> {
public CustomerValidations get() {
validations = new CustomerValidations();
validations.add(new CustomerShouldHaveAName());
validations.add(new CustomerShouldHaveAnEmailAddress());
...

return validations;
}
}


This cuts a very nice seam to configure which validations we want to run over our customers. I can easily write a unit test that asserts what validations we have configured. In fact, if order is important, then I can check that as well.


public class CustomerValidationsTest {
@Test
public void we_should_do_the_right_things_in_the_right_order() {
CustomerValidationsProvider provider = new CustomerValidationsProvider();
CustomerValidations validations = provider.get();
Iterator<Validation<Customer>> iterator = validations.iterator();

assertEquals(CustomerShouldHaveAName.class, iterator.next().getClass());
assertEquals(CustomerShouldHaveAnEmailAddress.class, iterator.next().getClass());
assertFalse("Should not have any more", iterator.hasNext());
}
}


Now, we have locked down our configuration such that if we change the validations, we have to change this test. I wouldn't always lock the configuration like this, but I often do.

Guice allows you to unit test your configuration (since it's all Java). Figuring out what needs tested and what doesn't can be an art form. You'll get a better feel for it with experience.

Thursday, January 22, 2009

Hudson Default Ant

Most Hudson configuration is self-explanatory and easy to find in the web configuration. Many props go to the developers of Hudson because it is quite easy to setup and use. However, there are a couple of things that I've found lately that don't seem to be documented in the Hudson docs.

Configuring Ant


From the Hudson dashboard, click on
  Manage Hudson -> Configure System
or you can simply navigate to
  http://your-server-here/hudson/configure

Look for the section labeled "Ant" and add your Ant installations by clicking "Add" and providing a name and the absolute path for ANT_HOME. This couldn't be simpler.

Default Ant


When you are configuring a build, you can tell Hudson which Ant you want to use. You may either use one of the named Ant installations that you previously added, or Hudson gives you the option of using the "Default Ant."

For some reason, I was thinking that I had somehow set the only Ant installation that I added as the default (since it was indeed the only one). But, this was not the case, and my build failed with this console output:

FATAL: command execution failed.Maybe you need to configure the job to choose one of your Ant installations?
java.io.IOException: Cannot run program "ant" (in directory "/home/tomcat/hudson/jobs//workspace/build")


Then, I got to looking at how to set the default Ant, and I could not for the life of me find the setting anywhere. This is because, there is NO default that can be changed from within Hudson.

If you tell Hudson to use the default Ant for a build, then it will use whatever ant it finds on the PATH. Note that I did not say that Hudson will use whatever ANT_HOME points to. Hudson must be able to find the ant command on the PATH.

In our case, Hudson runs as the user 'tomcat.'

So, if I wanted to use the default Ant for a build, I would typically solve this by setting both the ANT_HOME and PATH environment variables for the tomcat user. I would set ANT_HOME to the Ant installation that I wish to use as default, and I would then add $ANT_HOME/bin to the PATH environment variable.

What I Actually Did


Since I really didn't care to go to all that trouble of setting environment variables, I just used the named Ant instance that I had already configured in Hudson. We do not have a default Ant available to Hudson, and it's not a problem.

Wednesday, January 21, 2009

Hudson Gets an AccessControlException when starting on Ubuntu Tomcat

With fresh install of Ubuntu 8.10 I grabbed Tomcat 6 from Synaptic. Then, I dropped the hudson.war into the Tomcat webapps directory, and was greeted with an AccessControlException and a Hudson that would not start.

This is because on Ubuntu, Tomcat default installs with the Tomcat Security Manager enabled. This is probably a good thing for many installs of Tomcat, but it interferes with Hudson. When we finally found the problem, we took the lazy road and disabled the Tomcat Security. Depending on your install, this may be an unsafe decision. I would check the Tomcat documentation before doing this if your server is externally exposed. In our environment, the build server is on a completely trusted network. So, we didn't care much.

Here is the stack trace that is displayed when first trying to browse to the Hudson app:


HTTP Status 500 -

type Exception report

message

description The server encountered an internal error () that prevented it from fulfilling this request.

exception

javax.servlet.ServletException: Error instantiating servlet class org.kohsuke.stapler.Stapler
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:433)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
java.lang.Thread.run(Thread.java:636)

root cause

java.lang.ExceptionInInitializerError
org.apache.commons.beanutils.ConvertUtilsBean.(ConvertUtilsBean.java:130)
org.kohsuke.stapler.Stapler.(Stapler.java:659)
sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
java.lang.reflect.Constructor.newInstance(Constructor.java:532)
java.lang.Class.newInstance0(Class.java:372)
java.lang.Class.newInstance(Class.java:325)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:433)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
java.lang.Thread.run(Thread.java:636)

root cause

java.security.AccessControlException: access denied (java.util.PropertyPermission org.apache.commons.logging.LogFactory.HashtableImpl read)
java.security.AccessControlContext.checkPermission(AccessControlContext.java:342)
java.security.AccessController.checkPermission(AccessController.java:553)
java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
java.lang.SecurityManager.checkPropertyAccess(SecurityManager.java:1302)
java.lang.System.getProperty(System.java:669)
org.apache.commons.logging.LogFactory.createFactoryStore(LogFactory.java:320)
org.apache.commons.logging.LogFactory.(LogFactory.java:1725)
org.apache.commons.beanutils.ConvertUtilsBean.(ConvertUtilsBean.java:130)
org.kohsuke.stapler.Stapler.(Stapler.java:659)
sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
java.lang.reflect.Constructor.newInstance(Constructor.java:532)
java.lang.Class.newInstance0(Class.java:372)
java.lang.Class.newInstance(Class.java:325)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:433)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
java.lang.Thread.run(Thread.java:636)

note The full stack trace of the root cause is available in the Apache Tomcat/6.0.18 logs.



This was fixed by changing:

/etc/default/tomcat6


And setting the following property:

# Use the Java security manager? (yes/no, default: yes)
# WARNING: Do not disable the security manager unless you understand
# the consequences!
#TOMCAT6_SECURITY=yes
TOMCAT6_SECURITY=no


Note that we left the commented example in place for future reference. I hope this helps someone else. Mostly, I'm hoping that by writing this down, I will remember this in the future or at least be able to find the solution quicker.

Go forth and write tests...

Wednesday, January 14, 2009

Cool Code Snippet Tool

Simple post for my own memory:

The best online code snippet posting tool that I've found is at http://pastebin.com/. It has great syntax highlighting for a variety of languages (including Groovy) and it is very easy to use.

Wednesday, January 7, 2009

Tests Drive Good Design

Test-first development leads to better design in the production code. Specifically, you get much lower coupling (both internally and externally), and you get much higher cohesion.

For those of you unfamiliar with those two terms, Coupling is tying one class to another. For instance, if ClassA relies on ClassB to do some work in such a way that a break in ClassB causes unit tests for ClassA to break, that's coupling. We try to limit coupling so that individual classes are isolated. We will always be coupling our classes to a degre (if java.lang.String breaks, everything breaks), but we try to keep it to a minimum. We want classes with low coupling because it is easier to isolate change.

Cohesion is how well the responsibilities within a class relate to each other. Highly cohesive classes tend to be small chunks that are easy to understand because they have a single responsibility. If you are tempted to answer the question, "What does this class do?" by using the word "and" a bunch, then you have a class with low cohesion. We want classes with high cohesion because they are easier to understand and thus easier to change.

When you write good unit tests, especially when you write them first, its easy to detect classes that are NOT highly cohesive and have low coupling. Tests become much more difficult to write when you stray from sound coding practices. If you weren't writing unit tests, you might be tempted to simply "new up" a dependency. Testing drives one to inject dependencies to create better seams and better class isolation.

The bottom line is that testable code is better code. It is easier to change, easier to understand, and overall easier to support.

Tuesday, December 16, 2008

Private Bindings in Guice

There are rare occasions when I need to bind something locally in Guice, but I don't want that binding exposed. One such time happened today. Our application uses a Configuration object to hold what we read in from a configuration file. There is plenty of configuration in that file including database connection information and email configuration for reporting errors. Various parts of the application need various parts of the configuration, but nothing really needs the whole ball of wax.

There is, however, one exception to this in our application where a Guice Provider actually does need to have the whole Configuration object. So, we need to have a singleton Configuration instance bound, but I still don't want that exposed.

Enter annotated bindings. Guice allows you to bind the same type more than once and to distinguish the different bindings by adding an annotation. The annotation gets added to the binding in the module as well as the location where the injection is to occur. So, in this case, we have a binding and Provider like so:


bind(Configuration.class).annotatedWith(DontExpose.class).toInstance(privateConfig);
bind(Foo.class).toProvider(FooProvider.class);

private static class FooProvider implements Provider {
public FooProvider(@DontExpose Configuration config) {
...
}
}


The binding is placed in the configure() method of the Guide Module, and the FooProvider is a private static within the same Guice Module class. Unless you take one extra step, however, this binding is still exposed.


Normally, my binding annotations are publicly defined within the project. Any class that Guice builds can ask for a Configuration annotated with @DontExpose. To keep that from happening, we simply define the @DontExpose binding annotation as a private element within the Guice Module. So, the final module would look something like this:


import com.google.inject.*;
import java.lang.annotation.*;
import org.apache.commons.configuration.*;

public class TestModuleShouldBeDeleted extends AbstractModule {

private final CompositeConfiguration config;

public TestModuleShouldBeDeleted(CompositeConfiguration config) {
this.config = config;
}

@Override
protected void configure() {
bind(Configuration.class).annotatedWith(DontExpose.class).toInstance(config);
bind(Foo.class).toProvider(FooProvider.class);
}

@Retention(RetentionPolicy.RUNTIME)
@Target( { ElementType.FIELD, ElementType.PARAMETER })
@BindingAnnotation
private @interface DontExpose {
// marker annotation
}

private static class FooProvider implements Provider {

private final Configuration configuration;

@Inject
public FooProvider(@DontExpose
Configuration configuration) {
this.configuration = configuration;
}

@Override
public Foo get() {
return new Foo(configuration.getString("foo.value"));
}
}
}


Now, the binding to Foo is exposed (as we want it to be), but the binding to the Configuration is not. This isn't a pattern I use very often, but it was useful today.

Monday, December 15, 2008

Why I Don't Use "Given, When, Then"

In Introducing BDD, Dan North states that he and Chris Matts were trying to develop a template that, "had to be loose enough that it wouldn’t feel artificial or constraining to analysts but structured enough that we could break the story into its constituent fragments and automate them." This gave birth to Given, When, Then syntax. One example that is given in the article is:

Given the account is in credit
And the card is valid
And the dispenser contains cash
When the customer requests cash
Then ensure the account is debited
And ensure cash is dispensed
And ensure the card is returned

This certainly has structure. But, I personally feel this is still a bit too artificial. Perhaps it is the large amount of content related to the context (account is in credit, the card is valid, the dispenser contains cash). I try to avoid specifying behaviors that have this many moving parts. I would prefer to see a behavior like:

The dispenser when the account is in credit should dispense cash.
The dispenser when the account is in credit should debit the account.
The dispenser when all transactions are complete should ensure the card is returned

I want to read sentences. When possible, I want to read short sentences. Given When Then generates a matrix of sentences to be parsed. GWT also saves some space in the report, but I gladly give that space back to have behavioral sentences that are easier to read quickly.

So, how do I keep the language regular and well-formed? The answer shows up more in the source code of the behvaiors than in the report. So, I might write the following behavior using EasySpec (in Groovy):


@EasySpec(interest='The dispenser')
class Dispenser_happy_path_Test extends GroovyTestCase() {

def account = new Account(balance:1000)
def dispenser = new Dispenser(available:5000)

@Context('when the account is in credit and the dispenser has cash')
public void setUp() {
dispenser.dispense(account, 100)
}

@Behavior
void test_should_debit_the_account() {
assertEquals(900, account.balance)
}

@Behavior
void test_should_dispense_the_requested_cash() {
assertEquals(100, dispenser.totalDespensed)
assertEquals(4900, dispenser.available)
}

@Behavior
void test_should_return_the_card() {
assertTrue(dispenser.lastCardReturned)
}
}

Upon running the EasySpec report, the user will get the following behaviors:


The dispenser when the account is in credit and the dispenser has cash should debit the account

The dispenser when the account is in credit and the dispenser has cash should dispense the requested cash

The dispenser when the account is in credit and the dispenser has cash should return the card


Easy Spec actually generates reports with nice formatting like this.

Perhaps all of this is just personal preference. But, I do find it easy to go back to old specifications and understand what is going on. Language and fluency are important.

You Might Be A Behaviorist...

Are you doing BDD? This is a question I've often heard at recent conferences. As far as I can tell, most people that have looked at BDD concepts are quite sure if they're doing BDD or not. Here are some sign that you might be a Behaviorist:

  1. You talk more about executable specifications and less about "tests."
  2. You write your specifications before you write the production code.
  3. You place high value on natural language in your tests.
  4. You can generate a system-wide report that shows system behaviors in natural language. Bonus points if you do this with every build.
  5. You write your specifications or tests with exactly one context per test class.
Not everyone that is doing these things would classify their projects as using BDD. And, not everyone that says they're using BDD is applying these concepts. But, I think that in the majority of cases you will find a majority of these practices in some form or another.

If I have missed anything, Dear Reader, please let me know.

My English Teacher Would Be Proud -- Proper Language Is Still Important

My high school had one English teacher that was dreaded by all, Mrs. Koch. Mrs. Koch's classes were known to be tough. Most of my friends were accustomed to getting high grades, but this didn't happen too often in Mrs. Koch's classes. Over the course of two semesters, one student got an 'A' in one semester. Mrs. Koch took for granted that we knew the basics that we were supposed to know. For written assignments, she assumed that everything would be spelled correctly and there would be zero grammatical errors. Assignments were graded for content, but grammatical errors caused sever markdowns in one's grade. Language was important.

I am thankful to Mrs. Koch for nurturing a strong sense of grammar in me. Perhaps this is what I have always liked the strict syntax of programming languages. This may also explain why I like Behavior Driven Development so much. Language was critical in Mrs. Koch's class, and language is critical to understanding business software.

BDD brings language into what I believe is its proper place -- the forefront. Language allows developers to understand the business. Language allows the development team to communicate with the project sponsors and domain experts. The more prominent, clear, and accessible our language is, the more readily we understand each other. The more accessible the language is in the code base, the easier it is to understand what we are doing and why we are doing it.

This is why I like BDD so much. When I read through specifications, I can understand what the system does. The more natural the language is, the faster I can stop thinking about syntax and start thinking about the correctness of the system. Natural language also helps to engage the non-developers on the team. While I've watched our project managers look at Java code and guess about what the system is doing, its much easier for us to have a conversation without Java language constructs getting in the way. Likewise, the less we talk about exceptions, try/catch blocks, and if-else statements, the better. Instead, we prefer discussing how the system should and should not behave under certain conditions.

Case in point: Instead of, "The protected area should thrown an exception for unauthenticated users," I would prefer to say, "The protected page should require the user to be logged in." We shouldn't have to acclimate the business types to programmer speak.

Clear language also helps us identity when the design is going astray. One simple word is often a clue to me that a class has too much responsibility. That magic word is, "and." Here's an example:

Lets assume that we're developing a console application that takes in a relatively complex configuration file. The customer has told us that, when the configuration is bad, he wants to be notified in a variety of ways. Sometimes this process will be run manually, and he would like the operator to receive immediate console output for bad configuration. Sometimes, the process is launched automatically and unattended, so he would like configuration problems to be emailed as well. For a final good measure, he has also requested that problems be logged to the logging system we have chosen for the project. We'll assume that the logging and email services live behind a nice interface that is easy to test. We might, then, get a specification that looks like this

The ConfigurationHandler, when some configuration properties are missing and logging is configured and email is configured should log an error for the missing properties and send an email for the error and write an error message to the console.

Assuming that our logging and email systems are properly testable (injected somehow), the actual calls to those services could be a pretty small footprint in the production code. However, this is too much responsibility for the ConfigurationHandler. We see it logging, sending email, printing to the console and killing the process somehow. There are lots of "ands" in the specification indicating that perhaps too much responsibility has been given to the ConfigurationHandler.

If we look at the behaviors shown, they are all about reporting the error. This is when we notice that, perhaps what we need is one more concept called the ErrorService. We can hide all the emailing and logging behind that. So, we break out a new class and a new interface and we end up with the following specifications:

The Configuration Handler, when some configuration properties are missing should report the missing properties to the ErrorService.

The ErrorService should forward errors to the log file, email, and console.


There are still some "and's" there, but the responsibilities are better broken down.

Language is critical to understanding software. BDD helps bring language into more prominence. What does the language of your specifications tell you?

Package Properly: Where Your Tests Live Is Important

About nine months ago, our team decided to start using Behavior Driven Design. Rather than making big changes in the build system to bring in a BDD framework, I put together a BDD reporting framework called EasySpec that allowed us to continue to leverage JUnit. One of our goals in trying BDD was to really push the limits of natural language in testing and determine what the limits were for BDD. We ran into limits with our mocking framework, but Mockito solved those problems for us (more on that in a future post).

One thing that we found was that BDD works pretty well for all levels of testing. Many of the BDD practitioners will only use BDD for higher level integration testing. However, I've found that I really like it for unit-level testing as well. Language is important regardless of where. It is certainly nice to understand system behavior in the large, but as a developer I need to understand behavior in the small as well.

We package our unit-level tests in a test source tree that parallels the production code source tree. So, if I am spec'ing out the com.company.foo.NewFoo, then the production source lives in myProject/src/com/company/foo/NewFoo.java and the first spec will end up in myProject/test/com/company/foo/NewFoo_when_X_Test.java.

One unintended advantage of staying with JUnit and EasySpec was that our new BDD tests landed right next to the old JUnit tests. The subconscious communication that this packaging created was wonderful. It removes the step of questioning where the next test or spec should live. The next spec goes into the parallel package. This also communicates that we are going to be driving the same requirements with BDD that we drove previously using TDD methods. In other words, we aren't just writing larger integration tests with BDD. We are writing as much as possible using BDD because again, langauge is paramount to understanding the system.

How do you package your specs? And, have you pushed the limits to find out how low-level you can drive BDD concepts into your design? I love designing in the small with BDD. My production code is better, and the specification artifacts are wonderful. When supporting code writting six months ago, I find it much easier to understand the system if we have EasySpec specifications rather than JUnit tests -- regardless of the level of abstraction under test.

Thursday, December 11, 2008

Publishing Build Artifacts With Hudson

Tonight, I found yet another reason to love the Hudson continuous integration server. Publishing build artifacts is way easy. What's better, the latest artifacts are available under a static link. So, it's easy to set a bookmark and always have the latest output available without digging through the server.

I've setup publicly visible builds for EasySpec along with the Groovy example and Java example projects. All of these projects use EasySpec for Behavior Driven Design. A major component of BDD is having the latest behavior report available. So, I have included a build target named "report" in each of these projects. This target simply runs EasySpec to generate the behavior report into a known location in the workspace.

Let's take the Groovy example and walk through it. After every checkin, the Hudson build does

gant clean test report

This cleans the working copy, then compiles everything, runs the tests, and finally generated the EasySpec report. Relative to the working copy base, the report ends up in build_output/reports/EasySpec/index.html

To publish this report, only a couple of simple steps are required. First, go to the project configuration page for the build that you wish to publish artifacts from. In this case, that's Hudson/GroovyExample/Configure. Then, find the checkbox, "Post-build Actions / Archive the artifacts" Enter the relative path of the artifacts that you wish to publish. In this case, that's "
build_output/reports/EasySpec/index.html" Click "Save" and it's all done.

Now, everytime this project builds successfully, the latest EasySpec report is published to a constant URL. If you want, checkout the latest example EasySpec report.

I love Hudson

Sunday, November 30, 2008

EasySpec Continuous Integration Server Visible

I have made available a Hudson build for EasySpec. This turned out to be a fun exercise in setting up Hudson to build a GoogleCode project and a Gant project all in one. The Hudson plug-ins for GoogleCode and Gant both helped a great deal.

URL: hudson.testinfected.net

Hudson and .Net

Hudson has to be the easiest CI server I've ever worked with. And, based on the number of plug-ins and the rate at which plug-ins are being developed, it must have a pretty easy plug-in model. Apparently, the gant plug-in took about an hour to write.

Configuration is very easy as well. I don't believe I've ever had to dig into the actual configuration files for different builds and tasks. The web front-end for configuration is great. I also like the ability to watch the console during a build and all of the build status tracking and archiving. There are MANY more great plug-ins available, many of which would be applicable to .Net projects as well as Java projects.

Although I'm not doing much .Net development right now, if I was, I would probably be tempted to setup a Hudson CI server to see if I liked it better than CC.Net. For those readers that are interested in seeing more about using Hudson with .Net, Redsolo has a pretty comprehensive guide to getting started.

Check it out.

Thursday, August 28, 2008

GMail + Address - Why Duplicated Logic Is Still A Bad Idea

If you use GMail, you probably already know that you have an infinite number of addresses with a single account. You can add periods wherever you like in the address. You can also add tags to the address using the '+' symbol. So, foobar@gmail.com, foo.bar@gmail.com, fo.obar+baz@gmail.com all go to the same place.

I like using the '+' tags when giving out my email to automated systems and signups. This makes it easy to determine if someone is handing out my address for spam when I haven't agreed to that.

Here's the duplicated logic part:

So, a while back I activated a subscription for MSDN. I used my.address+msdn@gmail.com for the email address. Today, I needeed to download something, and I went to login again, and the system is behaving like I don't remember the password. This is possible, but unlikely since the passwords that I tend to use (1) I remember, and (2) fit most all password schemes. However, I conceded that, perhaps, I don't remember the password. When I go to enter the email address for password retrieval, I get a validation error stating that the email address that I entered is malformed. Funny, MSDN didn't have any trouble sending the email to that address. I tried with the +msdn, and of course, that yielded a validation error stating that the email address was not in the system.

And, yes, I did go back to the confirmation email, and they DID send it to the ...+msdn@gmail.com address. So, that is, in fact, the address that I registered with.

It's obvious what's going on here. The registration site gleefully accepted an email address that the password retrieval site refuses to accept as a well-formed address. The logic for what constitutes an email address has been duplicated. Perhaps at some point they were the same. The registration site may have been "enhanced" to allow the '+' addresses, or perhaps the lost password site was "fixed" to only allow certain formats of email address. Regardless, it now rests as one system with different rules for what is and is not valid.

Furthermore, this leads me to suspect that the login site actually shares the same rules with the lost password site. Meaning, I was able to register with an email address that I cannot login with.

Looks like I'll have to talk with a human to get this sorted out tomorrow. Figures that I would find it thirty minutes after everyone goes home.

Saturday, June 28, 2008

How Well Do You Know Your Tool?

Have you ever used a great tool? I've been doing some woodworking lately. So, I've been thinking a bunch about tools. There is nothing like having a good tool when you need it. Among tradesmen, tools (and tool brands) can evoke a great deal of passion. You may have know a "DeWalt guy" or a "Matco" lover.

My grandfather was a very skilled woodworker. He took a great deal of pride in crafting fine pieces of furniture that were beautifully finished. My grandfather was a Craftsman guy. Even when offered more expensive tools, he preferred to work with Craftsman. Perhaps the source of his passion was the good service he got from the local Sears, or perhaps it was because the tools had never let him down. Regardless of why, he was passionate about his tools.

Software development tools are no different. One need look no further than the vi / emacs wars fought at countless water coolers (to this day) to see the passion that one can have in a development tool. In Java-land, you may be an Eclipse or IntelliJ devotee. In .Net, you may insist on running ReSharper or CodeRush. All of this passion is useless without one critical component...

How well do you know your IDE? When was the last time that you looked through the feature shortcuts? When was the last time that you looked through release notes for new versions? What about learning keyboard shortcuts?

I primarily learn new features two ways. I pick up tricks from my teammates when pair programming. Sometimes, I learn things completely by accident. Every once in a while, I fat-finger a keyboard shortcut, and something really cool happens. Typically, it's not a feature that I want at the time, but it's new to me. To help me remember it, I will practice it a few times, and share the new information with the rest of the team.

Take some time and read up on your IDE. Good tools are useless if you swing everything like a hammer.

Wednesday, June 11, 2008

Running Fitnesse Tests

It is possible to execute a FitNesse page as a test, even when it is not marked as a test. This is a good thing. Say that you have a page that resides at:

http://localhost:8181/MySuite.MyTest

You can simply execute that test by appending "?test" to the end of the URL. Likewise, you can execute the page as a suite by placing "?suite" at the end of the URL.

In our project, we have some pages that are common to all tests. In order to prevent those pages being executed as tests, we changed the page property to indicate that they are not tests. However, it is occasionally useful to execute those pages by themselves for debugging purposes. Rather than going through the annoyance of setting the "Test" property and hoping that I remember to clear it, I can just append the magic text to the end of the URL, and I'm off to the races.

Friday, May 30, 2008

Agile Austin Open Space

The Agile Austin Open Space kicks off this evening with agenda and topic setting. You can find the proceedings documented on the wiki at: openspace.agileaustin.org

I will be blogging about proceedings as I see things interesting. Be sure to watch the wiki.

Wednesday, May 28, 2008

Why Behavior Driven Development?

Two years ago, I became completely test-infected. I hate writing implementation code without writing the test first. Then, about six months ago, I was introduced to Behavior Driven Development (BDD). I liked what I saw, but I really didn't see any tools that I wanted to bring into our build system. The last thing that I wanted to introduce to the company was another test framework. JUnit was meeting our needs fairly well, and we were already using FitNesse on our team whereas the rest of the company was not. We didn't want to add another tool on top of that.

Then, a few months ago, I saw Scott Bellware give a talk on BDD and saw how he simply did BDD within a normal unit-testing framework and used .Net attributes to markup the tests with the BDD language. I liked what I saw. That night, I started a similar tool for JUnit called EasySpec. The tool still has some kinks to work out, but BDD has definitely brought some interesting insights into how we design our tests.

So, why BDD? At first, it was simply a trial of a style that seemed to do a good job of pulling out the Ubiquitous Language. Now that we have been using the techniques for about three months, I must say that I really like using BDD for creating software -- especially around the Domain Model.

BDD cleans up the language and gets the developers talking more about behaviors and less about implementation. Where, in the past, I might have been tempted to write a test with a method name like, "the_service_should_throw_an_exception_if_the_user_is_not_authenticated," I would now write that same test with a name like, "the_service_should_require_authenticated_users." Internally, the test would still be implemented in the same fashion, with probably the same code. However, language is important. It's important for the developers to think in the domain rather than hiding in the implementation layer. If I'm interested in the details of how the service requires authenticated users, then I can look at the details of the test (which should still be cleanly written) and see that in fact, the service will throw an exception if it somehow is handed an unauthenticated user.

This is merely one example. Keep a watch here for more information about BDD and why I'm hooked. Also, I should be putting some polish into EasySpec in the next week or two so that it's more user-friendly. If you're already using JUnit, and you want to try out BDD, take a look at EasySpec.