Simple Web Development In Java

Teams often are slowed down by the increasing size and complexity of the frameworks they use and the code they write. But do they really need frameworks?

The reason we often choose frameworks is that they feel easy to start with and seem to hide the complexity involved in solving complex problems. Often though they give headaches and are a pain to get rid of.

If the solution to your problem does not require a framework, do not use one. Do It Yourself Simply (DIYS).


Simplicity is the key to brilliance

http://thepresentationdesigner.co.uk/blog/portfolio-item/bruce-lee-slide-2/

Reading the following situations might evoke a feeling of déjà vu.

a. You start a new development effort by assembling 5 to 10 (or more) libraries as a first step. The cost of carrying those libraries proves to be high. It’s not just installing. It’s the overall cost of learning, knowledge transfer, keeping up to date, supporting. It’s all the added complexity.

b. A framework keeps getting in your way. You have to invest of lot of energy to work around that framework. Typically, it gets in the way of test-driven development. The framework feels like a prison: you resist abandoning it because you fear the cost of change will be to high. Your code is too tightly coupled to the framework. Instead of listening to the feedback from your tests, you let go of your good intentions.

c. A framework keeps surprising you with some magical behaviors. It has unintended and inappropriate behaviors. You wish you could explain what’s happening, but cannot. You spend horrendous amounts of time searching user forums for an answer, but cannot find any. The source code is so hard to follow it won’t help either. You browse Google in desperation…

The Little Story

Some time last year, several discussions on the Growing Object Oriented Software, Guided By Tests discussion group inspired me to take action and rewrite an existing Java web application using only simple tools and libraries.

I was curious and challenged to see how I could actually build a transactional web application in Java in a simple way. By simple way I mean without a web framework, an Object Relational Mapping (ORM) framework or a Dependency Injection (DI) framework.

The original application is a sample application used mainly for academic purposes – typically when teaching how to do Test-Driven Development from the outside-in in Java. It uses Spring as a DI framework, Spring MVC, Hibernate as the ORM framework and Maven as the build tool. Velocity views and SiteMesh templates render the HTML. For better or worse, it’s a pretty standard Java stack – similar to what a lot of my consulting clients are using for their day to day development.

The Good, the Bad and the Ugly

There is some good, some not so good and some ugly in the original application.

The Good, the Bad and the Ugly

On the good side, the code is pretty clean and very well tested. It has been test-driven developed from the outside-in. End-to-end tests cover typical usage scenarios. Integration tests with the database cover both data access code, Spring transaction demarcation, Hibernate configuration and mapping, as well as database migrations. Unit tests for the views are done with offline HTML rendering and assertion against CSS3 selectors expressions with custom Hamcrest matchers. The overall code coverage is around 99% when combining coverage from the unit, integration and end-to-end tests.

There are also those areas were it could have been better. The domain model does not reify the concept of user requests, which results in some web controllers doing too much. Startup cost of the database integration tests is noticeable because they load Hibernate and a trimmed down Spring context. Assembling the application for running end-to-end tests is a bit tricky. Startup cost of the application also makes the end-to-end tests somewhat painful to run.

Finally, there are the real pain points. The Maven build is one of them, as always. It packs more than 1100 lines of XML for a rather small application! Configuring the application for running the end-to-end tests requires overriding application configuration with test settings via system properties override in Spring. End-to-end and integration tests use static contexts to avoid loading spring and hibernate contexts multiple times. Last, but not least, the WAR file weighs in at 53 jars, for a rather small application.

The Challenge

For the rewrite, the challenge was to eliminate the pain points and to follow these guiding principles:

  • Use only simple tools and libraries that are tailored to the problem at hand
  • No framework, all libraries should have a single responsibility – doing only one thing and doing it well
  • Do It Yourself Simply (DIYS)
  • No XML
  • No annotations
  • Minimum startup and shutdown cost – so that tests can run fast
  • Ease of assembly and deployment – so that tests are easy to setup

The new version of the application is built on top of Simple for the webserver, standard JDBC, Mustache Java flavor for the view templates, and my own small command line interface library. Everything else was test-driven developed. That is:

  • Object assembly,
  • Data mapping,
  • Transaction management,
  • Environment configuration,
  • Routing,
  • Serving static assets,
  • Access logs,
  • Layout templating

That new version does not follow the Servlet specification. It uses a simple web server and builds as a single jar with embedded configuration. Most things that were left to frameworks in the original version – namely transaction demarcation, objet assembly, wiring, routing, and database mapping – are done programmatically in the rewrite.

The Benefits of Simplicity

Built for Speed

One of the things I like the most about the new version is how fast it starts up. Startup time is down from around 6-7s on my machine for the Spring application to a negligible amount of time for the Simple version. That small startup cost makes a huge difference. It means the end-to-end tests run much faster. It also means re-deploying the application results in almost no service interruption.

