Scala

Test your Dependencies with Degraph

I wrote before aboutĀ (anti)patternsĀ inĀ packageĀ dependencies. And of course the regular reader of my blog knows aboutĀ Degraph, my private project to provide a visualization for package dependencies which can help a lot when you try to identify and fix such antipatterns.

But instead of fixing a problem we all probably prefer preventing the problem in the first place. Therefore in the latest version Degraph got a new feature: A DSL for testing Dependencies.
You can write tests either in Scala or in Java, whatever fits better into your project.
A typical test written withĀ ScalaTestĀ looks like this:

 

classpath // analyze everything found in the current classpath
.including("de.schauderhaft.**") // only the classes that start with "de.schauderhaft."
.withSlicing("module", "de.schauderhaft.(*).**") // use the third part of the package name as the module name, and make sure the modules don't have cycles
.withSlicing("layer",
("persistence","de.schauderhaft.legacy.db.**"), // consider everything in the package de.schauderhaft.legacy.db and subpackages as part of the layer "persistence"
"de.schauderhaft.*.(*).**") // for everything else use the fourth part of the package name as the name of the layer
) should be(violationFree) // check for violations (i.e. dependency circles)

The equivalent test code in Java and JUnit looks like this:

assertThat(
classpath() // analyze everything found in the current classpath
.including("de.schauderhaft.**") // only the classes that start with "de.schauderhaft."
.withSlicing("module", "de.schauderhaft.(*).**") // use the third part of the package name as the module name, and make sure the modules don't have cycles
.withSlicing("layer",
new NamedPattern("persistence","de.schauderhaft.legacy.db.**"), // consider everything in the package de.schauderhaft.legacy.db and subpackages as part of the layer "persistence"
"de.schauderhaft.*.(*).**") // for everything else use the fourth part of the package name as the name of the layer
),
is(violationFree())
);

You can also constrain the ways different slices depend on each other. For example:

…
.withSlicing("module", "de.schauderhaft.(*).**").allow(oneOf("order", "reporting"), "customer", "core")
…

Means:

  • stuff inĀ de.schauderhaft.orderĀ may depend on de.schauderhaft.customerĀ andĀ de.schauderhaft.core
  • the same is true for de.schauderhaft.reporting
  • de.schauderhaft.customerĀ may depend on de.schauderhaft.core
  • all other dependencies between those packages are disallowed
  • packages from and to other packages are allowed

If you also want to allow dependencies between theĀ orderĀ slice and theĀ reportingĀ slice replaceĀ oneOfĀ withĀ anyOf.

If you want to disallow dependencies fromĀ reportingĀ orĀ orderĀ tocoreĀ you can replaceĀ allowĀ withĀ allowDirect.

SeeĀ the officialĀ documentationĀ for more details, especially all the options the DSL offers, the imports needed andĀ how to set up DegraphĀ for testing.
I’m trying to get Degraph into maven central to make usage inside projects easier.
I also have some changes to the testing DSL on my to-do list. And finally I’m working on a HTML5 based front end. So stay tuned.

Reference: Test your Dependencies with Degraph from our JCG partner Jens Schauder at the Schauderhaft blog.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Back to top button