Monday, December 14, 2009

Part 4:: Who I Want To Hire and Work With::Can they learn

What have they done and what are they doing to learn?

Coninuing and hopefully finish, at least for now, my toughts on hiring I want to talk about learning. Probably the most important thing a programmer does. We have talked about fitting in the team and problem solving but learning is what creates a true long term employee and team memeber.

Learning is the one thing programmers must continually do. Since what we do is solve problems and the problem is continually changing so we must continue to learn. The IT industry is not stagnant and it is not mature. We have new languages, new APIs, new techniques, acronyms and more. Learning along with problem solving go hand and hand and are the most important tasks for a programmer or knowledge worker of any type.

Did they learn from past failures?

We learn many ways and all teach us differently. We learn a lot from failing. Did we do something wrong? Did we NOT do something we should have done? If you have done any development at all you have seen failures both big and small. Sometimes it is a simple direction chosen for a design that was recoverable. Was the design chosen to soon before we had enough information? Was the design chosen with a bias because of past experiences that did not match the current situation? Sometimes it is a combination of too many things and no one admitted it until the end when it was too late to recover. But we learn a lot from these failure, well we should. But too often we keep repeating them.

I also like to see who gets blamed for a failure. The easiest thing to see is what others did wrong that lead to failure. However, in every failure I have been involved in I was a part of the team and there is something I could have done better that may have helped prevent the failure. Maybe I made some of the bad decisions. Maybe I just had a bad attitude that affected others. The same is true for everyone and I want to know if they reallize it and admit it.

What did they learn from past successes?

Of course I do not want someone who has seen only failures or very poor projects. We learn from success as well. What decisions were made along the way that lead to successes? When problems occur how did the team solve them. Every success has plenty of oppurtunities for failure along the way and the team avoided them or were able to recover from them. How did they do it? What was the attitude of the team and how did they keep positive? Who lead the way? There is always a leader is successful projects that encourages the team in tough times. Sometimes it is the official leader but many times it is not. What did they do? What was there attitude?

What are the reading or studying?

We also learn through other means, reading, user groups, discussion groups, and the many communities available on the internet. I have been following a discussion on the agile developer skills group and I think the original goal was to come up with a set of material that could be used as training and mabye certification in agile. It may have some value towards those goals, maybe, but the value in following and participating a little in the discussion is incredible. Every time I have replied I may get a few I agrees but someone always challenges part of what I say. This makes me rethink my position and either clarify it or adjust it. Both of which have caused me to learn. No one that takes a class in the subjects will come away with the learning that the people involved in the debate are getting.

What are they doing to learn?

Learning in discussion is only partial though, you must apply this and put this knowledge to the test. So I want to know what they are doing not just what they are reading or saying. Doing shows us what we have learned and what we did not understand. It also shows us when our assumptions were wrong. I might think something is true but until I have seen it succeed there is a good change I am wrong. In programming we can try it and make a mistake and usually the worse thing that can happen is I lock the computer and have to reboot. :) This trying goes back to the failing section above. We learn, we try, we fail and we adjusts and start again. In this process I get experience.

Another area of learning comes when I get away from the computer and do something else. I want someone who has a life away from the computer. I spend a lot of the time on the computer but I also like to play different sports, play the guitar and listen to music. When I walk away from the computer I come back with a better perspective. I come back with fresh ideas and I am much more productive that when I spend 60+ hours in front of a computer. I am looking for a balanced team member and getting away from the computer is part of that balance.

Conclusion:

I am sure I have left some things out in these short blogs on hiring. And sometimes I do the things that I said earlier were less important like asking what APIs they know or about some strange behaviour in an API that is rarely used. But frankly this is being lazy and it will not accomplish the job of finding a good team member.

One other warning about what I have said. Doing this will make it difficult to hire someone. If you have put yourself in a position to need people fast this will not work. However, if you put yourself in that position someone will have an oppurtunity to learn a lot from the failure you are about to start. Almost every company talks about people being the most important part of there business but for most it is just a slogan. If you really believe people are important, and they are, then hire like it is important. Hire people that will improve your team and continue to improve themselves.

Sunday, December 13, 2009

Part 3:: Who I Want To Hire and Work With::Can they solve problems

How does this person think and solve problem?