The application is self-contained – it is packaged as a single jar – and has no external configuration. Configuration is bundled with the application – including test configuration. As a result, the end-to-end tests exercise the entire application through its main entry point, which results in greater test coverage. Self-contained configuration also makes it very easy to setup, startup and shutdown the application from the end-to-end tests. That means the application can be easily installed as a daemon as any other Unix tool.

Tests are blazingly fast, and that too makes a huge difference. End-to-end tests run 50% faster. They are down from 18s to 12s using Firefox and only 5s when run with PhantomJS. Database integration tests run under 1s compared to 3s in the original application. Configuring the tests for running on the test database is now straightforward. The best part is that database integration tests run so fast that it is no longer necessary to maintain a static test context. There is no penalty to bootstrapping the data mapping code on every test.

Doing simple has also tremendous benefits in terms of total cost of ownership of the application:

  • The cost of understanding the tools and technologies is low, which makes getting new team members up-to-speed much easier
  • The increased startup speed has lots of benefits on testing and solves re-deployment headaches
  • Smaller codebase size means reduced maintenance and communication costs
  • Simplicity of the design means cost of change is kept low
  • The explicit programming model makes codebase easier to follow and debug
  • All-in-one packaging reduces cost of deployment and configuration

Final Thoughts and Takeaways

That being said, the solution is obviously not very “enterprisy”. One legitimate question is to ask is whether there is anything in the frameworks that we would be missing. For example, we could question how the solution might scale up. One the other hand, if you rely on a large framework and at some point late in development you discover that the performance – memory consumption, reliability or anything else – is not as good as expected, you’re … screwed. There’s not much you can do except trying to rewrite parts of your application without the framework. On the contrary, if you develop your application incrementally with no framework and you keep it simple, then if at some point it’s not fast enough you are in a good position for applying whatever optimization is needed.

For some teams, using large frameworks is a belief that they’d rather use a proven solution than develop their own. If chosen well, they have a tested and stable component that works. They might wonder if they have the skills and knowledge to develop their own solution. Will it work as expected? How do we know for sure? How easy can we make it evolve as our needs change? How reliable will our solution be? Do we have the skills to come up with a good API design? etc.

Another question that arises is that you probably want to avoid solving problems already taken care of. If you can find a well-tested, well-crafted library that is easy to use and addresses the problem you’re trying to solve and just that problem, and if that library has minimal to no dependency, you might as well use it. Where to draw the line between doing it yourself simply and using an existing solution is a judgment call.

For the rewrite, I ended up using only few off-the-shelf libraries – mainly one for the web server, one for rendering HTML templates and one for parsing command line parameters. I chose libraries that I liked and that solved a single problem in a simple and elegant way – no less, no more. When I could not find a suitable library, I followed the Do It Yourself Simply principle and coded my solution. Some problems are not hugely difficult and you can solve them easily with few lines of code. As an example, the code that replaces SiteMesh in the new version of the application is no more than 100 lines long.

To avoid reinventing the wheel you can scan through the conventional framework code looking for special case handling that you wouldn’t have thought of. Also look at how the framework solves the problems you’re already aware of, to draw on as many good ideas as possible. The point is to steal the good ideas, and rewrite just the code you need in a simple way. With mastery of test-driven-development, you will be able to incrementally add as you need more. Of course, be careful to avoid turning your own solutions into large frameworks.

One last consideration is that frameworks allow you to do so many things quickly and that’s a very good point. One situation where it might be desirable to use a framework is when you don’t care so much about the code, for instance to do a proof of concept for a product idea.


I believe there is often an illusion that frameworks will help much more than what they do in reality. You tend to want to use more of what the framework has to offer to keep your project in the same ecosystem. You often have to twist your code until for it to fit the framework. You end up paying a hefty price for the added complexity, difficulties in test automation, learning curve, keeping up to date and upgrading. All of that adds to the cost of ownership of your codebase.

Staying away from large frameworks as much as possible will reduce your risk and increase your options. You can still add a framework later if you find you really need to.

Simplicity is the best way to keep your agility: speed of delivery and ability to change.

Simplicity is the ultimate sophistication. – Leonardo da Vinci

My blog is moving

I’m moving my blog to a new domain. I will now be at http://vtence.com.

Please update your bookmarks and feeds.

See you there!

Focus on solutions, not problems

One of the key ingredients to becoming a great team is learning to focus on solutions, not problems. Unfortunately, this is really hard and requires practice. As humans, our natural response is to do just the opposite. In this post, I will explore why this is so and share things you can do to help.

We tend to focus on problems

Over the years, I have trained teams to become great teams that build great software; I have coached product owners, managers and executives to adopt Scrum and move away from predictive thinking to empirical management. During my coaching work, I have consistently observed the natural tendency people have to focus on problems rather than solutions. If you take a moment to think about your own experiences, you might recall situations like these:

  • A meeting without a clear goal in which problems are discussed at length, even if that leads nowhere closer to a solution;
  • A Daily Scrum during which team members share the work they did, the technical difficulties they encountered, but fail to create a plan for the next 24 hours;
  • A one-on-one meeting in which a manager provides « feedback » to an employee, identifies weak spots and asks for improvements;
  • A code review session during which the reviewer describes what he does not like about his peer’s code.

