Tuesday, 26 May 2015

Testing Private Code

A common problem many people ask is - should you test private code? In short, you shouldn't. You should always test the public api of your code where possible. This is not always easy. Based on the context of the code in question there are a few options available.

Don't Test

Either don't test the private code or rely on manual testing. This will not be ideal in many cases, but if the code is covered in higher level tests you may be able to get away with it. If the code will be stable, short lived or low risk you can default to this option.

Test via Public Tests

Simply test the private code by adding assertions or verifications to exisiting public behaviour tests. If the setup requires a lot of work, many edge cases or much duplication you may want to avoid this technique.

Make the Code Public

Once public, the code is easily testable. Are we making this code public just for the sake of an automated test? Yes, but there are valid times to do this. Providing the behaviour is logically part of the object in question there is no harm, the single responsibility principle is not violated.

Interfaces can be used to control visibility here. For testing you always use a concrete instance, while your production code should hold references to interfaces only. To simply hide the method, don't add it to the interface. For dynamic langauges this is as simple as "don't invoke it" or relying on naming conventions to denoate implementation details.

Make a Public Class

When single responsibility principle would be violated in the technique above, this is your other option. Beware the power of just adding a new class and making it public. While it will allow testing in one place, each public dependency you introduce further increases coupling.

If the code that needs testing is a service, the act to introduce a public object should be considered thoughtfully. Once the class is pubic, you simply need to verify the use of the class, rather than what it does. However Value Objects can help limit the tests you need to write entirely and should be used whenever possible.

Wednesday, 20 May 2015

Mob Programming

I first saw this video of Mob Programming a couple of years back. Mob Programming is pair programming taken one step further, the whole team is based around a single machine. The developers rotate regularly and those who are not driving can add feedback, make suggestions or simply watch and learn. Everyone should be placed on a level playing field. I will admit to being highly sceptical of Mob Programming at first.

I advocate walking skeletons to ensure we are on the "right path" when developing. We wanted to do these as a team, during our planning and tasking phase. I suggested mobbing rather than watching a solo developer on a projector and it turned out to be quite fun. We also learned a few new tricks such as keyboard shortcuts or IDE techniques along the way.

There were a few rough edges, mainly due to the setup used. A laptop around a screen proved difficult and this in turned seemed to put pressure on individuals. In repeat sessions we have used a dedicated space, with a proper machine and large screen or projector. The ten minute rotation is enough to allow focus, while not being too long between switching.

While Mob Programming is a relatively new experience for myself, it is proving quite valuable as technique to help develop a walking skeleton. Currently we have not used Mob Programming for full time development. As it stands, I would find it hard to recommend this for some development tasks. Additionally I can think of developers and managers that would simply resist any suggestion of mob programming. Unfortunately for some teams this may be too much of a hard sell.

The end result of a mobbing session is a task board filled up with minor tasks such as improving test coverage, refactoring, or edge cases. The core functionality is delivered as a team. Combined with the walking skeleton Mob Programming solves some of the key problems that traditional tasking and planning introduces and is well worth an experiment.

Tuesday, 12 May 2015

Walking Skeleton

A Walking Skeleton is the thinnest possible slice of new functionality that can be delivered end to end. The term "walking" refers to the ability for the feature to "stand on its own". You should be able to deploy a Walking Skeleton and demonstrate it. Just like a human skeleton is an incomplete body, a Walking Skeleton is an incomplete piece of software with many internals stubbed, not implemented or consisting of basic functionality.

While the software won't do much it provides rapid feedback. It allows your build and deploy pipeline to be set up if not already in place. More importantly it gives developers a framework or scaffold to work with.

Production of a Walking Skeleton should be fast. Components such as which objects to introduce should ideally be developed top down, however the actual direction each solution takes will vary. Some design will still be required, but the choice of patterns or implementation details should be deferred where possible. Core interfaces such as application services, domain models and data access will naturally fall out of this process.

Tasking

Each new story or feature should be implemented as a Walking Skeleton whenever possible. The first task a team should implement should be to create the skeleton itself. An optional step during implementation is to wrap the functionality in a acceptance test. Once the skeleton is complete, a task per object can be created with clear inputs, outputs and responsibilities.

