Wednesday, July 14, 2010

I'm going full - Cannondale Prophet 3

I decided to move from my plain old hardtail Scott Aspect to something softer and more mountain-friendly. Good full suspension bikes are terribly expensive. My new Cannondale Prophet 3 is available in reasonable price. For this amount of money it is the best full option for my purposes:

  • blocking suspension on both fork and dumper
  • Rock Shock Pike fork with 95-140mm regulated step
  • full suspension with 140mm step
  • Avid Juicy 5 hydraulic disk breaks (185mm front, 160mm rear)
  • suitable for both uphill and light downhill






Thursday, July 8, 2010

ODE minimal process available at Hartifacts

Minimal ODE process is available on Hartfacts. It makes fooling around with ODE BPEL easier.

Just download it from SVN and deploy to your $ODE_TOMCAT/webapps/ode/WEB-INF/processes. Process WSDL can be found under following URL - http://localhost:8080/ode/processes/helloWorld?wsdl .

Wednesday, July 7, 2010

Help yourself with BPEL design

Free tools making designing the BPEL file easier:

  • Create BPEL file visually using Eclipse with Swordfish BPEL designer plugin (discovery site).
  • Validate correctness of BPEL file with bpelc compiler. It is provided with the Apache ODE.

Tuesday, July 6, 2010

TOCOVER marker as tests TODO

Every time I find TODO comment in the code I remove it and report it to the JIRA. Project is not the proper place for TODOs. Except...

Every time somebody reports me a bug I create unit test exposing it, fix it and keep the bar green. Usually. However sometimes there's a time pressure. What then?

Then I make the quickfix, test it manually, commit it and create test stub prefixed with the TOCOVER string. For example:

class TOCOVER_ShouldAssignUserToDocument {

  @Test
  void shouldAssignUserToDocument() {
    fail("http://foocompany.com/jira/ABC-123") 
  }

}

Prefix makes Maven's Surefire plugin to ignore the test till I implement it (I use Should*.class pattern for test classes).

I'm addicted to my test coverage stats so whenever I can I find all files matching TOCOVER.*groovy (I write tests in Groovy) pattern and complete the missing test for regression purposes (and higher coverage stats).

Grouping tests according to the iterations and purpose

I believe that organizing your test structure for modular testing is stupid, until you cover the majority of your project with isolated unit tests (not with the integration tests).

Most people group tests using the Java packages structure. Class foo.Bar is tested under the foo/BarTest file in the tests directory. This is good approach if you really test your classes with isolated unit test.

Something about 95% of my test coverage comes from the integration tests. I load minimal Spring context, minimal Hibernate session factory and so forth. I also try to treat my tests as my private (pre-QA) acceptance tests. In such case foo/BarTest hierarchy presented above sucks. It doesn't reflect what I'm testing since packages do not reflect the cross-concern nature of the integration tests.

My approach to is to create:
  • directories for application version (version == development process iteration)
  • many test classes with single (or few at most) testing methods describing particular testing scenario

For example:
  • version_1.2/ShouldSendAndValidateDoc.java
  • version_1.2/ShouldLinkUserDataToProcessMetadata.java
  • version_1.3/ShouldCreateAndReadEntityOracle.java
  • version_1.3/ShouldCreateAndReadEntityMySQL.java

BTW I use Should*.class pattern for localizing tests instead of *Test.class.

I believe that this is the only test structure maintainable for the long time. I associates tests with releases. This is quite logical since we write tests for current iterations, not for the system in general. Test path and name tell me everything about its purpose.

Monday, July 5, 2010

Database isolation in tests

Each test should be executed in database isolation. Each test should start with empty database and optionally create some fixture for its private purpose.