Problem solving is really what we do on a day to day basis as knowledge workers. Whether we are doing new development, fixing defects, testing there is a problem that needs to be thought about and solved. Sometimes the computer and the tools do not have all the answers. :-) I like the way Andy Hunt said it: "Programming is all about problem solving. It requires creativity, ingenuity, and invention." (Hunt, A: 'Pragmatic Thinking & Learning: Refactor Your Wetware, page 2. The Pragmatic Bookshelf).

It is difficult to determine how a person solves problems in a normal interview. Interviews often take place in 30 minute to 1 hour segments with different people in the organization. How many problems do you have that get solved in that time. Solving is usually a process of thinking about it, discussing it with others, trying some ideas and failing and continuing this process until a satisfactory solution is found.

Here are a couple of ideas to try. The first is if you only have an hour or so for your part of the interview. The second and more beneficial idea is if you can bring the person in for a half or full day to 'inteview' with the whole team.

Given a situation where a common design principle is violated and is causing a problem, can they identify it and solve it?

Start with a class which has a dependency it creates itself and tell the interviewee the class needs to change to handle 1 of n types of this class based on user preference. This is an easy problem obviously. However, the answer to this question will help show the person biases and experience. If the person starts talking about what tool they would use steer them away from this by telling them it is in a different language. Maybe they think it should be done by injecting the class via spring. In this case tell them it is being done in Ruby. It is fine to have them write sudo code if they do not know a specific language you suggest because the point is how they solve it when it is a different situation than they are most familiar with.

The problem with any scenario for a one hour interview is it will either be so simple or so difficult that it is improbable that it will be solved in the limited time. Both cases have limited learning about the capabilities of the interviewee.

If possible I want them to pair with the team.

If you can bring the interviewee in to work with the team for a half or full day this is even better. Some people do not do well in an interview situation. Other people do great in a theoretical discussion but cannot apply the knowledge in a real situation. A full day will give the team a real feel for the persons ability. It will also give the person some time to relax and start thinking (hopefully). Have them pair with multiple people on the team. Let them write code and review code being written. Go to lunch with them. Have a design discussion for a tough issue. Put them in as many situations as possible.

The ability to solve problems is extremely more important than the APIs they know. If you can find someone who can solve problems you will find someone who can find or write an API that fits the situation. If you find someone who knows an API or a language well you are very likely to find someone who solves every problem with what they know, best fit or not. However, you need someone who can learn and is learning what I will try to cover in the next post.

Wednesday, December 9, 2009

Part 2:: Who I Want To Hire and Work With::Fitting into the Team

In continuing my thoughts on who I want to hire and work with I want to start going into detail about the 3 main areas. Today I will cover fitting into the team.

How will this person fit into the team?

Will they work in a collaborative environment?

Being able to fit into the current team is very important. Having a team focused on a goal and not killing each other is a difficult place to get to. There will be stressful times on a team and they are usually the most critcal points of the project. It will not matter how good they are technically or whether they can solve every algorithm no matter how complex if the person causes the rest of the team to stop performing I do not want them on the team.

I prefer working in an agile environment. Which means a very collaborative open environment which requires a lot of trust. Some people do not fit into this environment. Many developers want to work on their own and be left alone and they leave everyone else alone. This does not fit in an agile environment. In my oppinion this does not work in many environments but to be open maybe there are a few places such as a one man project. However, every environment I have worked in required constanct communication. Even before I worked in an agile environment we would get our project team together in a conference room for a couple of months to work faster and better together and help keep ourselves focused.

Will they fit in and still add a new perspective to the team?

I guess this is more of a goal that an absolute must have, but maybe I will change my mind after writing more. :) A good developer that has the exact same view point as everyone else and very similar experience to everyone else may not make the team better. Since I want a continually improving team, I want to improve the team with each hire. I want someone who has a slightly different set of experiences. Maybe I have a team whose expereinces are from large companies at which point I might consider someone from a small company. This person would bring the negative and the positive experiences and add that to mix that goes into all aspects of what we are doing. The great thing about this is it chanllenges both the new person and the existing team members. Everyone grows and the team improves. In James Surowiecki's book 'The Wisdom of Crowds: Why the Many Are Smarter Than the Few and How Collective Wisdom Shapes Business, Economies, Societies and Nations' he discusses that lack of diversity is one of the things that cause groups to fail. OK, I have changed my mind this is not optional.

Will they be challenged enough to be engaged with the team?

If I am looking for a full time employee, which in most cases is the only reason I should be hiring someone, I want them to stay a while. If I want them to stay I need to have a good idea they will be challenged.

Tuesday, December 8, 2009

Writing Maintainable BDD Specs/Tests

