Implementing architectural fitness functions using Gradle, JUnit and code-assert

Architectural fitness functions

Inspired by Neal Ford’s presentation at our Change is the Only constant event I started experimenting with architectural fitness functions. An architectural fitness function provides an objective integrity assessment of some architectural characteristic(s).

If you want to take a deeper dive into evolutionary architectures including fitness functions take look at Neals book: Building Evolutionary Architectures: Support Constant Change.

Neal’s slides contained an example of verifying package dependencies from a Unit Test using JDepend.

 

Verifying code modularity

In this blog post we’ll elaborate on that approach and create a Unit Test that verifies that our code complies to the chosen packaging strategies using an alternative to JDepend named code-assert.

We’ll verify two types of packaging strategies; package by layer and package by feature. For a definition of these strategies please have a look at this blog from Simon Brown.

Creating the fitness functions

To illustrate both types and their fitness functions I created a small demo project that contains a package structure for each of this strategies containing dummy classes/components.
Needless to say that this is for demonstrating purposes only and normally you would choose only one packaging strategy for a project and stick to that, preferable package by feature ;)

Code packaged by layer

Code packaged by feature

Adding code-assert to our Gradle project

Lets start by adding the dependency to code-assert to our Gradle build file dependencies.

Configuring code-assert for Gradle

Update: as of version 0.8.4 code-asserts now supports Gradle with AnalyzerConfig.gradle() directly.

The first step in each Unit Test is to configure code-assert and specify where the sources and classes resist on our filesystem. For Maven code-assert includes an easy way to create this configuration but it lacks this feature for Gradle (for now). I’ve created a GradleAnalyzerConfig class which you can use to create the correct configuration. A pull request to the code-assert project is on it’s way.

Verifying package by layer

Now we can create a Unit Test that will verify if our code is packaged by layer.

If we execute this Unit Test it will pass because our demo code complies with the specified rules.

Now we modify the code by accessing a Repository directly from our Controller and change App.java accordingly.

Execute the Unit Test again and it will fail, because we violated our rules by accessing the Repository directly from our Controller:

Verifying Package By Feature

The following Unit Test will verify our package by feature strategy:

The Unit Test is almost identical to the previous one, the rules are even less complicated. We allow our App class to access all, that’s it. There are no dependencies allowed between packages a and b.

But what if we need to use ServiceB from ControllerA?

Initially our test will fail:

But if the dependency is really needed and we really thought this through we make this explicit by changing the Unit Test and adding the following rule:

Bonus: a cyclic dependency test

Adding the inter package dependencies might lead to a cyclic dependency. Using code-assert it’s easy to add a Unit Test that detects this:

Demo source code

The source code of the demo project is on GitHub: https://github.com/robbrinkman/architectural-fitness-functions

2 thoughts on “Implementing architectural fitness functions using Gradle, JUnit and code-assert

Leave a Reply

Your email address will not be published. Required fields are marked *