However the problem is how to remove data created by the test:

  • removing existing data manually is too annoying
  • listing tables automagically using JDBC and dropping their content will fail due to the foreign keys constraints
  • you cannot create new database for each test (1. too slow 2. JDBC doesn't support database management 3. Spring context should be cached between the tests)
Test data isolation is the problem indeed. My solution?
  • test classes extend AbstractTransactionalJUnit4SpringContextTests i.e. database changes are rollbacked after each test 
  • tests that cannot extend the class above (or need to be executed outside the transaction scope) have to clean after themselves manually
Follow the two rules above and you're gonna be sane.

Oh! And yes, transactional tests are bit slower but rollbacks are faster then deleting test data manually.

Use TDD for acceptance testing or go to NASA

TDD == buzzword. Everybody talks about it, recruiters in companies ask questions about it and then 5% of developers use it.

The main reason of that state is that everybody talks about the TDD in the context of the modular unit testing. And 95% of developers do not have enough time to create isolated unit tests for each class. Most companies do integration testing without detailed unit tests for each class. Developers usually create test covering loading of the Spring context, Hibernate mappings and writing to HSQL database. One test covers many classes.

Also designing tests for each class eventually requires a lot of planning and lots of time to implement all the tests (i.e. money). This is good for Motorola, Google or NASA, but not for avarage business-oriented company. Most companies don't need 10000% test coverage - 80% covereage of crucial system areas is fair enough.

However I still find TDD amusing - I simply use it for acceptanace testing. Before I start to implement the core business code I create acceptance test for the entire requested functionality (front-end with Selenium, back-end services with Spring test utils, Web Services with SOAP-UI etc.). When my tests pass I can deliver the product to QA for further testing. My acceptance tests tell me that my job is done (and provide regression for future changes). And I don't have to think about that should I implement next - test failures tell me that. The important thing however is that I do not test deep internals of my code with separated tests without the explict reason.

Please be a good citizen and stop bother people with TDD-TO-EACH-OF-YOUR-TINY-CLASS bullshit. It just doesn't work that way.

Sunday, July 4, 2010

Hello Huava

Guava is cool. Nice idea to have all the missing Java utils in one place.

However Google guys don't included in Guava all the utils I dream of. That's why I created Huava - project where I put my magic utils designed in the fashion similar to Guava.

Iterable transformations using Guava

I love Groovy for spread operator (for example users*.name). Google Guava allows you to do the same using the Function interface and Iterables.transform() method.

Function<Date, Integer> YEAR = new Function<Date, Integer>() {

  public Integer apply(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    return calendar.get(Calendar.YEAR);
  }

};

Date[] dates = {new Date(), new Date(), new Date()};
Iterable<Integer> yearsIterable = Iterables.transform(Lists.newArrayList(dates), YEAR);
List<Integer> years = Lists.newArrayList(yearsIterable);

System.out.println(years);

Saturday, July 3, 2010

Guava Files util - my top methods

Guava makes Java code more Groovy-like. Now say hello to the Spring IO utils and Ant. Introducing com.google.common.io.Files:

// Just write this fuckin' String to the file, man...
static void write(CharSequence from, File to, Charset charset)
static void append(CharSequence from, File to, Charset charset)

// File system operations
static void copy(File from, File to) 
static void deleteDirectoryContents(File directory)
static void deleteRecursively(File file)
static void move(File from, File to) 
static void touch(File file)

// No more annoying Java IO
static void createParentDirs(File file)
static File createTempDir()
static BufferedReader newReader(File file, Charset charset)
static BufferedWriter newWriter(File file, Charset charset) 
static List<String> readLines(File file, Charset charset)

Guava Object helpers

Say hello to the Spring utils.

import com.google.common.base.Objects;

// Null-safe equals
Objects.equal("foo", null);

// Choose first not-null or throw NPE
Objects.firstNonNull("foo", null);

// Helper for Arrays.hashCode()
Objects.hashCode(1, "foo", null);

// ToStringHelper which generates - String{foo, bar, baz=qux}
String toStringTarget = "foo";
Objects.toStringHelper(toStringTarget).
   addValue(toStringTarget).addValue("bar").add("baz", "qux");

Friday, July 2, 2010

Abstract naming

  • using abstract words like handler, processor, manager, holder is dangerous
  • try to reserve abstract naming for abstract classes
  • abstract words are fine if they correspond to the design patterns (factory, visitor, proxy, wrapper, decorator etc)
  • choose one abstract word and stick with it (get vs retrieve, driver vs manager, holder vs wrapper, delegate vs wrapper).
  • whatever you choose - be consist

Thursday, July 1, 2010

Free JRebel licenses for brown and black belts

Some time ago Java Black Belt announced that ZeroTurnaround gives free JRebel licenses for brown and black belts.

Several days ago I asked JRebel guys whether is it possible to get my annual license now (JBB news was published 2 years ago). And yes, it is possible - I'm the owner of the brand new free annual personal license.

Thank you for the license, guys. And for JRebel in general - it rocks.

Execute cleaning callback after Spring shuts down

I develop some fancy database management framework for purpose of integration testing. This includes calling PosgtreSQL client process from Java using the exec.

Such approach leads to the problem with cleaning the database (dropdb) after the tests. That happens because my testing beans are disposed before the Hibernate's SessionFactory (and you cannot delete database with connections opened by sessionFactory).

I could use the depends-on="dbTestFixtureBean" on sessionFactory bean definition. That would initialize my testing tool before the sessionFactory and therefore dispose my tool bean after the sessionFactory is destroyed. However my sessionFactory XML definition has to be unaware of the testing tools.

My solution? Runtime#addShutdownHook(). Since I use Groovy I use:

@Override
void afterPropertiesSet() {
  createDBFixture()
  addShutdownHook {cleanDBFixture()}
}

My cleaning callback is then called after the current thread is disposed.