I will continue my thoughts on interviewing and hiring in the near future. But now I would like to add to a set of discussions, from Dale Emery and Uncle Bob Martin, on making acceptance tests maintainable or as I titled this post BDD specs/tests maintainable. Both blogs are excellent and the video is a nice demonstration of making this happen with FitNesse.

One point I want to add to is duplication versus keeping the spec/test customer understandable. Keeping them customer readable/focused is not being done by many of the tests I have seen that have duplication too. I am afraid everyone will focus on the duplication and miss the other very important details about removing, what Dale calls, the ‘incidental details’ and ‘naming essential ideas’. In my opinion these are more important in the test than the duplication. Removing duplication is second to making the intent clear which are hidden by ‘incidental details’ and confused by not getting ‘naming essential ideas’.

Naming essential ideas is better described in a combination of Domain Driven Design’s ‘ubiquitous language’ and Behavior Driven Development’s ‘getting the words right’.

I also think if removing the duplication makes it difficult for the customer to understand the tests, which are really specifications first, then you should find a better way to remove the duplication or keep it so the intent stays clear.

Some of the examples I have seen of un-clear intent lately:

  • Test of a specific gui (web or otherwise) that show the complete flow to get the application in the state to do the real test.
  1. Instead describe the current state (given step in BDD). e.g. the user is ready to purchase X.
  2. There should be other tests which describe and verify the steps in the flow prior to the ‘ready to purchase X’ state.
  3. Keep a single flow tests for each flow path but name it as such and do not display it in every tests that depends on it.
  • Tables to setup large amounts of data that contain significant amounts of ‘incidental details’
  1. Instead break these into ‘scenarios’ or separate test pages that test specific expectations.
  2. If an object in the domain is required for the tests and the important information is the date then make that clear: given a flight on SomeDate SomeTime.
  • Tables with large sets of data to verify (then BDD steps) action (when BDD steps) results
  1. Instead break these into specific steps/rows that describe the expected behavior.
  2. If flight A at some time and data should arrive the next day based on an action then state it clearly: Then flight A should arrive the day after departure because the DST time zone change
  3. If there are multiple verifications make sure each is clear why this action causes that and verify each in a different row (Uncle Bob does this is the video but does not explain why. He has a vast amount of experience and has mastered acceptance tests and probably just did it because he intuitively knew it was needed.)
I am also not saying do not test the flow. I am acutally saying the exact opposite. Test the flow and make it clear that this is being tested. Do not obscure your non-flow based functionality with flow and vice versa.

I am not saying never use tables to setup or verify data. There are times when they are helpful, and that is the key, in understanding but it is not as often as they are used.

Thanks Dale and Uncle Bob for having this conversation. I needed some help convincing others that they were creating a mess.

Thursday, December 3, 2009

Who I Want To Hire and Work With

There are a lot of articles, blogs, etc. written on interviews and interviewing and I am not sure what I have to say adds much to the discussion but I hope something.

When I stated thinking about this I thought I would right a simple blog post about this ... but it is not that simple. So I think I will start with my general thoughts on the subject at high level in this posts and then add detail on each area in follow up posts. Forgive me because I am also using this to learn and improve my own interviewing ability.

I am currently reading 'Pragmatic Thinking and Learning: Refactor Your Wetware' which is what lead me to think about this, Who do I want to hire and work with? For me the three most important areas I am interested in, with a few examples I consider when determing the skill level in the area, are below.

How will this person fit into the team?
  • Will they work in a collaborative environment?
  • Will they fit in and still add a new perspecive to the team?
  • Will they be challenged enough to be engaged with the team?

How does this person think and solve problem?
  • Given a situation where a common design principle is violated and is causing a problem can they identify it? The do not need to know need to know the text book principle name but they need to understand the cause of the issue.
  • If possible I want them to pair with a couple of team members?

What have they learned and what are they learning? (I would have worded this differently before reading the book)
  • What made successful projects successful? Why or What was the context? What did you have to over come for it to be successful?
  • What caused your failures? Who was responsible? (do they take blame or at least some of it) Why was it a failure? What did you learn?
  • What are you learning now? How are you learning? (reading, doing, writing, teaching) What is the goal?
  • What do you do other than software development? I learn a lot when I put down the keyboard and do something else.
