Pages

Monday, June 13, 2016

The Kick Off

What is this?
This document describes an internal(team) designed and agreed mandatory rules for the process that just precedes the development of a story, This process is commonly known as the "Kick Off".

Why?
The main reasons for this are:
  • to make sure that the team is aligned/understands the story that is about to be developed
  • distil the requirements given to the team by the business analyst and early spot errors in them
  • revisit and adjust the scope of the story if necessary 
  • create a mandatory repeatable process so the risk of early introducing an issue is less
  • agree upon work that need to be done

THE KICK OFF

  1. Read the story description independently
    Regardless of if we work in a pair programming environment or not, we(each member of the team individually)  will take some time in our own to read the requirements that were written in the ticket management tool(e.g JIRA). The time this first glance takes is somewhere around 5' and 20'.
  2. Gather questions
    We must understand that the kick off is a team activity. We are not expected to understand everything in the requirements at 100% neither to know exactly everything that needs to be done and how it should be done. We will write down all our concerns, doubts, assumptions, questions, etc... in a list and we will keep it for the time of the kick off. Individual solutionising is not an acceptable behavoir.
  3. Craft a task proposals list
    Now with our pair programmer or by our own if we don't have one, what we will do is to write down a list of proposed tasks, based on our understanding of the story so far. This list is just a draft, not a final decision. The purpose of this draft is:
    - To make visible to others our views/sense about the story in hands.
    - To make it easier for the developers to spot task parallelisation opportunities.
  4. Empty acceptance test
    An empty acceptance test(just text in the Given When Then format) will serve as a conversation starter during the kick off. The propper creation of the real failing acceptance test will be done as an independent task, later since only when all is clarified in what regards to requirements, we can write an accurate and meaningful acceptance test.
  5. The Kick Off
    At the kick off all the team gathers and look together at the story. The BA will start by giving a brief summary on what is the story about. Then the developers will show the empty acceptance test they've written. Now is the time to use the questions, assumptions we gather initially. If any discrepancy exist, it will be clarified by the team and the acceptance test will on spot be corrected. At this point, the story is considered to be kicked off with the team(but yet not officially marked as started).
  6. Dev's talkWhen the kick off is complete and we know exactly what needs to be done, we will huddle with the rest of the colleagues to distil the proposed task list we made and agree on what tasks we can parallel. It is highly likely that after the kick off toke place that initial draft is no longer accurate at 100% so the devs will revisit it and distil the final version. This final task will be published in the same place where the requirements were published, so the progress of the story is transparent to everybody.
  7. Start development
    The developers will now prepare their tools for development(e.g rebuild local DB, synchronise VCS, awake zombies...). When this is complete the developers will move the story into "dev in progress" and development begins. Good time for a coffee now ;p

Thursday, June 9, 2016

Mockito ArgumentCaptor example

Lets observe the following class

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
public class MyService {

    private Collaborator collaborator;

    public MyService(Collaborator collaborator) {
        this.collaborator = collaborator;
    }

    public void doSomething() {
        Thing thing = new Thing();
        thing.setType("ABC");
        collaborator.doStuffWith(thing);
    }
}

If we were to test the method doSomething() what we would be interested in,
perhaps mostly is to make sure that the collaborator that it uses is reached and the appropriate
parameters are passed. We could do that very easily by just verifying on a mock

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
public class MyServiceTest {

    private Collaborator collaborator = Mockito.mock(Collaborator.class);
    private MyService myService = new MyService(collaborator);


    @Test
    public void shouldDoSomething() throws Exception {
        myService.doSomething();
        verify(collaborator).doStuffWith(any(Thing.class));
    }
}


But there is a peculiar thing about this method. The argument that is passed into the collaborator
function doStuffWith() its using an object. Objects as its well known, contain other objects and/or
primitive variables. Since the object thing its being created internally in the method rather than be
injected(Its a hardwired dependency), we have no way of accurately knowing about it anything else but its type. So if we were curious about knowing more precisely about that object, what we would have to do is to spy on it. Mockito, allows us to spy on the objects that are passed to the mocks using a little tool called Argument Captor.
Let's have a look at how this test would look like if we were spying the object thing.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
public class MyServiceTest {

    private Collaborator collaborator = mock(Collaborator.class);
    private MyService myService = new MyService(collaborator);


    @Test
    public void shouldUseTheRightThing() throws Exception {
        ArgumentCaptor<Thing> argument = ArgumentCaptor.forClass(Thing.class);

        myService.doSomething();

        verify(collaborator).doStuffWith(argument.capture());
        assertThat(argument.getValue().getType(),is("ABC"));
    }
}

As you see, spying is an interesting way of in a non intrusive manner(without having to refactor), you can discover things about your code.

Now a question comes to our head. But declaring that object of type Thing in the method like that, is not an smell? Well, maybe but have in mind that if you were to inject that object from either the constructor or via a setter injection, we could say that you would be changing the api of the class. So that is not very good, because maybe you don't know if the clients that use the class are actually capable of providing the object thing or if would that even make sense form a design point of view.

To express this last point in a more pragmatical form, I am going to show you another 2 more intrusive refactoring to this class that could help you test that object, but that will need from you to sacrifice in design.  

1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
public class MyService {

    private Collaborator collaborator;
    private ThingBuilder thingBuilder;

    public MyService(Collaborator collaborator, ThingBuilder builder) {
        this.collaborator = collaborator;
        this.thingBuilder = builder;
    }

    public void doSomething() {
        Thing thing = thingBuilder.withType("ABC").build();
        collaborator.doStuffWith(thing);
    }
}
If you had a builder, you could mock it and train it, but you would pay a design price of having to add the builder to the constructor.
Even if you choose to use a setter to set the builder or keeping the original constructor as it is(so you don't affect the clients) and overloading, you are still sacrificing your design for the purpose of the test. Your test would also become more complex. It would look like this:

1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
@Test
    public void shouldUseTheRightThing() throws Exception {
        Thing thing = new Thing();
        thing.setType("ABC");
        when(thingBuilder.withType(anyString())).thenReturn(thingBuilder);
        when(thingBuilder.build()).thenReturn(thing);

        myService.doSomething();

        verify(collaborator).doStuffWith(thing);
    }
The other alternative I was thinking about would be to override equals and hashcode, so you could do a comparison in your test against a newly created object that would be the
expectation.

1
2
3
4
5
6
7
8
9
@Test
    public void shouldUseTheRightThing() throws Exception {
        Thing thing = new Thing();
        thing.setType("ABC");

        myService.doSomething();

        verify(collaborator).doStuffWith(thing);
    }

It looks naive, but again is intrusive. You are adding 2 methods in your entity, just for the purpose of making the test green.

1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class Thing {
    private String type;

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Thing thing = (Thing) o;

        return type != null ? type.equals(thing.type) : thing.type == null;

    }

    @Override
    public int hashCode() {
        return type != null ? type.hashCode() : 0;
    }
}

Wednesday, June 8, 2016

Remote debug - IntelliJ + Java + Gradle + SpringBoot

This brief video just shows how to hook IntelliJ's remote debug config.
If you want to try this yourself, here you can find the app I am using in this demo:
https://github.com/SFRJ/hitthegroundrunning




Debugging for hours and still you didn't found the bug? No panic, just call this guy, he can solve all your problems:




Share with your friends