$30 off During Our Annual Pro Sale. View Details »

Test your architecture with Archunit

January 24, 2022

Test your architecture with Archunit

Workshop on archunit


January 24, 2022

More Decks by Yoan

Other Decks in How-to & DIY


  1. @yot88 Test your Architecture with ArchUnit

  2. @yot88 Your current software architecture In group, discuss what are

    your current architecture rules inside your team and how you ensure that your code is always matching those rules Examples : All our events must reside in the events package Our repository layer can only be accessed through our application layer …
  3. https://www.archunit.org/ ArchUnit is a free, simple and extensible library for

    checking the architecture of your Java code. It does so by analyzing given Java bytecode, importing all classes into a Java code structure. ArchUnit’s focus is to automatically test architecture and coding rules, using any plain Java unit testing framework.
  4. @yot88 “Once upon a time somebody experienced looked at the

    code and drew up some nice architecture diagrams, showing the components the system should consist of, and how they should interact. But when the project got bigger, the use cases more complex, and new developers dropped in and old developers dropped out, there were more and more cases where new features would just be added in any way that fit. And suddenly everything depended on everything, and every change could have an unforeseeable effect on any other component. Of course, you could have one or several experienced developers, having the role of the architect, who look at the code once a week, identify violations and correct them. But a safer way is to just define the components in code and rules for these components that can be automatically tested, for example as part of your continuous integration build.” ArchUnit’s promise
  5. What can be done with it ? – Checks https://www.archunit.org/use-cases

    Namespace Dependency Checks Types().That().ResideInNamespace("Model").Should() .NotDependOnAny(Types().That().ResideInNamespace("Controller")); Class Namespace Containment Rule Attribute Access Rule Classes().That().HaveNameContaining("Canvas").Should() .ResideInNamespace(typeof(ICanvas).Namespace); Classes().That().DoNotHaveAnyAttributes(typeof(Display)).Should() .NotDependOnAny(Classes().That().AreAssignableTo(typeof(ICanvas)));
  6. What can be done with it ? – Checks https://www.archunit.org/use-cases

    Layers Checks Cycle Rule Slices().Matching("Module.(*)").Should() .BeFreeOfCycles(); [Fact] public void TypesShouldBeInCorrectLayer() { IArchRule exampleClassesShouldBeInExampleLayer = Classes().That().Are(ExampleClasses).Should().Be(ExampleLayer); IArchRule forbiddenInterfacesShouldBeInForbiddenLayer = Interfaces().That().Are(ForbiddenInterfaces).Should().Be(ForbiddenLayer); //check if your architecture fulfills your rules exampleClassesShouldBeInExampleLayer.Check(Architecture); forbiddenInterfacesShouldBeInForbiddenLayer.Check(Architecture); //you can also combine your rules IArchRule combinedArchRule = exampleClassesShouldBeInExampleLayer .And(forbiddenInterfacesShouldBeInForbiddenLayer); combinedArchRule.Check(Architecture); }
  7. How to use it in .NET ? Add dependency(ies) Define

    your own rules as described after Check your rules with your favorite test runner (xUnit here) https://archunitnet.readthedocs.io/en/latest/guide/
  8. @yot88 Archunit – Layered Architecture Presentation Layer (Controller) Application Layer

    (Service) Data Access Layer (Repository) Model (Service) https://github.com/ythirion/archunit-examples
  9. Archunit – Layered Architecture Explains why it fails Presentation Layer

    (Controller) Application Layer (Service) Data Access Layer (Repository) Model (Service) Define your Layers Define Layer rules
  10. @yot88 Why use it ? • Can be really difficult

    to maintain clean boundaries between layers Team rules can easily be broken by inadvertence • Document your architecture decisions (at least structural ones) With a clear DSL • Automate their check and ensure to respect them at any time Can easily be checked with ScalaTest in your CI
  11. @yot88 What else can we do with it ?

  12. @yot88 Reading Writing ArchUnit can help us ensure our guidelines

    and reduce cognitive load while reading code Remember this
  13. @yot88 Archunit – Check naming conventions All our services in

    a namespace “Services” should be suffixed by Service All our classes implementing ICommandHandler<Tcommand> should be suffixed by “CommandHandler”
  14. Archunit – Check team rules / guidelines Easy DSL to

    create custom rules, imagine in your team you decide… that interfaces should always be prefixed by a big I that controller classes should be in their dedicated package
  15. Archunit – Check class dependencies Restrict class dependencies Module cycles

    Help identify cycle dependencies A Module1 B Module2 ctor private method
  16. @yot88 Archunit – Check function return types (CommandHandler) You work

    with CommandHandlers and want to constrain the return values :
  17. @yot88 Archunit – Check function return types (API) You work

    with Rest Controllers and want to force the use of a generic APIResponse in public functions
  18. Arnaoudova’s six categories of linguistic anti-patterns Complete list here https://veneraarnaoudova.com/linguistic-anti-pattern-detector-lapd/LAs/

    Methods that do the opposite than they say Methods that do more than they say Methods that say more than they do Identifiers whose name says that they contain more than what the entity contains Identifiers whose name says that they contain less than what the entity contains Identifiers whose name says that the opposite than the entity contains
  19. Arnaoudova’s six categories of linguistic anti-patterns She studied their occurrence

    in 7 huge open-source projects : 11% of setters also return a value in addition to setting a field 2.5% of methods : method name and the corresponding comment gave opposite descriptions of the working of the method 64% of identifiers starting with ‘is’ turned out not to be Boolean
  20. Archunit – Can check Linguistic Anti-Patterns

  21. @yot88 We already use SonarQube why we should use it

    ? You could declare some of those rules in Sonar BUT Cost less with ArchUnit Easier rule creation We can check high level rules as well as fine-grained Layer constraints Class A cannot have dependencies on something else … We have fast feedback Even with SonarLint Already integrated in your CI / CD Just a dependency to add Rules automation with XUnit
  22. @yot88 Any questions / feedback before we conclude ?

  23. @yot88 Reflect • What can we do with it ?

    • Which rules could be useful ? • Any volunteers to go further ?