It does not matter whether you are a CEO or a software developer, we all suffer from the same brain bugs. In order to become more efficient, whether as a team member or individual, you need to learn how to overcome them. To do so, it helps to understand what those brain bugs are and where they come from.

The brain tries to maximize rewards and minimize danger

Our brain has one overarching organizing principle:

It tries to maximize rewards and minimize danger.

It also registers negative emotions much stronger than positive ones. This phenomenon is known as the Negativity bias. Negativity bias is pretty easy to explain considering that our brain has evolved over thousand of years and that during most of that evolution period, surviving amongst predators was the only thing that mattered. Our brain has been optimized to react quickly and efficiently to threat responses, even though we do not always react the way we would like to.

Threat responses generate negative emotions. In his latest book, Your Brain At Work, David Rock explains that negative emotions put people in what he calls an away state. Away responses make people defensive and reduce their cognitive resources. It becomes harder for them to think clearly.

The brain is a prediction machine

Our brain is also a formidable prediction machine, as Jeff Hawkins describes in his book, On Intelligence. It is continuously trying to predict the outcome of future actions to make decisions. Considering this, you can understand why your brain hates uncertainty and actively seeks to reduce it. Uncertainty leads to the inability to make decisions. Too much uncertainty often results in being stuck in a decision process. The more complex the situation, thus the more uncertainty, the more your brain has to focus attention and process stimuli, an energy hungry process. Your brain hates to do that.

Uncertainty creates a threat response. So there is a natural biological response to reduce uncertainty.

The past has lots of certainty and the future has little

Unfortunately for us, the future has very little certainty. It is scary to the brain. This is why so many leaders look for definitive answers and have such a hard time with empirical management. They prefer to live in the illusion that predictive management can actually work.

On the other hand, the past is all about certainty. It is about facts, things that are known. It is much easier for the brain to talk about the past than make decisions about the future.

Consider now that solutions are generally untested, and thus uncertain. They live in the future. It takes effort for your brain to dampen down the threat response that comes with uncertainty. On the opposite, it is very easy to discuss problems, because they come from the past.

Some things you can try

Next time you end up in a meeting, pay attention to how people tend to talk about problems, rather than focus on solutions. Here are some things you can do to help people put the focus back on solutions:

  • Simplify the situation;
  • Consider the whole;
  • Minimize perceived threats;
  • Take a break.

Set clear and concise goals

You can simplify situations by stating clear and concise goals. To be helpful, a goal has to be stated using a simple language that is common to the team.

Simplifying the situation using a goal statement will help people generate insights (see The Eureka Effect) and move them toward solutions.

Consider the big picture

Consider the big picture (for the system thinkers out there, the system), rather than the details. Take a step back and then focus only on the parts of the system that are relevant to achieving your goal.

On that subject, have a look at that great talk from Eric Berlow: How complexity leads to simplicity.

Minimize threats

Be careful to minimize perceived threats. Remember that negative emotions are registered much stronger than positive ones.

You can minimize perceived threats by discussing the positive, rather than the negative. Discuss things that are working well, what’s good in what you are doing and engage in a dialogue about how you would like things to be.

Take a break

It is surprisingly easy to get stuck on a problem. This is known as the impasse phenomenon (The Eureka Effect).

Whenever you feel the group is stuck, take a break and do something light and interesting, to see if an answer emerges.

100% de couverture de code par les tests

Voici les slides de la session que j’ai donné à Agile Tour Montréal 2011 et à Confoo 2012.

L’idée maîtresse est de considérer l’objectif de 100% comme un objectif asymptotique et un état d’esprit. Cet objectif amène l’équipe à continuellement se dépasser et à améliorer entre autres, ses pratiques d’ingénierie, ses outils, son infrastructure.

Le résumé de la session est le suivant :

S’adonner au développement itératif et incrémental sans automatiser les tests, c’est s’engager sur la voie du Scrum Flasque (Flaccid Scrum pour reprendre l’expression de Martin Fowler). C’est voir petit à petit la vélocité de l’équipe diminuer, la dette technique s’accumuler, la livraison de valeur d’affaires cesser. La base de code devient progressivement intravaillable. Bref, la qualité se détériore et les coûts de maintenance de l’application explosent. L’automatisation des tests à tous les niveaux est essentielle pour livrer itération après itération du logiciel de qualité qui enchantera vos clients. Plus facile à dire qu’à faire, à priori. Et quelle couverture de code devrait-on viser ? Seulement le chemin nominal ? 70% ? … ou bien 100% ! Certains diront déjà, 100% c’est irréaliste ! Au contraire, cette session vous présentera comment viser … et atteindre une couverture de test de 100% en tirant profit des différents types de tests et en construisant vos propres outils de tests.

