poniedziałek, 16 grudnia 2013

Good/Bad .vs. Appreciative Inquiry Retrospective

Lately I had a great chance to participate in a Coach Retreat session organized by Oana Juncu with cooperation with Code Sprinters in Krakow. The idea of coach retreat is nicely described on Oana's blog hence I won't be describing it here.

The thing I wanted to write about is a way how we can use one of the coaching techniques (called Appreciative Inquiry) while doing Agile Retrospectives.

The main idea behind AI to focus on the place we want to be and ways of how we can get there (as oppose to focusing on problems that we can find on the way). The best way to understand new technique is to compare it with something we already know. Let's compare regular problem solving approach with AI:


One might think that it is just a re-wording, a game of words but I perceive it more as a mindset. The founder of AI David Cooperrider in his article Appreciative Inquirey in Organizational Life states that over-focusing on a problem-solving techniques can actually limit your imagination and kill your potential that is actually needed to overcome difficulties. There is a danger that you will start perceiving a step as a goal, loosing the original goal out of sight. Sometimes it even happens that the more you are focused on a problem, the more you bound yourself to it and the more difficult it is actually to deal with it.

One of the biggest problems with retro is that while discussing current situation/problems teams fall into a fin-de-siecle mood: we've had these problems, we still have them, basically we're in deep shit and nothing can be done about it. AI technique does not allow for such mood to enter the room.