Benefits

  • Highlights problems that tasking often misses.
  • Tasks can be implemented in parallel once a framework is in place.
  • Implementing or replacing stubbed code is easy given a stable API.
  • Provides working software very quickly and cheaply, which is great for feedback or exploration.
  • Puts the whole team on the same page.
  • Code trumps documentation.
  • Leads to a more stable API.
  • TDD is a natural fit once the skeleton is complete.

Producing a Walking Skeleton is not perfect, problems still crop up, but they can be handled in a more controlled manner. Most issues relate to implementation details at lower levels, rather than integration or functional failures which are often symptoms of tasking before writing any code.

Wednesday, 6 May 2015

Tasking in Software Development

Tasking is core part of XP, Kanban, Scrum and other software development methodologies. It is required when more than one developer is working on a feature. I consider it to be the most wasteful part of the development process as practiced in the mainstream.

Tasking typically involves the team sitting around a machine/desk/whiteboard/projector. From past experience this can take anywhere from an hour up to a day or more. Engagement is often low and this process can be both mentally and physically tiring. During which many assumptions about what should be done is made.

The end result is nothing but index cards, scribbled diagrams or other lightweight documentation. These artifacts are often transformed into digital versions.

Problems

The foolish understanding is that now any developer can pick up a task and start work. This leads to dependent tasks being worked on in an independent manner. Team members then find themselves being impeded until a certain piece of code is in place. No amount of swarming or pair programming can help in most cases.

The biggest failure that poor tasking encourages is a task board with numerous items moved to complete, yet the actual functionality is broken and stood no chance of working. In my past experience, this is unfortunately very common.

An equally common scenario is when task cards are stationary for long periods, until they all move across to "done" very suddenly. This is usually a symptom of a unidentified problem or change coming into play.

Ultimately poor tasking results in waste.

Solutions

Due to the frustrations of experiencing these problems week after week, across numerous teams, I have experimented with a variety of solutions.

Possibly the most controversial and difficult to sell is to have small enough stories and features that mean a single developer/pair can work on. Tasking becomes organic, just part of the day to day work. A simple check list of tasks can suffice here. Both team members stay in sync because the overhead of other team members has been removed. Ultimately you still need to integrate these small(er) features but there are ways to slimline this.

A less dramatic solution is to task in a ad-hoc basis, per story/feature and limit WIP to include tasking. In other words, if you are aiming to deliver three features over several weeks, task the first feature and move onto coding. If during this coding phase you change plans or discover a problem, limited work is lost. Additionally tasking in smaller chunks is better for the teams' morale.

The two other solutions are the most powerful at combating the tasking problem I have described, these are to utilize a Walking Skeleton and try Mob Programming. Both of which will be detailed in future posts.

Tuesday, 28 April 2015

Getters and Setters are Evil - Redux

Back in early 2011 I wrote one of my most viewed and commented posts at the time - Getters and Setters are Evil. Four years later it's time to review this.

The feedback within the team was generally positive. Production code was written in this style to great success. The core benefit was encapsulation was preserved as Business Objects were the sole source of domain logic. As an additional side effect testing was easier.

However not everyone within the team agreed that the benefits were worth the extra hassle or believed in the benefits of encapsulation. I always found the addition of an IRender interface or similar broke the SRP, even if you moved the logic to a separate class. The OCP suffered too, if view requirements changed, you need dig out your business object. The biggest failing is that legacy code and frameworks still require public getters/setters to function.

Overtime I found myself and others slipping back to the "old ways" of applying getters/setters without thought.

2015

I now simply use two models, where the used to be one. Changes go to the domain model in the form of commands. Queries get returned as view models. The big change here is to simply split commands from queries and embrace the second model, everything else falls into place. This style works without a rich domain model also. The commands can be expressed as Transaction Scripts or similar if desired.

This is not new, I've applied this style in the past, but the big difference is the business object is never mapped or converted into a view model. There is no relationship between the two. They are two distinct paths in the code. This is the difference that CQRS brings - limited coupling.

Benefits

Encapsulation is preserved as before, but the view model can be tailored to requirements. SOLID principles are not broken, while still having the huge benefit of playing nicely with frameworks due to exposing public getter/setters in order to facilitate model binding.

Getters and Setters are not evil as I've concluded before. It just turns out there are better ways of embracing the benefits of thinking they are evil.


The term Business Object is also known as Domain Object. The later being my preferred term now. I stuck with the original terminology to match the original post's code example.