Les programmes de certification Scrum, comment ça marche ?

Au début de l’été, Eric et moi avons eu le plaisir d’être les invités du Visual Studio Talk Show, un podcast en français sur l’architecture logicielle animé par Mario Cardinal et Guy Barette. Cet enregistrement fut l’occasion de partager ma vision des programmes de certification offerts par l’Alliance Scrum et Scrum.org et de parler plus spécifiquement du programme de formation et certification Professional Scrum Developer pour Java.

J’ai été pendant 4 ans un Certified Scrum Trainer de l’Alliance Scrum. Pendant ces 4 ans, j’ai travaillé avec Ken Schwaber et enseigné Scrum à des centaines de personnes. L’année dernière, j’ai poursuivi l’aventure Scrum avec Ken en joignant Scrum.org après avoir été le premier formateur certifié par Ken pour donner le cours Professional Scrum Master (qui s’appelait encore à l’époque Scrum In Depth). Je partage dans ce podcast les différences de mission, de focus et d’approche de la certification que j’ai constatées entre les deux organisations.

La mission de Scrum.org est d’améliorer la profession du développement logiciel, afin que les clients adorent travailler avec nous et que nous soyons fiers de notre travail. En ligne avec cette mission, nous proposons un programme de formation et de certification pour les équipes de développement. J’ai développé avec l’aide de Marc-André Thibodeau, un développeur Java comme on en rencontre peu, ce programme Professional Scrum Developer Java en utilisant des outils et technologies libres. Offert en version 3 jours ou 5 jours, ce programme de formation offre une expérience intensive unique à une équipe qui veut apprendre à livrer sprint après sprint du logiciel de qualité qui enchantera ses clients. Dans le podcat, Eric et moi partageons les éléments distinctifs du programme Professional Scrum Developer Java et l’emphase particulière qui est mise sur l’automatisation des tests à tous les niveaux.

You need an Agile Product Manager, not an Agile Project Manager

When an organization starts using Scrum, it runs into tough questions. One question that is particularly challenging is:

Is the Scrum Master the Agile Project Manager?

What if you consider that it is not the right question to ask?

Scrum is about product management, not project management. A more useful consideration is that the Product Owner is the Agile Product Manager. Indeed, the Product owner is responsible for the ultimate direction and success of the product.

The job of the Product Owner is like the typical product manager’s job with an added focus on maximizing value, delivering just-in time, and optimizing the return on investment. The Product Owner maximizes value by collaborating with the Team and customers, by leveraging the entire Scrum Team and also by simplifying product absorption. The faster and more often the release, the faster and more often the creation of value. Where traditional Product Management using the waterfall will typically delay the realization of value, the Product Owner uses Scrum to maximize the flow of value and eliminate waste.

Like the traditional product manager, the Product Owner is responsible for many things, from market analysis and strategic product planning to release planning and sustaining the product. None of this matters though, until the product is actually released. Agile Product Managers, a.k.a Product Owners, help their organization quickly seize market opportunities while controlling risk. That is what agility is about from a business standpoint.

The Birth of Team Sosoft

Last november, I experienced the first Codapalooza as part of team Sosoft. This was the first event of its kind in Montreal. And it was amazing! Xavier already shared our experience as a team.

It was so much fun coding day and night in ruby using Rails 3 that we decided to carry on with the development of Hibou. Hibou is a social software designed to help community daycare centers manage their day-to-day operations. What do I mean by social software? Hibou is charity work, which has been driven by the will to help out Carrefour péri-naissance de St-Eustache.

Following the Codapalooza, we spent some of our spare time to give the application a decent look and feel and pack a bit more features. The latest Hibou is now available on Heroku. We’ve also made the source code available on Github. I plan to talk about what we’ve learned in a near future.

The next step now is to release version 1.0 of Hibou so that Carrefour péri-naissance can start using Hibou on a daily basis. You can track our progress on our product backlog. One thing you’ll probably notice is that it’s a bug-free backlog. Want to know more about bug-free backlogs? Nicholas blogged extensively about it here, here and here.

If you’re looking for an high-performing agile development team in the Montreal area, look no more and hire Team Sosoft. We can build the right software for you using Scrum and state-of-the-art software engineering and testing practices. Check out our offer.

How to change things when change is hard?

That’s the question the Heath brothers address in Switch. I had great expectations before reading the latest book from the authors of best-seller Made to Stick, and man, I was not disappointed. Switch delivers some very solid advice on the subject of change. It’s simple and powerful. It made me wonder why no-one had explained change to me that way before.

Switch presents the change challenge around an analogy borrowed from Jonathan Haidt in his book The Happiness Hypothesis. We have an emotional side, the Elephant, and a rational one, the Rider. Perched on top of the Elephant, the Rider seems to lead the way. But the Rider’s control is an illusion or at best precarious, for when the Elephant decides to go its own way, it easily overpowers the small Rider.

