Friday, 31 May 2013

Lessons Learned: Retrospectives: A union of team honesty and responsibilty

Having been in a number of retrospectives I love the dialogue where team members are not afraid to say what they really think.
  • If something was a lemon, then lets chat about it! 
  • If something was great, let's praise and continue it! 
  • If something was only lukewarm let's at least acknowledge it and see how we can improve it!

And equally so where the team takes responsibility for the evolving action points to put things right!
  • What is it that I can do that can make a difference?
  • If the test team cannot easily write tests how can we adjust the process that it is so?
  • A developer might say I don't think I can solve this, but let's time box it for 2 days to see what can be achieved.

Without the honesty a team does not have the true chance to improve the development cycle for all team members! And without individual responsibility on action points the same faults will keep arising and we loose faith in the retrospective process. So perhaps with no surprise, a combination of both lack of honesty and responsibility may mean cancelling the retrospective process altogether! Horror!!

So how exactly do we encourage the team to be honest?
  • The faults of the team should not be attributed the individual. 
  • Supporting the team to be honest about what they really think.

Then encouraging individual responsibility on action points? This is not as clear cut. But there at least needs to be:
  • Room to manoeuvre in the backlog to implement the action point tasks. (That not on top of normal allocated tasks.)
  • The support of the team where a team member could not resolve an action point in the time allocated.

There is of course much more to retrospectives than team honesty and responsibility of action tasks, but it's a great start!

Lessons Learned: BDD: More than just behaviour driven development

BDD: More than just behaviour driven development


Quite often when looking at BDD scenarios and objectives we can miss the key point about why we do it and the real benefit it can give to development teams. That is if the behaviour can be expressed to a wide enough audience then it becomes more valuable both in terms of long term robustness and the effective nature as Real Time Documentation.

Real Time Documentation has the advantage that it never goes out of date like that of Wiki type documentation, and typically cannot lie if written correctly! But not all BDD scenarios represent Real Time Documentation!

I always suggest creating scenarios which have the most amount of power in terms of audience, suitability for Real Time Documentation and least amount of immediate change needed.

An example of BDD scenarios and compatibility to Real Time Documentation

1) The Poor BDD Scenario

Load Page 'xyz.html'
Enter 'foo' in '\\div[3]\p[5]\table\tr[1]\td[1]'
Assert 'specific error message'

Please notice:

  • It is readable only to a technical audience
  • It is extremely brittle and should fail on the slightest number of changes
  • It cannot be easily read grammatically and what it is meant to achieve in terms of behaviour is not clear
  • It would be hard to a tester or developer to maintain this test
  • This scenario is not suitable as Real Time Documentation.

2) The average BDD Scenario


Given we go to the login page
When we enter 'foo' into field 'j_password'
Then we should get 'x_errors' value 'com.custom.LoginException foo is not recognised as a known'

Please notice:

  • The scenario is readable to a larger audience but the terms involved make it appear very techie.
  • The test is much less brittle but it still relys on development criteria 
  • It can be read grammatically but again is far too techie
  • It can be maintained more easily than the first scenario. But the references to the fields and Exception messages make it far more brittle than it needs to be
  • The scenario has average suitability for Real Time Documentation

3) The ideal BDD Scenario

Given we go to the login page
When an unknown username is entered
Then an error message should be displayed

Please note:

  • The scenario is grammatically readable to technical and business audiences
  • The scenario is not brittle (although care should be taken in the underlying code to prevent passing this further down the line)
  • The scenario is unlikely to have to change that often
  • The scenario is ideal for Real Time Documentation.

Looking to learn more about NoSQL?

A found a free online course/certification on MongoDB here

You can catchup on the requirements if you start now!

Lessons Learned: Avoiding Distributed Transaction Management

In one particular project we were using an Oracle 11g Database and XA Datasources to persist transactions to multiple database environments. Whilst in theory this is fine, it wasn't really needed and by reverting to a more modular separate transaction management (as illustrated bellow) huge gains in performance were obtained.

Therefore I would strongly recommend alternatives to global transactions on XA Datasources to multiple databases. Unless it is really needed


Example Seperate Datasource Configurations


Multiple Transaction Manager IOC Configurations

<beans xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

    <bean id="firstTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="firstEntityManagerFactory"/>
        <qualifier value="first"/>
    </bean>

    <bean id="secondTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="secondEntityManagerFactory"/>
        <qualifier value="second"/>
    </bean>

    <tx:annotation-driven />
</beans>

Custom transactional annotations for the transaction managers

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Transactional("first")
public @interface FirstTransactional {
}

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Transactional("second")
public @interface SecondTransactional {
}

Custom transactional annotations embedded within a service

@Service("exampleService")
public class ExampleServiceImpl implements ExampleService{

    @FirstTransactional
    public boolean saveToFirstDatabase(ReceivedEvent toSave){
         ....
    }

    @SecondTransactional
    public boolean saveToSecondDatabase(ReceivedEvent toSave){
         ....
    }
}

In the Beginning!

The Very First Entry!

The Silverback is excited to be here!

I'm looking forward to sharing both technical and agile lessons learned in development to help out individuals and groups. Hopefully this will encourage further discussion and thought in the technical/agile development.