Dear Maven

I know we’ve always had a rocky relationship, but the fight we had yesterday was the last straw.

Let’s face it, this just isn’t working. I wish I could say it’s me, but it’s really you. I’ve tried and tried to make you happy, but in the end, it has just made me unhappy.

Look, you really are amazing. The things you know and the things you can do–damn! But, when we disagree, it is awful. When it happens, it makes me wonder why we are together.

So, we should break up. I can use the space and time to catch up with old friends, to do things that I used to do before I met you.

Maybe we’ll cross paths again in the future, but for now, we should go our separate ways.

Ask

When I first started programming, I made it a point to investigate to the limit of my understanding before asking a question. Once I reached that limit, I’d go ask somebody. This served me well because I learned on my own, and didn’t feel guilty about “wasting” somebody else’s time.

As I became more senior, the knowledge I acquired by investigation and asking meant that I became a person providing answers to questions. In fact, there are times when that is all that I do–so much so that I sometimes I forget that I can ask questions. Nowadays, (in the worst case) I’ll flail for a while making progress, but at too slow of a pace. Then, I’ll either eventually figure it out or eventually realize I need to ask some questions. Either way, it isn’t the most efficient use of my time.

I need to remember as I progress, it is still OK to ask questions. I can’t always know all of the answers and, in some cases, figuring out the answer does not have a good return on the time invested.

Engineering NOT Tool Selection

When I was in the the seventh grade, my industrial arts teacher, Mr. McQueen, gave his definition of engineering:

Using what you have to get what you need

That definition has always stuck with me. I find it to be the simplest, most straight-forward definition of what an engineer does. Admittedly, it is vague. But, I think it is vague in a good way. It doesn’t overspecify, it just gives us a conceptual framework.

How does this tie into what we sometimes call software engineering? Most of the time, we are trying to solve some problem (to get what we want) with software (which we already have or will have).

Ideally, we have an idea of what we want. But, in reality, that’s rarely the case. Much of software development is discovering what is actually needed. An easy way to do this is to have some software, let the users work with it, get their feedback, make changes, and repeat.

This is where many organizations go astray. Rather than doing software work (engineering) themselves, many organizations decide to buy a tool. On the surface, this isn’t a bad a idea–why reinvent the wheel? But, in order for a tool to solve a problem, we have to fully understand the problem.

And, this is where the title of the post comes from. If there is a piece of software that solves the problem, it would be unprofessional to propose creating our own. However, it is also unprofessional to propose using a tool when we do not know enough about the problem. Without the engineering exercise, we are going to have a tougher time selecting a tool.

In the end, even if we think it is possible to use a tool to get what we want, it is worth while to do some engineering.

Unit Testing Guidlines

Recently I was asked to draw ups some guidelines regarding Unit Testing. I was hoping to find something that I could point people to, but I didn’t find any one listing that I liked. So, I’ve drawn up my own Unit Testing Guidelines / Commandments / Rules Of Thumb / Principles / Heuristics / Best Practices / Whathaveyous:

Tests should be written first

Let the test help direct the design
Make the code easy to test

Each test must be independent of other tests

Running tests in isolation provide faster feedback and makes testing easier
Junit assumes that tests can be run arbitrary order
Depending on other tests indicates tightly coupled code

Tests should not be dependent upon upon production code to be tested

For example, don’t use your dao to insert data for testing
Failing to do so requires proving that the dao works, which then creates a dependency on another test

Tests should demonstrate behavior for expected and unexpected behavior

Tests serve as documentation for the happy path and the sad path

Red, Green, Refactor

This is where we remove duplication, simplify, and in general make things better
Applies to the test code as well

Each class merits its own test class

Applies to “simple” classes, too
Not only is it a test, it is documentation for the future

Organize test methods in three chunks arrange, act, assert

This makes your intent much easier to understand

Isolate layers

You shouldn’t need a database connection to test a class that doesn’t directly use the database
Mocks, Stubs, and Dependency Injection are your friends

Each test method should test one thing

This makes your intent much easier to understand
This makes it easier to understand what is and isn’t working
Ideally it would have one assert

Prefer naming conventions that describe the scenario and outcome

One example is methodName_Scenario_Outcome
Use the language of the domain

Know what you are testing and how to test it

Prefer state-based testing for checking return values and outcomes
Prefer behavior-based testing for testing interactions

Keep tests as quiet as possible

Avoid printing out statements, logging, etc.
Your tests should only be vocal when something interesting (usually bad) happens

Tests should be as small and as fast as possible

Do one thing, do it fast
Fast feedback is the name of the game

Tests should be run regularly

In the very least, every time there is a code change
Automate it
Get notifications if tests are failing

Fix tests ASAP

Even if you aren’t the on who created the issue

Write tests to reproduce bugs

Use this to guide fixing code.