Here is a proposal of how your retro board could look like (it's taken almost precisely from wiki article about AI):


Design part which is about planning and prioritizing a process that would work well wasn't on the board when we were doing this style of retro but it was the discussion that was happening in the room.

One problem we as a team had with AI style retrospection is that we felt really uncomfortable talking about our strengths, and we left this row almost empty (only one sticky-note appeared there).

All in all, I must say that I have a great team that does really rarely fall into negative (not-constructive) mood hence it might have been easy to introduce such type of retrospection.
On the other hand I can imagine that such type of retro can serve well for team which often fall into such negative mood but it may require a skilled scrum master to shape the discussion using appreciative inquiries.

sobota, 26 października 2013

Behaviour Driven Development

The company I work for has been using BDD for over 2 years right now. I think it would be good to define what BDD means for us (as possibly BDD is similar to Agile in a way that you'll have hard time finding two people for whom it means the same). Couple of points that visualise our mindset:

  1. We do not add feature, we add an ability so our product is able to act under certain, new circumstances (obviously we first need to understand the business context/circumstances from much wider perspective then previously)
  2. Since we understand business much better (we have small business trainings at the beginning of working on every new user story - it was difficult at the very beginning as there was much to learn - it's much easier today) it is much easier for us to think about different business border cases and still being engineers we come up with cases that non-engineer would rather not come up with which usually also ends up as separate examples.
  3. We do not have business documentation as we fill up so called system tests with bunch of examples how our system behaves under certain circumstances - after these two years I can say that for us this is the most difficult part (there are certain traps waiting for thee one that will tray to follow this path - I will write about them later on)
  4. We have also introduced BDD on unit test level (discussion under this blog post describes what it means quite well: http://dannorth.net/2012/05/31/bdd-is-like-tdd-if/)
 
There are a few tools that support BDD (ex. JBehave, Cucumber), I can tell about JBehave only as this is the only tool we've been using, nevertheless I believe that whichever tool you choose, problems you'll encounter will be similar.

JBehave is just a tool and at some point in time we realized that we've hurt ourselves with it - we simply used it in a wrong way. I will write just short sentences but you must know that behind each sentence there was blood and sweat:
  1. JBehave is an overhead - you suddenly need to maintain twice as many files (story + implementation). Use it only if someone will be reading story files, only if it truly be treated as documentation. If this is not going to be the case, think what is it that you want to achieve with JBehave because there is a price that you going to pay.
  2. Think twice before you'll use JBehave on lower (then system tests) test levels. Our experience showed that JBehave is great to visualise some main concepts in the software (main paths through the SW) but it is not the best tool to explain some complicated and-or-or-and-and logic as in order to understand the core of such logic you need to grasp multiple stories at once which is really difficult.
  3. Examples alone are sometimes not enough - JBehave gives a special key word ("narrative") to add some context but in our case we needed to add more description of a context then it seemed intuitive at the beginning (after couple of months we found ourselves in quite usual situation when something that what obvious some time ago is not so obvious anymore)
  4. Do not use technical language - at the end of the day it is to be read by Business guys and they are not really interested in XPaths or threads
  5. Hope that Uncle Bob won't have anything against it that i'll quote him as a fifth point: “You don’t get a special license to write a highly coupled tests just because you’re doing BDD” by R.C. Martin

Fifth point is taken from the discussion that took place under Dan North's blog post I've already mentioned in this post.

I hope to find some more time in the nearest future to create some post about much more technical aspects and pitfalls.

poniedziałek, 11 lutego 2013

Money and self organized teams

Managing a self-organized team is a challenge... especially when it comes to salary. On one hand side we can not leave it  up to the team to decide how much their salaries will be raised. On the other hand asking the team for an opinion about given team member when it is time for his annual appraisal is so obvious that even if the team wants to be honest and is mature, the opinion may be skewed. It seems that there is no easy way out from this situation.

It seems that the only way is to leave it up to the manager to decide but a situation when a salary raise depends on one person only leaves a room for an abuse and by definition does not even try to be objective.

Here is a proposal of an algorithm that can be used to calculate a salary raise in a self organized team. An algorithm that promotes team-work, tends to be as objective as possible, does not introduce "an acid atmosphere" in the team but on the other hand side it gives precise numbers.

According to my model salary raise is composed out of two factors:

R = R1 + R2

1. (R1) Inflation + Salary ranges

To compute this part (R1) we can employ an equation for a restoring force
I - inflation factor
k - restoring factor
slow - lower boundary of a salary range
shigh - higher boundary of a salary range
smean  = (shigh + slow)/2 - mean of a salary range
scurr - current salary
k = I / (shigh - smean)

if (scurr < shigh) {
    R1 = I - k * (scurr - smean)
} else {
    R1 = 0
}

Short analysis:
- if you are below them mean of your salary ranges then this restoring force will pull you up, you will get an extra boost as you are underpaid
- on the other hand if you are over the mean of your salary ranges this factor in the most extreme situation (scurr >= shigh) will be equal to zero (never negative)

2. (R2)Performance factor

Everyone's opinion, appropriately gathered and analyzed compose the core of this factor (weights can be applied, but to be honest, in order to make the process as fair as possible I wouldn't introduce them). Just for the sake of this example let's assume that we have two teams cooperating with each other and every team consists of 7 people.

Step1. you ask every person to put all others in a row, starting from the one she likes to work with the most.

After this step is taken you have [7 (team1)+ 7 (team2)] 14 lists with [7 - 1 (all team-mates except author of the list) + 7 (all mates from the other team)] 13 names each.

Step2. you take all the lists together and sum them up in a way that if a given person is the last person on a given list you assign 0 points, if a person is at the first place on a given list she gets 12 points.

After this step is taken you have one list with pairs of names and score / weights.

In our current example you can simply compute that a given person can at most get score of 12 (points) * 13 (lists) = 156 points.

Having such a list and a budget for salary raises it is very easy (just by using a proportion) to compute how much of a pay raise a given person should get. If you'd like to take under consideration for example client's opinion with a higher weight (let's say 70%) you can ask client to assess every person from both teams by assigning a number ci from a range 0..156 (or you can perform a simple normalization of 156 down to 100, which would probably be more intuitive for a client). 

ci - weight of an ith person assigned by a client
scorei - weight of an ith person got directly from lists
wi - final weight of an ith person

wi = 70% * ci + 30% * scorei

B - budget for salary raises
si - current salary of an ith person


 

 

Advantages:

1. By combining subjective opinions of all people that co-work with a given person you get the opinion that is the closest to the objective one.
2. This algorithm promotes team-players over individualists
3. It is easy to employ additional weights if needed

Disadvantages:

1. Being forced to put your team-mates in an order usually creates a dissonance (especially putting someone on the last position) - that's why there should be another process of giving feedback introduced in the team so given person knows what (s)he should be working on. In that way being fair with each other we encourage ourselves to grow and develop.
2. It is best if an appraisal process is triggered for everybody simultaneously, other way it is possible that people being constantly forced to put their team-mates in a row would become frustrated.

 

Step-by-Step simulation

Team of 6 people + client:

Alex (Senior engineer): 1000$  
Jane (Senior engineer): 900$
John (Junior engineer): 500$
Mark (Principal engineer): 1600$
Anna (Junior engineer): 800$
Barbara (Senior engineer): 1200$

Junior engineer salary ranges: 500$ - 900$
Senior engineer salary ranges: 800$ - 1200$
Principal engineer salary ranges: 1100$ - 1500$

Inflation: 5%
Budget for salary raises: 600$

Alex's list:  Jane, John, Mark, Anna, Barbara
Jane's list: Alex, Barbara, John, Anna, Mark
John's list: Alex, Mark, Barbara, Jane, Anna
Mark's list: John, Alex, Anna, Barbara, Jane
Anna's list: Barbara, Alex, Mark, Jane, John
Barbara's list: Anna, Jane, Mark, John, Alex

Alex: 4 + 4 + 3 + 3 + 0 =14
Jane: 4 + 1 + 1 + 0 + 3 = 9
John: 3 + 2 + 4 + 0 + 1 =10
Mark: 2 + 0 + 3 + 2 + 2 = 9
Anna: 1 + 1 + 0 + 2 + 4 = 8
Barbara: 0 + 3 + 2 + 1 + 4 = 10

Total number of points possible to get: 4 * 5 = 20
After normalizing scores to range 0..100 we have:

Alex: 70
Jane: 45
John: 50
Mark: 45
Anna: 40
Barbara: 50

Client's opinion about every team-mate:

Alex: 80
Jane: 75
John: 60
Mark: 65
Anna: 90
Barbara: 80

Final score every person obtains (having in mind that we value clients opinion more [70%]):

Alex: 0.3 * 70 + 0.7 * 80 = 21 + 56 = 77
Jane: 0.3 * 45 + 0.7 * 75 = 13.5 + 52,5 = 66
John: 0.3 * 50 + 0.7 * 60 = 15 + 42 = 57
Mark: 0.3 * 45 + 0.7 * 65 = 13.5 + 45.5 = 59
Anna: 0.3 * 40 + 0.7 * 90 = 12 + 63 = 75
Barbara: 0.3 * 50 + 0.7 * 80 = 15 + 56 = 71

After putting all equations together we obtain following values:
Alex: 12,85%
Jane: 14,23%
John: 15,81%
Mark: 6,02%
Anna: 10,15%
Barbara: 7,24%


niedziela, 10 lutego 2013

Statement coverage .vs. Branch coverage .vs. Path coverage

This post is for these who would like to prepare themselves for ISTQB exam and have difficulties with understanding the difference between various types of coverage. Let's consider following piece of a code:

public int returnInput(int input, boolean condition1, boolean condition2, boolean condition3) {
  int x = input;
  int y = 0;
  if (condition1)
    x++;
  if (condition2)
    x--;
  if (condition3)
    y=x;
  return y;
}

Statement coverage
In order to execute every statement we need only one testcase which would set all conditions to true, every line of a code (statement) is touched.

shouldReturnInput(x, true, true, true) - 100% statement covered

But only half of branches are covered and only one path.

Branch coverage
You can visualize every "if-statment" as two branches (true-branch and false-branch). So it can clearly be seen that the above testcase follows only "true-branches" of every "if-statement". Only 50% of branches are covered.

In order to cover 100% of branches we would need to add following testcase:
shouldReturnInput(x, false, false, false)

 With these two testcases we have 100% statements covered, 100% branches covered

Path coverage
Nevertheless there is still a concept of path coverage. In order to understand path coverage it is good to visualize the above code in a form of a binary tree













As you probably see the above two testcases cover only two paths t-t-t and f-f-f while in fact there are 8 separate paths:
1-2-3
t -t -t - covered with testcase 1
t -t -f
t -f -t
t -f -f
f -t -t
f -t -f
f -f -t
f -f -f - covered with testcase 2