Change efforts often fail for a simple reason: the Rider cannot keep the Elephant on the Path of change long enough to reach the destination. When the Elephant stops moving forward, change fails. I can recall tons of personal examples when this occurred.

For change to occur, we need to appeal to both the Rider and the Elephant and shape the Path. Our Rider is logical, responds well to reason and facts and is useful for long-term planning and direction. Our Elephant looks for short-term gains and instant gratification. We need the Elephant to provide the energy and passion to get things done. If the Rider can keep the Elephant moving down a well prepared Path then there is a good chance for change.

Switch proposes a framework to guide us in situations where we need change to occur. The framework addresses each of the three parts of the change challenge:

  1. Direct the rider

    Provide clear direction to the analytical self, the Rider, to prevent over-thinking and wheel spinning. What looks like change resistance is often lack of clarity.

    Use the following tactics:

    • Find the bright spots

      Focus on the success stories around the change you wish to see; duplicate the things that are working.

    • Script the critical moves

      Make the key steps clear. Describe specific expected behaviors; don’t talk in terms of big picture.

    • Point to the destination

      Describe a compelling purpose and paint an inspiring picture of the future. Change will be easier if people know where they’re going and understand why it’s worth it. People will start thinking about how to make it happen.

  2. Motivate the Elephant

    The Rider will rapidly get exhausted if controlling the Elephant, the emotional side, against its will. For action to take place you need to bring the Elephant onboard. The Elephant might be slow to get going, but once in motion, it goes a long way!

    The tactics are:

    • Find the feeling

      Knowing we need to change is not enough for change to occur. We need to feel something to take action.

    • Shrink the change

      Make the change looks smaller. Big changes feel unattainable and spook the Elephant.

    • Grow your people

      Help people relate to an identity and shift to a growth mindset.

3. Shape the Path

Most change problems are about situations and not people. Instead of trying to change people, change situations to make the process of change easier. 

Use the following tactics:

* **Tweak the environment**

	Make the change as easy as possible by changing the situation. Situation changes result in behavior changes.

* **Build habits**

	Encourage new habits that reinforce the change. Automatic behaviors do no tax the Rider. Set triggers for change in the environment.

* **Rally the herd**

	Use group dynamics to your advantage. Help new behavior spread.

After reading Kotter’s Heart of Change and Bridges’ Managing Transitions, I find that Switch addresses change management in a clear, practical and engaging way. The book is full of stories that illustrate the behavior leaders need to adopt for sucessful change to occur.

If you’re a ScrumMaster in an organisation, I recommend you read the book. It will serve you well. And don’t forget to drop some copies on your high-level managers’ desks.

You need a ScrumMaster to change the old style

There seem to be a confusion between the role of the ScrumMaster and one of a team facilitator. Jason Little recently wrote that you might need a coach, not a ScrumMaster:

So what is a coach going to give you compared to a Scrum Master? Scrum talks about a Scrum Master as the team facilitator, someone who is there to protect the team, remove obstacles and help the team function better. Essentially the scope of a Scrum Master is local optimization for the team.

A coach, on the other hand, will be focused on optimization of the organization. Often they are working and thinking on multiple levels and deeper when team output is exposing other organizational dysfunctions.

I disagree. This is a misinterpretation of the role of the ScrumMaster. Scrum is a tool that an organization can use to address hard problems. It is a tool to foment change. An organization that decides to use Scrum to address its issues is choosing very hard work. Only few organizations will fully take advantage of Scrum. The remaining organizations will try to use Scrum and run into ScrumButs. ScrumButs are the reasons why they cannot take full advantage of Scrum to solve their problems and realize the benefits. Each ScrumMaster is responsible for fighting ScrumButs by maintaining the integrity of the Scrum process, even if it is in conflict with the organization. This is much more than a facilitator role, right?

Of course, when a ScrumMaster starts working with a team, he or she might act as a parent, teaching the team how to self-organize. As the team gets more mature though, the ScrumMaster will spend more time working with management on the ScrumBut backlog to remove the dysfunctions of the organization. The ScrumMaster is not a team facilitator, it is a secret change agent!

Start doing sprint reviews, not demos

There’s a misunderstanding I’ve noticed in quite a few Scrum projects. Teams use Scrum and at the end of their sprint they do what they call a “sprint demo”. It works out like this:

  • They demonstrate their increment of the product to the product owner
  • Product owner seats passively
  • Product owner accepts or rejects the increment
  • No modification is done to the product backlog
  • After a while the product owner is unhappy with the current state of the product and the progress being made

There is nothing like a sprint demo in Scrum. But there is a sprint review.

Scrum is empirical, meaning that there are inspect and adapt points along the way. The sprint review is the inspect and adapt point where the product increment, the most current product backlog and the current conditions are for inspection. The adaptation is the modified product backlog.