Not included:
* What APIs/frameworks do they know? - For a long term hire APIs/Frameworks they know may have some importance but if they can learn I know am getting someone that has long term value.
* Trick questions. - Interviewing is a pressure and nerve racking situation for many people. You might be able to get how they react in a pressure situation from these questions, but only maybe.
* There are context specific issues but I am more concerned here about the concepts to cover. However, usually these context questions are applying my context to the areas above.

Sometimes I wonder if I would hire myself. What I tend to find and even find myself putting on my resume is all the languages, APIs and technologies I have worked with. But these are usually of lesser value when I am interviewing.

Sunday, November 15, 2009

GivWenZen and FitLibrary Part 4

I did not see this topic going any further; however, I had a question about turning the test green and I think I should explain how to do this and why I do it the way I do.

Please see the other posts if this post has no context for you read part1, part2, and part3.

So let's start with the simple part, the how.  To turn a test step green or red your step method must return a boolean.

e.g.

@DomainStep(“my business domain step”)
public boolean myStep() {
  return isTrue();
}

If the method returns true the step is turned green and if it returns false the step in turned red. (see the image from the previous post) Only the first column in the row is turned green/red.  In our given-when-then test this means the given, when or then column is turned red (and steps are turned green/red too).  Remember that we still have a table it is just not visible to the user.  From a technical standpoint a step written as ‘given the application is in some state’ is a two column table with ‘given’ in the first column and ‘the application is in some state’.  FitLibrary does the magic of turning our plain text into a table by looking for methods in our system under test and/or our fixture.

Now the more difficult part of the post.  Why do I only make the ‘then’ steps in the test turn green?  The simple answer is the ‘then’ step is the only ‘test’ of the actions the test has performed. So first let’s talk about the steps in a BDD test.   My reasons are influenced by and I will borrow heavily from Dan North and Cucumber’s Aslak Helles√ły in this section.  Please read there descriptions as they are much more knowledgeable that I am on this subject.

I am going to describe each step from two points of view.  First I will describe the step as part of a specification or acceptance criteria.  I think this is the most important because in BDD we are first describing the business value we are delivering to the customer.  Then I will describe the step from a test point of view (i.e. what should the methods do when executed as part of a test).

Given specification steps are meant to describe the starting state of the application in order for the actions in the current scenario (the 'when' steps) to be performed.  Given test steps are meant to put the application in to the state described so that the 'when' step can execute successfully (once the application is written correctly :) ).  I do not turn these steps green.  It is my assumption that this part of the application is working and covered in another spec/test.  If something goes wrong here then an exception should be thrown.  Of course, since all your test were passing when you started you should create a new spec that describes how and test that the application can be put into the desired state.

When specification steps are meant to describe an action that is valid or invalid based on the current application state as described in the given steps.  When test steps perform the described action.  If something goes drastically wrong here I like to throw an exception that describes where the problem is in the system.  Why would I turn this step green/red?  What does it mean?  Really it can only mean that the action was performed and no exception was thrown.  Maybe that is enough but usually it is not which leads us to the ‘then’ steps.  It should be impossible for this step to be green if any of the ‘then’ steps are red so I think it is best to not color this step and throw an exception on serious failures.

Then specification steps tell us what is expected after the action of the when steps occur.  Do I expect the application to be in a new state?  Do I expect the action to fail?  Do I expect a message to be sent?  Then test steps verify that thee expected outcomes are true.  These steps must be turned green or red because they are the tests.

The problem with turning the 'given' and 'when' steps green is it gives some false impression that the expected outcomes of the test are true.  It is very likely when you are adding new functionality or changing existing functionality in an existing system that the 'given' and 'when' steps will be green the day the specification is written.  And in the case of FitNesse it will say you have N number of passing assertions and in reality you have not asserted anything.

In conclusion I must ask you to please read Dan North’s articles on BDD and check out the Cucumber pages as they have some good stuff (even if you cannot use Cucumber which is why I wrote GivWenZen).  Please let me know what you think about this method of doing BDD with FitNesse/FitLibrary.

Saturday, November 14, 2009

GivWenZen and FitLibrary Part 3

I mentioned in the previous post that I liked the plain text but really would like to write plain text without the indicator, '- ', that it is plain text.  In my continued testing of and improving the usage of GivWenZen with FitLibrary I have tweaked the ParseUtility class in FitLibrary to look for BDD keywords given, when, then and and.  This allows the same simple test we have been looking at to be written like the following.



A bit cleaner, in my oppinion, that prefixing each line with '- '.

