TDD and Architecture

Let us first look at the TDD and why I feel it is right way to develop functionality. To start with let me just ignore TDD as if it does not exist but obviously I do believe writing unit test cases is worth the effort.

So I have done my design, written my implementation as per the design and now I am writing the unit test cases to test out every possible scenario and then I realize I am not able to unit test a scenario until I modify the code to get it more suitable and enabled for testing. I modify my code to make it available for testing but then we know if our code is not testable, it is a flaw in the design and the design itself should have been such to allow for it to be tested. So I need to modify the design.

So in a way my tests are driving the way the code is written and eventually the design hence why not start with the unit tests at the very first place rather then going through an unnecessary loop and that is what is TDD (or more aptly TDDAD – Test driven development and design).

But then can we just stretch it even further and have my test cases drive the architecture of the system as well. Not really

1. Architecture by definition has much wider scope and relevance then may be just the design of few classes. It is a decision which is taken at a team and solution level and not merely confined to the reasoning being done at the pair programming level.

2. We need to get some basic architecture in place as part of zero iteration which takes in account just enough skeleton in place from which we can start building. We need to ensure we are pretty confident of this basic skeleton as it will be one of the hardest stuff to alter later in the future iterations and will have quite a strong consequence whenever we plan to do it.

3. Architecture decisions are very hard to postpone as something like going for a typical n-tier architecture or may be for SOA or in some case opting for a third party off the shelf solution or the very latest GAE as PaaS solution has to be taken upfront and cannot be delayed for a point in future

Not to say that we need to do big upfront architecture but still the bare bones or the minimal set has to be in place and then let the design evolve

Keep refactoring seperate from reconstruct

Refactoring we all do all the time, be it due to change in requirement or for that matter even when the requirements are pretty constant and not change much still we need to keep on evolving and improving the code and design to remove the smells and pain points and our knowledge of a better design.

How many times we are able to code it right the first time around, I never did. Generally we start being very messy and then keep evolving and changing the code with small improvements and that is for me what I call refactoring so in a way it should not be treated in anyway different from implementation or development of a piece of code and this is especially true while doing TDD. Do we ever need to keep some time aside for refactoring, no never. In fact over the period for me it is a little blurred to treat it as a separate activity by itself. Should be done continuously and in small increments

But sometimes it gets bigger then that, when we might have to alter the public API for example or may be a something which will effect our commitments to the sprint goal or even effects the timeliness for a release. This is what I call reconstruct or restructuring which requires a timeslot and a new story to be created within the product backlog.

Do we solicit feedback on non functional requirements?

Most probably no during our showcase of the stories after the release of a workable software each time and most probably this could be also one of the reason for the growing items within technical debt.

These are the requirements which is beyond any functional need as such but more about the characteristics and behavior (expected) of the system and is often ignored while creating the product backlog to start with and thus never features as a story in any of the sprints. There are more of expected way the system should work or the -ilities of the system as such. Very sure this is a mistake which I have seen happening quite often especially to the team which are just adopting Agile.

Just wondering what could be the reason for not tackling non-functional requirements the same way we tackle the functional requirements and why even at the very first place we term them non-functional.

Should SLR be enforced

Why not? SLR (Single Responsibility Principle) part of SOLID should be enforced as part of the code and design reviews more as an adherence to guidelines rather then a rule.

There has been a lot of debate over the possibility of applying the SLR from the very start of the development and then continue to maintain it over the period where your design evolves which as I have experienced is difficult as may be acceptance to TDD or Pair Programming was to start with, but it has to be developed as a habit and the benefits will follow. It is easy to understand but can get quite tricky to implement at the very start. How it helps is

  1. One reason to change for a class means complexity of the code is highly reduced
  2. Code is decoupled making it easy to evolve
  3. Ease for testing the code
  4. Each class has a well defined and thought through purpose for its existence

As always there is a tradeoff as it might create a little bigger codebase with a lot more classes as soon as we start assigning single responsibility to each and keep on refactoring the code to do that but even then it will be much more maintainable and readable. Also it might take a little bit more time to get a hang of it and might not be as relevant for quick and dirty POCs but then those are never supposed to be deliverable working piece of software.

So no doubt an excellent principle to follow as a guideline but then is there is a limit and should not be enforced as a rule while doing a code/design review and when I say limit, there is a limit to clarity of code which you can bring in keeping the code consistent, a limit to break down the code in separate classes which share a very similar purpose, a limit to how much you want to adhere to it still developing stories at the breakneck velocity being demanded because of business reasons and a limit o isolate and encapsulate cross cutting concerns like logging or exception handling etc.

Mocking private methods while testing

Having been working with mocking frameworks for quite sometime, mostly easymock, I always wondered some way of mocking the private methods and then testing them in isolation as I would do for any non-private methods. There has been no direct support for doing this in any of the popular mocking frameworks till now. So I was left with very few options

  • Make them protected ( a hack as this is going to break my design and encapsulation), thus making it available to test in isolation. Also now I can override that method with an empty implementation while testing other public/protected methods which makes a call to this method, thus in a way trying to stub it.
  • Leave them as private and have them tested as part of another method test so that it is covered as part of code coverage tool, but still has no way of testing it in isolation and also at the same time it might get executed multiple times if it is invoked from multiple methods

But recently I came across another mocking framework powermock which is sort of extension on top of easymock to allow mocking of not all private methods but also of static methods, constructors, final methods etc. It uses bytecode instrumentation and a custom classloader to do this which is OK but a little more intrusive then what I would have liked.

There is good enough documentation to depict how to mock private methods here . Also it provides some useful reflection utilities which can be used in unit testing private methods, some examples of which can be found here

Waste Elimination

Waste by definition, is garbage or rubbish and elimination of it quite literally means removing the bad, rotten, stinking practices from our software development process and code smells (a side effect of not eliminating the rubbish) from our implementation.

When we talk about lean manufacturing or more precisely eliminating the waste, then essentially what we are talking about is

  • Delivering what makes sense to the customer and nothing more, as anything more is a waste. Try and help the customer distinguish between what he really needs against what he might need.
  • Keep paying off the technical debt as soon and as much as possible. I consider paying off technical debts as synonymous to eliminating waste.
  • Keeping a constant flow of work and working at a sustainable pace, eliminating the chance of dip in productivity, quality and motivation.
  • More lines of code when less can do, is a waste. How often we have looked at a big massive codebase and thought to ourselves. What a waste? Get rid of it and every time I have a done it I have felt very good about it. Just think of it as if removing even few grams of weight from your backpack while travelling on an adventurous trip. Code light and it will definitely pay off
  • Eliminate the artifacts which states what we are going to do, by really doing it. Non working, out dated artifacts is something we should always avoid
  • Eliminate specialist roles as that would promote collective ownership and passion to collectively work for the success of the project.

A big part of being agile is doing ‘Just Enough’

Just Enough Requirements: The idea is not to get down to the finest details up front, capture just enough information which will enable team to estimate the development time for the requirement (in a form of user story) with a window to have a discussion with customer at a later time for the needed functionality. By going lazy with the requirement gathering, we are sure what is being developed is really what the customer want. Guy Beaver supports this in his article on The Challenge of Enterprise Requirements Management

The suggested solution is to replace early detailed specification with solution road maps that can be detailed by collaborative teams at just the right time. Agile methods provide the structure and mechanics to allow business vision to lead product development with cross-functional teams that unfold detailed requirements when needed

Read the rest of this entry »

Posted in Agile. 1 Comment »
Follow

Get every new post delivered to your Inbox.