During the Sprint Review, the Scrum Team and the stakeholders collaborate about what was just done during the sprint and what are the things that could be done during the next sprints. The presentation of the product increment is not the goal. It is used to understand what should be the next sprint goal. The sprint review provides input to the next sprint planning meetings. One of the possible consequences of this evaluation is the decision to not proceed further with the development of the product. Another possible consequence is the decision to release the existing product.

Consider your next sprint review. If you get out of the meeting without a modification to your product backlog and an insight to your next sprint goal, it’s probably because you’re not inspecting and adapting. You might be suffering from the “sprint demo” syndrome.

Asking powerful questions to hire right

Many organizations spend a significant amount of time defining the experience, education, skills and other factors required for open positions. Most of the time, though, their hiring process fails to make sure they hire right. If you’re looking for a different way, you might be interested to know how it works at Pyxis.

This morning I sat down with François to prepare the first hiring interview of a candidate looking for a software developer position. We decided to not have a look at his resume just yet. Since one of our colleague had recommended the applicant, we trusted he was a good candidate and wanted to understand if there was a cultural fit.

We talked about the values, characteristics and behavioral traits we wanted to find in a potential colleague. We figured out we wanted someone who shared the following characteristics:

  • Accountable
  • Humble
  • Passionate
  • Intelligent
  • Team-oriented
  • Continuous improvement orientated

We then devised a series of powerful questions to help us figure out if the applicant was someone we wanted to work with. Below are some of the questions we used during the interview process. Keep in mind that those questions are no more than tools we used to orchestrate the conversation. How we frame the questions is decisive. To make sure we hire right, the questions have to be ambiguous, personal, and stressful:

  • Tell me why it is more important for you to be having this conversation with us, rather than being doing something else?
  • What are the things you hear yourself most often complain about in your current (or last) position?
  • What have you done to change the very things you complain about?
  • What would be an extraordinary accomplishment for you?
  • What is the greatest contribution that you plan to make to the organization?
  • What will you hold the organization accountable for?

With answers from the candidate to questions such as these, we now have a pretty good idea whether the candidate is a good fit for our organization or not.

The next step is to validate the technical skills of the candidate. I know of no other way to validate the skills of a developer than to orchestrate a conversation around code. So we will give the candidate an opportunity to show us what kind of developer he is through his code. But that’s another story.

Making good use of assertion messages in tests

Have you ever struggle with coming up with useful assertion messages in your tests? Well, I have; until not so long ago.

I remember when I started using JUnit. It was summer 2000, and I became addicted to writing tests first. I was already writing automated tests at that time, inspired by my lecture of Thinking In Java. Not using any automated unit test framework, I was writing my tests last in the good old main() function. I had to inspect the outcome of my tests for correctness each time I run them, and that was painful.

JUnit was a discovery that changed the way I programmed and approached software development forever. Central to xUnit frameworks is the notion of making the tests self-checking by using assertion methods, basically utility methods that evaluate whether an expected outcome has been achieved. Now I had a way to express the expected outcome, let the computer check it for me, and produce a useful message for me (and others) - the human readers - to help diagnose problems. One of the goals of automating tests is to use tests as documentation. In case of test failure, what you want is for the test to act as a tracer bullet, helping you understand very quickly what the problem is. Assertion messages play a role in this. A well-crafted assertion message makes it clear which assertion fails and what the symptoms of the problem are. Now that’s easy to say, the hard part is to figure out what the message should say.

As Nat Pryce and Steve Freeman explain in their book, during the test-driven cycle, after you make the test fail, take a moment to read the assertion message, ask yourself what the reader will get out of it, and adjust to make the diagnostics clear. They provide a number of best practices in the book to help with test diagnostics. One is about making the assertion messages explanatory.

I have long been in the school of thought that strives to have a single assertion per test method and as result, for a long time I felt no need to use assertion messages. If you use small and focused tests and name them well, the tests will tell you most of what you need to know to diagnose the problem. For example, when the following test fails:

calculatesGrandTotal() {
    String[] prices = { "50", "75.50", "12.75" };
    BigDecimal expectedTotal = new BigDecimal("138.25");

    for (String price : prices) {
        cart.add(anItem().priced(price).build());
    }
    assertThat(cart.getGrandTotal(), equalTo(expectedTotal));
}

the failure report can be considered enough to understand what the problem is:

Expected: <138.25>
     but: was <139.25>
	at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
	at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:8)
	at test.com.pyxis.petstore.domain.order.CartTest.calculatesGrandTotal(CartTest.java:53)
	...

Indeed, the name of the test tells us that the cart fails to calculate its grand total correctly. The assertion messages shows the difference between the expected and actual outcome. Yet we can make the diagnostics even easier for the reader by simply adding an assertion message to identify the value being asserted:

assertThat("grand total", cart.getGrandTotal(), equalTo(expectedTotal));

See how that helps:

grand total 
Expected: <138.25>
     but: was <139.25>

