what is a business requirement?

Just because the customer asks for something doesn’t make it a requirement.  It makes it a discussion point.  For questions to ask, see my other blog post when should I question a technical business requirement

I tend to see five categories of non business requirements.  Many of these come from posts I’ve seen at JavaRanch rather than my actual users.

1. The customer is making assumptions about the technical implementation
Any requirement starts with an actual need.  Sometimes this is what gets stated as a requirement.  Other times, an implementation is given as the requirement without mention of what the original requirement is.

2. The requirements are technical and suggestions slip in
Some requirements, such as when you are interacting with other systems are technical.  Making it harder to differentiate the actual requirement from implementation suggestions.  With such a technical customer, it’s going to be harder for the customer to separate what is really a requirement in his/her head.  Questions can often draw this out.  And the technical customer may provide more useful insights during this process.

3. The customer  is trying to pre-optimize
Some customers give you requirements based on what they think is easiest rather than what they really want.  This happened to me recently.  My customer asked for something that was acceptable rather than what he preferred because it sounded easier to implement.  (In reality, it was an order of magnitude more work.)  When we talked about it, we decided to go with the actual easier solution.  Talking about it worked out very nicely.

4. The customer doesn’t really know what he/she wants
I think this is the hardest case.  It’s more than asking questions until you find out what is in the customer’s head.  It takes more discussion to help the user figure out what he/she wants.  Often technical mockups/prototypes help.  When you don’t know what you want, you may recognize it when you see it.  Or at least recognize what you don’t like in what you see.

5. The customer isn’t aware of what is out there
Sometimes a customer gives interaction requirements based on the desired behavior.  This makes sense.  At times, this description is extremely similar to an existing widget.  Either a built in one or one that’s already been implemented.  Showing the existing widget often results in something the customer likes better.  (or likes that he/she can get for little effort.)  Of course, technical people don’t always know the name of the widget either as evidenced by my what is this widget called thread!


What other categories can you think of?

writing readable & maintainable tests

Manning’s Art of Unit Testing is interesting in that it has chapters dedicated to the maintainability and readability of the tests. I didn’t read the whole book as most of it is about unit testing .NET code. (I’m a Java developer)

While these are pretty much all things I do regularly, I learned many of them through experience rather than starting out writing them that way. The most interesting along with some commentary from me were:

Readability

  • name your tests clearly – “test_method_1”, “test_method_2” are not useful names.  Better to say what is being tested.
  • use meaningful asserts – grouping your assertions into those with business meaning makes the main test easier to follow

Maintainability

  • avoid duplicate code – While this should be obvious, developers tend to be better at avoiding duplication in “real” code than “test” code.  It’s all code though.
  • avoid long and hard to understand tests – In my mind, the ideal test is as close to three lines as possible – a setup, a method call and a business assert.  There may be a few more lines.  But if there are too many, it likely the method doesn’t contain enough abstraction.
  • override toString – A great way to see the state of the object when the assert failes.
  • avoid specifying internals for dummy objects – Use stubs where you can.  Unless you are testing the interaction with an interface, you likely don’t need the granularity of mocks.

Anti-patterns

  • constrained test order – Despite the claims of TestNG, tests should remain independent of each other to make them as useful as possible.  It’s nice to see the author from the .NET world leans towards the JUnit philosophy.
  • shared state corruption – static state invites tests to rely on each other
  • multiple tests in same method vs a bunch of asserts for same scenario – I once heard a rule of thumb “one assert per test.”   I think the goal should be one scenario per test instead.  Having a bunch of asserts to check the state of a single logic thing makes sense.  Calling the same method with different parameters is crying out to be different tests.

What are your favorite tips on the topic?

learning programming by asking

Overall, I still think that Ted Nelson had the best idea when he wrote this in Computer Lib/Dream Machines (Aperture, 1974):

The best way to start programming is to have a terminal running an interactive language, and a friend sitting nearby who already knows the language, and has something else to do but can be interrupted with questions. And you just try stuff. Till more and more you get the feel of it. And you find yourself writing programs that work.

– “Software Craftsmanship” (page 95) and available online in an article about how it applies to Ruby.

This quote was from 1974.  Since then, some things have stayed changed and some things have stayed the same.  In particular, we now have personal computers rather than interactive terminals.  Of course, a command line prompt or IDE is an interactive session – just a more powerful one.  I think the concept is just as critical as it was then.

I can think of a few ways this learning applies to me here in 2009:

  1. Summer interns – When I was a college intern, I shared a cubical with an employee.  This made it easy to ask a short question when I got stuck.  (among other benefits)  The scenario was very similar to the quote – there was someone sitting nearby that I could ask without getting up that already knew the answers.  I plowed along until I got stuck and then there was someone to put me back on the right path.  I really appreciated this approach and have voluntarily shared my cubical with our summer interns once I was the employee.
  2. Pair training – Training new developers by pairing with them allows them to see the big picture before learning all the details.  If the goal is to be able to develop without pairing, the new developer needs to become self sufficient.  I like the idea of a more gradual path to there.  Whether it be going back to my own desk for snippets or bringing my laptop to work on other stuff, it provides the atmosphere where the new developer can start applying knowledge, but having someone “on call” to ask.  Personally, I think it was more effective when I brought my laptop because it lowered the “cost” of asking.
  3. JavaRanch – “a friendly place for Java greenhorns” – an online forum doesn’t have quite the same turnaround as someone sitting nearby, it is certainly better than nothing.  Very easy questions do tend to get answers within a few hours.  It’s the same idea of having someone available to ask when learning a new language.  The internet is great for that when there isn’t something in the office.

Not all my examples just cover learning a new language, but they do show how having someone more experienced around helps with learning other things.