Obviously, this isn’t the alpha and the omega of unit test practices, but I think it captures most of what’s critical.

The following links were influential (but not the only influence) for this list.
http://exubero.com/junit/antipatterns.html
http://geosoft.no/development/unittesting.html
http://stackoverflow.com/questions/106800/unit-testing-guidelines
http://blog.jayfields.com/2005/11/unit-test-guidelines.html
http://developer.apple.com/library/mac/#documentation/DeveloperTools/Conceptual/UnitTesting/1-Articles/UTGuidelines.html No Longer Valid
http://pragprog.com/the-pragmatic-programmer/extracts/software-entropy
http://www.robertbeal.com/145/thoughts-about-unit-testing-private-methods-and-100-coverage
http://martinfowler.com/articles/mocksArentStubs.html

Remember Who Is In Control

We are. Not the computer, not the software.

If a piece of software doesn’t behave the way we’d like, if it doesn’t complete the desired task, it is broken. Acknowledge that is broken, acknowledge that we performing work arounds, then fix it.

To do anything else is to relinquish control. We become slaves to a master that doesn’t even know we exist. If that happens, nothing gets better.

Remember, we are in control.

Don’t Program In The Database

On a particular project many moons ago, I was tasked with creating a reporting system for a small number of retail stores. It was bunch of stuff about inventory, sales, and the like. Something that has been done a million times. And, unfortunately, will be done a million times more.

As this was one of my first programming jobs using the Java/J2EE stack, I tended to stick with what I knew. Or, maybe it is better to say I stuck with what I knew would work. In this case, it was the database. The bulk of creating a report was done in the database with some rather huge and gnarly queries. The queries did their jobs, I took the results pushed them up a layer (a *very* thin layer) for processing, and then presented the data to the user.

Things went well. I even did that new-fangled thing called “refactoring” on the processing layer. I created some very broad and generalized code for taking results from the database and putting them in a UI. Look at how awesome I am!

Then, of course, things went to Hell. The users wanted more information in their reports that couldn’t easily be obtained by modifying the aforementioned gnarly queries. I couldn’t capitalize on the processing layer simply because there really wasn’t much of one. And, the one that was there was uber-coupled to how results were pulled from the database.

After much investigation, I determined that the modifications were really going to have be rewrites. I just couldn’t justify “making it work” when I knew there was eventually going to be yet another round of changes. I needed to split the responsibilities of the processing and the database appropriately. It was going to be work.

Luckily, the customers were OK with the rewrite. I laid out all the mistakes I had made, and what I really needed to do, and they said “Do it.” I was lucky to be working with these folks. Otherwise, this would be a story about losing a job.

In the end, I did the rewrite. I am not going to claim that the rewrite was the end-all, be-all for what we needed. But, it worked. It handled changes over a couple of years, and there was only that single rewrite.

The pain I experienced taught me a lot about layering and how to think about using databases. If there was one thing I took away from the experience, it was this: don’t program in the database!

Playing With Jetty

I’ve been meaning to play with Jetty for years. I first learned of its existence when mucking around with Selenium about 5 years ago. But, I never got around to it. I knew it was (in the least) a light weight servlet container that had a quick start up time and an API that made it easy to work with programmatically.

This is intriguing because it gives us the chance to quickly get timely feedback without a servlet container up and running. We’ll just fire it up and use it if we need it! We can actually do testing at the ‘acceptance’ level as part of a continuous integration set up without having to do an actual deployment.

To get started, we are going to need a few things:

From GlassFish:

javax.servlet.jar

From Jetty:

javax.el_[version].jar
javax.servlet.jsp_[version].jar
jetty-continuation-[version].jar
jetty-http-[version].jar
jetty-io-[version].jar
jetty-security-[version].jar
jetty[version]-server-[version].jar
jetty-servlet-[version].jar
jetty-util-[version].jar
jetty-webapp-[version].jar
jetty-xml-[version].jar
org.apache.jasper.glassfish_[version].jar

You will also need Ant:

ant.jar
ant-launcher.jar

The javax.servlet.jar is found in the glassfish/modules directory. With these jars on our classpath, we can then create a simple class to run a toy app:

package com.bitmotif.jetty.examples;

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.webapp.WebAppContext;

/**
 * Created by IntelliJ IDEA.
 * User: pjberry
 * Date: 2/24/11
 * Time: 7:51 AM
 */
public class HelloWorld
{
    public static void main(String[] args) throws Exception {
        HelloWorld helloWorld = new HelloWorld();
        helloWorld.run();
    }

    private void run() throws Exception {
        Server server = buildServer( buildWebAppContext() );
        server.start();
        server.join();
    }

    private Server buildServer(WebAppContext webApp) {
        Server server = new Server(8080);
        server.setHandler(webApp);
        return server;
    }

