As the cloud computing and SaaS revolution continues to drive the adoption of microservices and approaches like continuous delivery among ISVs, product engineers are looking for every possible opportunity to deliver higher quality software faster — and for less cost.

One approach product engineers can add to their growing DevOps toolkit is fitness function-driven development, or FFDD.

An evolution in test driven development

This recent approach actually has roots in test driven development (TDD). When I first heard of TDD earlier in my career as a software test engineer, I thought it made sense. From my perspective, testing should drive development, rather than serving as the afterthought it often was at the time.

To give you a sense of how TDD works, picture two windows of an IDE open, side by side. A test script is written in one window with conditions to pass, and then the code is subsequently crafted in the other window, with the intent of passing the test.

Fitness function driven development (FFDD) is a variation on test-driven development that encompasses validation of business outcomes along with testing alignment to architectural goals. FFDD serves the same purpose as traditional TDD, in that it allows for testing to inform development and to provide a continuous feedback flow, but it also has the advantage of collecting input from stakeholders and forcing early discussions regarding trade-offs.

Fitness function driven development at work

We’ve all seen what happens when these tradeoffs aren’t discussed early on: Product development teams end up chasing goals and always remain one step behind. For example, focusing on the rapid addition of features increases technical debt by sacrificing performance or compromising security. This creates a vicious cycle where every release is focused on chasing down the unintendend consequences of what was ignored in the previous sprint.

FFDD ensures all project leads and development teams understand what is being accepted and what tradeoffs might result before coding begins.

Below are some examples of fitness functions:

  • Code Quality
  • Resiliency Testing
  • Performance Testing
  • Compliance Standards Testing
  • Security Code Analytics
  • Operability Standards

How does this all work when the “rubber hits the road” and it’s time to implement FFDD? The answer is quite simple: continuous integration, in the context of a continuous delivery pipeline. Automation and code should be written to validate these fitness functions at every phase in the cycle as they progress towards promotion of the code base to a final iterative build.

Here are a few examples of FFDD at work:

Logging

Let’s begin with one of these fitness functions, Operability Standards, and in particular, logging. In many software development circles, logging is often added as an afterthought. With FFDD, before any feature is promoted to production it must be validated for operability standards, like ongoing support.

Verifying proper documentation, log creation and known limitations prior to production will ensure operability and support costs and problems are minimized later in the cycle.

ArchUnit library for Java code

We can also utilize FFDD concepts and techniques to test common architectural patterns and enforce standards. For example, ArchUnit library is useful for checking the architecture of Java code, automatically testing architecture and coding rules, using any plain Java unit testing framework.

The Library API offers predefined complex rules for typical architectural goals, and can check dependencies between packages and classes, layers and slices, cyclic dependencies, annotations and more.

NetArchTest for .Net frameworks

NetArchText is a fluent API for .Net Standard that can enforce architectural rules in unit tests. Developers can create tests that enforce conventions for class design, naming and dependency in .Net code bases within any unit test framework and can be incorporated into a build pipeline.

NetArchTest It is a .Net Standard 2.0 library that is compatible with .Net Framework 4.6.1 or better and .Net Core 2.0 or better.

Removing technical debt from software development processes

Building FFDD into your continuous delivery approach will ensure you have the correct checks and balances in place in order to verify your organization’s architectural goals, reducing unintended consequences, increasing code quality and reducing technical debt.

Just as TDD has introduced testing earlier in the development cycle, revented costly defects found later, FFDD forces decisions and trade off discussions to occur earlier in the cycle before resources are committed while also serving as a constant check during the normal development process.

As the pressure on software development teams to deliver better software faster grows, FFDD is a valuable approach to ensure code quality doesn’t suffer as speed increases. 

Vist our website to read more about Persistent’s digital product engineering capabilities.