I’ve come to adopt that practice since reading Pryce and Freeman’s book. Assertion messages are not used as often as they should. They can really help make failure reports more helpful, whether you have a single or multiple assertions in your test.

Another help in making assertion reports clearer comes from using Hamcrest matchers and assertThat(). Consider the following example:

findsItemsByNumber() throws Exception {
    havingPersisted(product);
    havingPersisted(anItem().of(product).withNumber("12345678"));

    Item found = itemInventory.find(new ItemNumber("12345678"));
    assertThat("available inventory", found, itemWithNumber("12345678"));
}

In case of failure, here is what we get:

java.lang.AssertionError: available inventory
Expected: an item with number "12345678"
     but: number was "87654321"
	at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
	at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:8)
	at test.integration.com.pyxis.petstore.persistence.PersistentItemInventoryTest.findsItemsByNumber(PersistentItemInventoryTest.java:56)

which I hope make the point.

As Pryce and Freeman say, diagnostics are a first-class feature. I now do my best to make assertion messages helpful so that whoever has to change the code in the future will understand what the expected behavior is.

Change is the job of the ScrumMaster

I recently finished reading Community, the Structure of Belonging, by Peter Block. While reading the book, I could not help but draw parallels with what I teach about Scrum.

In his book, Block talks about the small group as the unit of transformation. I already wrote about Scrum as a tool to foment change. In the context of Scrum, the Scrum Team is that small group, that unit of transformation. It changes the context of work in a way that alters how we think, behave and thus work together, which in turn can radically improve performance. François shared a similar view recently on Scrum teams, compelling goals and performance.

Block also states that for real transformation to occur, it is not more or better leaders that we need, but more care and belonging. I’m often asked what role management plays in Scrum. People ask the question : “So in Scrum, that means we don’t need managers?”. Mike Cohn has already addressed part of that question in his last book, Succeeding with Agile, by saying that management has a key role to play by creating the right environment for self-organization to occur. To add to that idea, we can say that management task is to shift the context, so that it creates in the Team a sense of belonging and ownership. Engagement from the Team will come from care so we must be careful to choose care over speed or scale.

Scale, speed, and practicality are always the coded arguments for keeping the existing system in place.

Scrum is all about changing the existing system. This is why the ScrumMaster primary responsibility is to ensure the Scrum process is followed. He or she uses Scrum as a tool to ask powerful questions to spark off change.

The ScrumMaster job is to change the conversation. The ScrumMaster is initiator, facilitator and leader of real discussions. This is a leadership role about creating commitment and accountability, which are the building blocks of self-organization.

To make a difference we must start by naming the way things are, use powerful questions as a tool, and listen, rather than advocate or defend.

ScrumMasters, take the time to master the art of orchestrating conversations, for this is what your job is about.

Scrum is not about project management

I often hear people talk about Scrum as a project management framework. I don’t like that idea. Scrum is for managing complexity to provoke change. I don’t like the notion of Agile Project Management either. Nor do I believe in the Agile Project Manager.

Our conventional approach is to solve problems. In fact we love problems and we take pride in devising complex solutions. We operate on a belief that we can make a real difference with more or better problem-solving. It’s only natural then, that we think of products in terms of projects (project resonate with problem to be solved) and that we see Scrum as another approach to manage projects (hopefully a better one). In my experience, product developments that use Scrum as a project management approach rather than a tool to ask powerful questions to spark off change, do not make a real difference. They only manage to project the past into the future.

Scrum is about the art of the possible. It is when we start thinking in terms of products, people and possibilities that real change is possible. To make a meaningful difference in our software development efforts we have to embrace uncertainty (and the anxiety that comes along) and tap into the possibilities it brings. We have to acknowledge that we don’t have all the answers, and that we’re going to explore how to best meet our goals and that of our users.

Product vision and Strategic Design

When I coach Scrum teams, I usually spend a significant amount of time working with the Product Owner to teach her how to create an effective product vision, one that will act as a guiding light for the Scrum team and stakeholders.

I don’t want to delve into the details of product envisioning activities. I usually use a number of workshops and techniques to produce some (or all) of the following artifacts:

  • Elevator statement
  • Product box
  • Business goals
  • User goals
  • Value drivers
  • Key attributes and capabilities
  • Risk assessments
  • etc.

What I’m interested in talking about is the activity of defining the product quality attributes and how strategic design (in the Domain Driven Design sense) fits in. Thinking about the quality attributes is key to defining “done”. Product quality attributes give meaning to the product being potentially shippable.

Among the quality attributes, some will pertain to the external quality of the product, like usability, securability or availability for instance. Others will focus on the internal quality. This is the case of maintainability, modularity, evolvability, etc.

Yesterday, I was out for beers with my colleague Ernst Perpignand and Greg Young. Greg was in Montreal to give his Domain Driven course and we (at Pyxis) sponsored the event by hosting the course in our Laval office. Of course during the evening we talked about CQRS, Event Sourcing, write and read models and all the stuff Greg likes to talk about. Needless to say I had a great time.

