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

Test your architecture with Archunit

Yoan
January 24, 2022

Test your architecture with Archunit

Workshop on archunit

Yoan

January 24, 2022
Tweet

More Decks by Yoan

Other Decks in How-to & DIY

Transcript

  1. @yot88
    Test your Architecture
    with ArchUnit

    View Slide

  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

    View Slide

  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.

    View Slide

  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

    View Slide

  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)));

    View Slide

  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);
    }

    View Slide

  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/

    View Slide

  8. @yot88
    Archunit – Layered Architecture
    Presentation Layer
    (Controller)
    Application Layer
    (Service)
    Data Access Layer
    (Repository)
    Model
    (Service)
    https://github.com/ythirion/archunit-examples

    View Slide

  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

    View Slide

  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

    View Slide

  11. @yot88
    What else can we do with it ?

    View Slide

  12. @yot88
    Reading
    Writing
    ArchUnit can help us ensure our
    guidelines and reduce cognitive
    load while reading code
    Remember this

    View Slide

  13. @yot88
    Archunit – Check naming conventions
    All our services in a namespace “Services” should be suffixed by Service
    All our classes implementing ICommandHandler should be suffixed by “CommandHandler”

    View Slide

  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

    View Slide

  15. Archunit – Check class dependencies
    Restrict class dependencies
    Module cycles
    Help identify cycle dependencies
    A
    Module1
    B
    Module2
    ctor
    private method

    View Slide

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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  20. Archunit – Can check Linguistic Anti-Patterns

    View Slide

  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

    View Slide

  22. @yot88
    Any questions / feedback before we conclude ?

    View Slide

  23. @yot88
    Reflect
    • What can we do with it ?
    • Which rules could be useful ?
    • Any volunteers to go further ?

    View Slide