    private WebAppContext buildWebAppContext() {
        WebAppContext webApp = new WebAppContext();
        webApp.setContextPath("/");
        webApp.setResourceBase("./jetty-examples/src/main/webapp");
        webApp.setAttribute("stringRecptale", new StringReceptacle());
        return webApp;
    }
}

In the above, we set the “stringReceptacle” attribute to a new StringReceptacle. We’ll refer to this attribute in a JSP to verify the basic functionality is working. The code for StringReceptacle:

package com.bitmotif.jetty.examples;

/**
 * Created by IntelliJ IDEA.
 * User: pjberry
 * Date: 3/1/11
 * Time: 7:12 AM
 */
public class StringReceptacle {

    private String string = "The Default String";

    public String getString() {
        return string;
    }

}

Our JSP looks like:

<%--
  Created by IntelliJ IDEA.
  User: pjberry
  Date: 2/27/11
  Time: 8:29 AM
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<h1>From The JSP</h1>

<h2><%="Hello"%> ${"World"}</h2>

And, here is what StringReceptacle says: "${stringRecptale.string}"
</body>
</html>

Last, but not least we need to have our web.xml set up.

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
         version="2.4">

  <display-name>Jetty JSP unit test simple example</display-name>

  <!-- Welcome files -->
  <welcome-file-list>
      <welcome-file>hello-world.jsp</welcome-file>
  </welcome-file-list>
</web-app>

Bringing it all together, my project structure looks like:

___src
|____main
| |____java
| | |____com
| | | |____bitmotif
| | | | |____jetty
| | | | | |____examples
| | | | | | |____HelloWorld.java
| | | | | | |____StringReceptacle.java
| |____webapp
| | |____hello-world.jsp
| | |____WEB-INF
| | | |____web.xml

With everything in its place, we can run the main method in HelloWorld. Then, we point our browser to http://localhost:8080. We should see something like below:

And, that’s pretty much it. We have the beginnings of a sandbox to test out a number of things (which will be the subjects of future posts).

The following links were a lot of help in figuring out what was need.

Setting a Web Application Context
Tip: Enabling JSP support in Jetty.7.0.0
How to Reference and Use JSTL in your Web Application
Tutorial: How to set up Tomcat 6 to work with JSTL 1.2

Extra special thanks to genthaler’s JSP example code.

Fail Fast

For the last two months I have been on a project where I’ve violated a number of core development principles. Right now, I want to talk about one of those principles. (The others could be their own post or series of posts).

FAIL-FAST

When people talk about failing fast, they are usually talking about it in the context of an application’s runtime. Instead of letting something bad continue, end it. Rather than propagating errors, fail as fast as possible so we can recover as fast as possible.

Another context in which fail-fast is applicable is in the notion of development progress. That’s what I am going to talk about. You see, on this particular project I made the code, well, err, more forgiving than I normally would. I did this so I could get feed back on some other aspects of the code and to make what should have been only throw-away code “work”.

You can probably see where I am going with this. Because things “worked”, there was the illusion of a mostly-finished application. I am not going to lie—even I started to believe it. So, when I tried to explain that something wasn’t finished, or a fix for something would take X amount of effort, it didn’t register with the non-technical people. It looked like we were pretty much done.

I realized I did my customer and myself a disservice. An impression had been made. The code looked like it was almost done. If I had stuck with a fail-fast mindset, I would have had feedback for the customer to understand where we are. And, I would have the failures as a guide for what the next development steps should be.

Sometimes, a spectacular failure is what’s needed.

The New Year

For 2011, I am going to attempt to average one post a week. I am putting this on the record to try to make sure that I actually do it.

In addition to topics related to software engineering in general, I am planning on learning and blogging on the following:

SchemaRede
Clojure
Comet
And maybe this Comet, too
Jetty
JSON
DWR
Neo4j
Cassandra
db40
MongoDB
jQuery
Node.js
Amazon EC2
Google App Engine
7 Languages In 7 Weeks (More Like 7 Epochs)

Also, I plan on attending 1 major conference and at least 8 local users groups. Once again I am putting it on the record to shame me into doing it.

And, yes, this counts as blog post.

What A Little Communication Can Do

Over the last few weeks, my team has spent time refocusing on communication within the team as well as with our customer proxy. For various reasons, we had become a very siloed. There was little communication with our customer and only little more communication between team members–primarily among individuals that had to make their pieces of code talk to each other.

We’ve gone back to tasking out work on a regular basis. In the course of doing this, we all are talking about what’s there, what’s needed, what we understand, what we don’t understand. With this, we were able to figure out what we could comfortably commit to. Then, we worked with our customer proxy while we developed. This was done in conjunction with our normal code review/refactoring sessions. Lo and behold, the iteration went smoothly.

I hope the rest of the team feels the same way. I know from a lead/senior development perspective, it was less painful (almost fun!) than previous iterations. I’d almost forgot what a little communication can do.