Those discussions made me realize how important it is to communicate that context maps are strategic outputs of the product vision activities. There are good reasons why Eric Evans talks about strategic design when he discusses bounded contexts and distillation. He refers to the conceptual core of the system as the “vision” of the system. It is indeed the guiding vision for internal quality attributes of the product. Determining our own bounded context and its relationships to others is both a political and business decision. We need to understand where the potential for ROI lies to design and architecture in consequence.

Imposterizing checked exceptions

I have been frustrated many times by some of Java’s checked exceptions. I’m sure you can recall some of your own experiences where you wished a CheckedException was a RuntimeException instead.

Let me share a useful exception idiom that I’ve been using for a long time and on lots of projects, which I call the ExceptionImposter.

We all know the Java standard libraries use checked exceptions to signal problems that can only occur at runtime either if we have screwed up or if something really bad has happened - something we cannot do anything about anyway. Personally, since I use Java reflection capabilities a lot, I have to deal with the InstantiationException and the IllegalAccessException too often for my taste.

For example, whenever I want to dynamically instanciate a class, even if I know the code should never fail, the underlying Java code throws a checked exception and I end up with code that looks like this:

...
        try {
            return WebDriverFactory.class.cast(webDriverFactoryClass.newInstance());
        } catch (Exception shouldNeverOccur) {
            // now what?
        }    
        ...

If I know that the webDriverFactoryClass has a public no-arg constructor that does nothing, the code cannot fail. If it fails, it could be that something is wrong with my environment or that I made an error while programming the class. That’s something I will catch during my development cycle but that I don’t expect to occur afterwards. I cannot just ignore the exception, because if something really went wrong, the application will not behave correctly and I will have a hard time diagnosing the failure and finding the source of the error.

I know I must throw another exception and I want that exception to be a runtime exception because there’s nothing useful the calling code can do about the error. I can wrap the exception into some generic RuntimeException but that’s not very satisfying. It will not help me find the error and it will add another level of nesting and make the stack trace harder to read. I find we already have too many levels of nested exceptions which make framework exceptions very hard to read.

I could also write my own wrapper to rethrow a checked exception. It think it would be slightly better, since I can now name the error, but what still annoys me is that other level of nesting and the longer stack trace.

Instead, I use the ExceptionImposter to mimic the checked exception and turn it into a runtime exception:

...
    try {
        return WebDriverFactory.class.cast(webDriverFactoryClass.newInstance());
    } catch (Exception shouldNeverOccur) {
        ExceptionImposter.imposterize(shouldNeverOccur);
    }    
    ...

Here’s how it works:

public class ExceptionImposter extends RuntimeException {
        private final Exception imposterized;
      
        public static RuntimeException imposterize(Exception e) {
            if (e instanceof RuntimeException) return (RuntimeException) e;
        
            return new ExceptionImposter(e);
        }
      
        public ExceptionImposter(Exception e) {
            super(e.getMessage(), e.getCause());
            imposterized = e;
            setStackTrace(e.getStackTrace());
        }
      
        public Exception getRealException() {
            return imposterized;
        }
      
        public String toString() {
            return imposterized.toString();
        }
    }

As you can see from the following test case, the ExceptionImposter looks like the real exception as much as possible:

public class ExceptionImposterTest {
        private Exception realException;
    
        @Test
        public void leavesUncheckedExceptionsUnchanged() {
            realException = new RuntimeException();
            assertSame(realException, ExceptionImposter.imposterize(realException));
        }
    
        @Test
        public void imposterizesCheckedExceptionsAndKeepsAReference() {
            realException = new Exception();
            RuntimeException imposter = ExceptionImposter.imposterize(realException);
            assertTrue(imposter instanceof ExceptionImposter);
            assertSame(realException, ((ExceptionImposter) imposter).getRealException());
        }
    
        @Test
        public void mimicsImposterizedExceptionToStringOutput() {
            realException = new Exception("Detail message");
            RuntimeException imposter = ExceptionImposter.imposterize(realException);
            assertEquals(realException.toString(), imposter.toString());
        }
    
        @Test
        public void copiesImposterizedExceptionStackTrace() {
            realException = new Exception("Detail message");
            realException.fillInStackTrace();
            RuntimeException imposter = ExceptionImposter.imposterize(realException);
            assertArrayEquals(realException.getStackTrace(), imposter.getStackTrace());
        }
    
        @Test
        public void mimicsImposterizedExceptionStackTraceOutput() {
            realException = new Exception("Detail message");
            realException.fillInStackTrace();
            RuntimeException imposter = ExceptionImposter.imposterize(realException);
            assertEquals(stackTraceOf(realException), stackTraceOf(imposter));
        }
    
        private String stackTraceOf(Exception exception) {
            StringWriter capture = new StringWriter();
            exception.printStackTrace(new PrintWriter(capture));
            capture.flush();
            return capture.toString();
        }
    }