Program Specification Through the Mechanism of Automated Tests

December 7, 2009

My previous findings regarding the testing of public methods versus private methods opened the door to allow me to better understand that the mindset of a developer performing unit “testing” is different from the mindset of a developer “specifying program behaviour through the mechanism of automated test methods”. The difference is subtle but important.

In the concept and terminology of Behaviour-Driven Development, Design, Analysis and Programming, the resulting program code is simply an implementation of previously specified behaviours. Those said behaviours are initially defined at the business level via the process of requirements gathering and specification, and can be expressed in the business’s language as a set of scenarios and stories. These requirements can then be further analysed and broken down into logical and physical program specifications.

Regardless of whether a test-first approach to development is taken, by the end of the construction task, there should be a set of unit test cases (automatic and/or manual) that were successfully executed and that covers all of the logic specified in the program specification. In other words, by the end of the construction task, the developer has verified that the program behaves as specified.

Typically a program’s specification is written in a document somewhere which is divorced from the location of the actual code -  so great discipline and effort is required in order to keep the specification and code in synch over time. Depending on the company and financial constraints of the project, this may not be feasible.

However, what if we could remove this boundary between the document and the code?

Automated test cases serve a number of useful purposes, including:

- Behaviour verification;

- Acting as a “safety net” for refactoring code;

- Regression testing;

- Professional evidence that one’s own code actually does what one has said it does; and

- Acting as sample code for other developers so they can see how to use one’s code.

What if the automated test assets were the actual living program specification that is verified through the mechanism of test methods?

This concept has been recognised before, and the libraries JBehave, RSpec, NBehave and NSpec have been the result. While I honour the efforts that have gone into those libraries and the ground-breaking concepts, I do not necessarily like the usage of them.

In fact, all I want is to be able to express my specifications in my MSTest classes without the need for a different test runner or the need for another testing framework. In addition, I want other team members to easily grasp the concept and quickly up-skill without too much disruption.

While a DSL might be more ideal under these circumstances, I write my automated test assets in the C# language. Working within that constraint, I want to express the program specification in test code. With special note to the agreeable BDD concept that “Test method names should be sentences” I devised the following structure for expressing program specifications as automated test methods.

namespace |MyCompany|.|MyAssembly|.BehaviourTests. |MyClassUnderSpecification|Spec

{

public class |MyPublicMethodUnderSpecification|Spec

{

[TestClass]

public class Scenario|WithDescriptiveName|

{

[TestMethod]

public void When|MoreScenarioDetails|Should|Blah|

{

// Test code here

}

[TestMethod]

public void When|AnotherSubScenario|Should|Blah|

{

// Test code here

}

}

}

}

This structure allows for the naming of the public method that is under specification (the parent class name), a general scenario with a description of the context or given setup required (the nested MSTest class name), followed by the test method names which further narrow the scenario and provide descriptive details of the expected behaviour.

The test names look neat in the Test View in Visual Studio (when the Full Classname column is visible), and are readable just like their corresponding stories.

The full class name in this instance would look like:

|MyCompany|.|MyAssembly|.BehaviourTests. |MyClassUnderSpecification|Spec. |MyPublicMethodUnderSpecification|Spec +Scenario|WithDescriptiveName|

With automated spec/test assets/classes structured in this fashion, instead of developers performing unit “testing”, developers can instead embrace the mindset of “specifying program behaviour through the mechanism of automated test methods”. In turn, developers should be more focused on their tasks and it should also lead to higher quality code bases.

Oh, and I haven’t even mentioned how much easier it would be for a developer new to a project to learn and understand the code base by looking at the test view and reading all the scenarios that have been specified and coded…


Towards Behaviour Driven Programming – Part 2

July 13, 2009

Today a small team of three had a post-iteration meeting, and for the first time within the company (I dare say), there was agreement about the benefits of BDD/TDD when automated tests are required. The team agreed that it takes significantly longer to retrofit automated tests than it does to do the coding and testing in a BDD/TDD fashion.

The main reason is because when BDD/TDD practices are followed, the code is designed cleanly from the start and it tends to naturally follow best practices. When tests were retrofitted, the code typically has to be refactored/restructured and sometimes even completely rewritten so that the test cases can be properly identified and then written.

This is a hard-earned and yet relatively small victory, and after a long amount of time, suffering and battling, I’m telling everyone who’ll listen!

One step closer… critical mass… you are now in my sights! 


Towards Behaviour Driven Programming

July 13, 2009

Yes, I am a Behaviour Driven Development (BDD) man – and in this post I am limiting my discussion to Behaviour Driven Programming – the reframing of the very badly named Test Driven Development (TDD) practice. If in the future I find a better coding practice, I will switch to it, but at the moment this is the best I’ve found. I don’t necessarily follow the practice to the letter, but I do exude the spirit of BDD.

In case you are unfamiliar with it, BDD (and its predecessor TDD) are all about developers designing their code – code that is simple to use, simple to maintain, squeaky clean, follows best practices (like SOLID development principles), and it just happens to result in the very welcome side-effect of an automated test asset suite. If you don’t understand the benefit of automated tests already, then… I am sorry…

For almost two years now, I have been attempting to up-skill and convince various developers and teams and management at work about the benefits of BDD. The slow progress that has been made at work in no way correlates with my efforts – it is quite difficult to change the culture of teams. However, slowly and surely, I am happy to say that progress is being made.

Late last Friday night, I was showing a well-intentioned developer how he could perform behaviour tests on his code. We started by trying to retrofit the tests to his code, but it was quite smelly to say the least. In addition, because of the structure of the code, we were struggling to identify the valuable test cases we would create. In my disbelief, I quickly reached the point where I blurted out something along the lines of “if it were written using BDD/TDD practices in the first place, then we wouldn’t be having this trouble” – and it was true.

FLASH! It was one of those defined moments in history. I almost didn’t realise what I had said, but then it sank in… and the door reopened to showcase the power of BDD/TDD…

We then scrapped most of the pre-written code, and in a Pair-Programming style I walked the developer through the process of how to write clean code and perform unit testing with the practice of BDD/TDD. The resulting code was clean, intuitive, highly maintainable (as it read like a story), and was easily tested.

We compared the code that he had written with the new code, and there was no contest – the BDD/TDD code was significantly better, and the tests were easy and quick to create.

BDD/TDD is the unavoidable “pit of success” that enables the writing of clean, high quality code with automated test cases.


Follow

Get every new post delivered to your Inbox.