I have done an override of the fitlibrary.utility.ParseUtility class. Unfortunately it is not extensible because it is mostly static methods. :( My override of this class simply changes the place that looks for '- " to look for one of the GivWenZen/BDD keywords, given, when, then or and. Here is the part I changed/added.  I added the static int isGivWenZenLine(String html)method and replaced a line that was simply looking for '- ' with a call to the new method. See ParseUtility is the example source.


When the test is run the then line is turned green on a failure. (more about this later)





In reality there are tables when the plain text test runs. FitLibrary is still running this as if each line were tables and magically creates the tables at run time. I have a custom CSS to stop the tables from showing after the test runs. Below are the CSS values I have overridden in my fitnesse.css. table, td, th { border: none; }


Monday, November 9, 2009

GivWenZen and FitLibrary Part 2

Yesterday I showed an example of using GivWenZen with FitLibrary.  I was pleasantly surprised with how simple it was.  It seemed much easier than using FitNesse/SLiM alone.

Today I want to continue with the FitLibrary and show you a new feature that I really like, plain text specification / test.  Again, I was amazed at how easy it was to do.  To use plain text we can use the same Fixture we used yesterday.  And we simple change the test to look like the following:


!|GivWenZenDoFixture|

- given i turn on the calculator
- and i have entered 50 into the calculator
- and i have entered 75 into the calculator 
- when i press add 
- then the total is 125


For the test you simple write the sentence and prefix it with a '- '. No special CSS needed to make the table go away. Very nice. It would be nice if the '- ' was not required. I would prefer an assumption that a line is a specification step and require a special character to indicate a comment. However, I do like the feature and it is a step in the right direction toward plain text.






Sunday, November 8, 2009

GivWenZen and FitLibrary

My previous examples of using GivWenZen to write BDD style tests with FitNesse were done with the SLiM test system.  This was mostly due to an issue getting FitLibrary to run with the latest version of FitNesse.  However, Rick Mugridge has released a new version that fixes this issue as well as a few other nice enhancements.  Fixing of autowrapping of booleans, Strings, and other native java types was also big benefit to helping the BDD test read better.


Using GivWenZen with FitLibrary is very easy.  Create your own fixture that extends DoFixture, or any of the related type fixtures, and set the system under test to your instance of the GivWenZenExecutor.  The following is a simple example with a DoFixture extension.


import fitlibrary.DoFixture;

public class GivWenZenDoFixture extends DoFixture {

    public GivWenZenDoFixture() {
        super(new GivWenZenExecutor());
    }
}




This will allow you to have a FitLibrary specification/test like the following:

!|GivWenZenDoFixture|

|given|i turn on the calculator| 
|and|i have entered 50 into the calculator| 
|and|i have entered 75 into the calculator | 
|when|i press add| |then|the total is 125|


I am looking at enhancing this using the FitLibrary pluggability to change how methods are looked up. Hopefully, I will have a new post on this soon.


Thanks for the FitLibrary update Rick!

Tuesday, October 6, 2009

BDD Open Source is Growing

When i heard Dan North talk and show examples of BDD a couple of years ago it excited me. I had been doing TDD and ATDD for a while but the way the specs were worded with BDD just made since.  When I went back to work I found that most of the tool support was in ruby and groovy which did not help me with Java projects I was working on at time (yeah I know you can use Groovy with Java but it is not always easy to convince a Java team to do this). So, I kept doing TDD and ATDD (see discussion regarding ATDD vs. BDD).

A few months later I was frustrated with how most ATDD specs were looking and started playing with Cucumber.   I really like the way the specs read in Cucumber.  I also like the way it allows you to group the steps which made reuse so easy and logical.  The problem I have is most teams I am working with are still doing only or mostly Java.  These teams also have FitNesse experience both in the QA and Development groups.

So earlier this year I decided to start creating a tool that would allow me to give a FitNesse experienced team the ability to use the BDD Given When Then language.  The tool is called GivWenZen.   We have used it on a couple of projects internal and I hope you will give it a try.  I have also done an example implementation of using GivWenZen from JUnit as a BDD spec.

What I found after I released it was there are a lot of tools now for BDD.  There is even another tool that is similar to GivWenZen and it is called NarrativeFixture.  Both projects appear to have similar goals but went about implementing a bit differently.  Try them both out and see what you think.  I know I would like any feedback you have on the tool.

There are a lot of other tools out there as well.  If you have not tried out BDD I really recommend reading up on it.  I have found the idea useful in explaining myself in situations outside of just development.  Yeah, it is geeky I know.