Showing posts with label agile. Show all posts
Showing posts with label agile. Show all posts

Tuesday, 18 May 2010

AgileNorth - May 2010

On Friday I attended AgileNorth May 2010 at Preston UCLAN.

It was an excellent day and thankyou to all the organizers and sponsers Valtech, Thoughtworks to name two.

The opening keynote was by Kevin Murray of Valtech, titled 'Agile in Waterfall Case Studies'. Kevin talked about two case studies where he had been the project manager and introduced agile working practises. Both were large goverment waterfall projects with the latter being a project rescue.

The second project was especially interesting. He was the 14th PM in 2 years and the team members were desperately demotivated. Kevin identified the following benefits:

  • increased morale

  • increased motivation

  • feeling of ownership

  • issues addressed earlier

  • visibility to all of status

  • better quality

  • less bugs at FAT


Kevin emphasised that introducing agile especially into large government style projects must not:

  • compromize estimates

  • question or sacrifice governance


The second talk I attended was by Nick Mckenna of Mckenna Consultants.
Nick is an agile consultant based in Harrogate offering training and consultancy and his talk was titled 'Agile Adoption'. The talk was good and interesting but felt to me like we were getting the first hour of a 1 day talk. His main point was to define a timetable when starting with agile and that could typically be about 3 months. He also emphasised the following:

  • get everyone to agree

  • identify roles

  • spend some time on training

  • take it slow

  • prepare to compromise

  • make it visible

  • keep everyone informed

  • the timetable must be agile

  • review the time table


The third talk was by Paul Shannon (twitter) and Craig Judson (twitter) of Codeweavers titled 'From Chaos to Kanban'

Their talk discussed the life story of how Codeweavers had adopted and adapted agile over the last 2 or 3 years along with the help of the agile consultant Kevin Rutherford. They are clearly exstatic with where they are now in terms of performance and quality. They emphasised to me how agile is in itself agile. how they started doing scrum by the book and ended up with their own kanban solution and board. Their slides are available here.

An excellent lunch was followed by a workshop from Sam Wessel also of Codeweavers on 'CRC - the forgotten Design Tool'. Here is one link to CRC - Class Responsibility Collaborator. This was a fun workshop designing a library application. It showed how to really break down an issue and see your self as the objects in the problem along with their inter-reactions and roles.


The penultimate talk was by the Agile consultant Kevin Rutherford of Rutherford Software (twitter) entitled 'Flow'. The aim of the talk was to show how agile increases the speed with which changes can flow through from requirements to an end product. I really like Kevin's dry and straight talking style. His blog write up of the talk is here. Here are some of his points:

  • YAGNI - do not do what you do not need now

  • question or sacrifice governance

  • thin sliced MMFs (minimal marketable feature) - IE breakdown the work into small chunks

  • continuous integration

  • Theory of constraints

  • The Goal by Goldratt


The closing keynote - phew it was a long day - was by Jim Barritt and Mark Crossfield. Mark is a Thoughtworks ">Thoughtworks consultant and Jim works for Autotrader. There talk covered the issues of working running an agile product with a rapidly expanding workforce.

Two interesting tools that I came across in talks and will investigate soon are

1) Migratordotnet - This is based on the idea of Rails ActiveRecord Migrations. Interestingly it puts the migrations into a dll making them easy to run & install on a windows PC without the need for Rails or other bespoke software.

2) AgileZen - This is an online kanban board, free to use for a single project.

The next AgileNorth will be October time and will be free.

Find other links on AgileNorth via this delicious tag.

Finally here are some twitter links:
@BlueReZZ - Paul Shannon of Codeweavers
@craigjudson - Craig Judson of Codeweavers

Friday, 10 July 2009

EasyMock - Reason to update to the latest version

I have recently started working on a new project that consisted of three dependant Java projects.

These three projects were using two different versions of EasyMock so first off I decided to bring them into line. The projects are all Java5 but one project had EasyMock 2.4 and the other two had EasyMock 1.3

Following on from Andrew Beacock's article on using easy mock's class extensions I decided to give that a go.

Strangely after upgrading some of the tests were failing. Why ?

Well it looks to me like a bug in the old version of EasyMock 1.3,
so the easy answer is upgrade. The bug appears to be that you can not call MockControl.expectAndDefaultReturn() more than once.

Here is the test using the old code, and below that a test class using 2.4.

EasyMock 1.3 version:
package uk.co.utilisoft.entrecaweb.web.validators;

import java.util.ArrayList;
import java.util.List;

import junit.framework.TestCase;

import org.easymock.MockControl;

public class TryOldEasyMock extends TestCase{

public void testSingleCall(){
List<String> list = new ArrayList<String>();
list.add("hello");
MockControl control = MockControl.createControl(TestMock1.class);
TestMock1 mock = (TestMock1)control.getMock();

ClassUnderTest1 classUnderTest = new ClassUnderTest1();
classUnderTest.setService(mock);

control.expectAndDefaultReturn(mock.getLength("hello"), 5);
control.replay();
assertEquals(5, classUnderTest.getLength(list));
control.verify();
}


public void testTwoCalls(){
List<String> list = new ArrayList<String>();
list.add("hello");
list.add("bye");

MockControl control = MockControl.createControl(TestMock1.class);
TestMock1 mock = (TestMock1)control.getMock();

ClassUnderTest1 classUnderTest = new ClassUnderTest1();
classUnderTest.setService(mock);

control.expectAndDefaultReturn(mock.getLength("hello"), 5);
control.expectAndDefaultReturn(mock.getLength("bye"), 95);
control.replay();


assertEquals("this is the wrong value & should fail.", 190, classUnderTest.getLength(list));
assertEquals("this is the correct value & should pass.", 100, classUnderTest.getLength(list));
control.verify();
}
}

class ClassUnderTest1{
private TestMock1 service;

public void setService(TestMock1 service) {
this.service = service;
}

public int getLength(List<String> someText)
{
int total = 0;
for (String value : someText) {
total += service.getLength(value);
}
return total;
}

}

interface TestMock1
{
public int getLength(String someText);
}


EasyMock 2.4 version, using the class extensions jar:
package uk.co.utilisoft.entrecaweb.web.validators;

import java.util.ArrayList;
import java.util.List;

import junit.framework.TestCase;
import static org.easymock.classextension.EasyMock.*;

public class TryEasyMockTest extends TestCase {

public void testSingleCall()
{
List<String> list = new ArrayList<String>();
list.add("hello");

TestMock mock = createMock(TestMock.class);

expect(mock.getLength("hello")).andReturn(5);

ClassUnderTest classUnderTest = new ClassUnderTest();
classUnderTest.setService(mock);
replay(mock);

assertEquals(5, classUnderTest.getLength(list));
verify(mock);
}

public void testTwoCalls()
{
List<String> list = new ArrayList<String>();
list.add("hello");
list.add("bye");

TestMock mock = createMock(TestMock.class);

expect(mock.getLength("hello")).andReturn(5);
expect(mock.getLength("bye")).andReturn(95);

ClassUnderTest classUnderTest = new ClassUnderTest();
classUnderTest.setService(mock);
replay(mock);

assertEquals(100, classUnderTest.getLength(list));
verify(mock);
}
}

class ClassUnderTest{
private TestMock service;

public void setService(TestMock service) {
this.service = service;
}

public int getLength(List<String> someText)
{
int total = 0;
for (String value : someText) {
total += service.getLength(value);
}
return total;
}

}

class TestMock
{
public int getLength(String someText){
return someText.length();
}
}