Русский
Русский
English
Статистика
Реклама

Перевод Модульное тестирование архитектуры Spring Boot проектас помощью ArchUnit

При создании программного обеспечения команды разработчиков обычно определяют набор руководящих принципов и соглашений по разработке кода, которые считаются лучшими практиками.

Это методы, которые обычно документируются и доводятся до сведения всей команды разработчиков, которая их приняла.Однако во время разработки разработчики могут нарушить эти рекомендации, которые обнаруживаются во время ревью кода или с помощью инструментов проверки качества кода.

Поэтому важным аспектом является автоматизация этих директив в максимально возможной степени по всей архитектуре проекта, позволяющая оптимизировать проверки.

Мы можем реализовать эти рекомендации как проверяемые JUnit тесты с помощьюArchUnit.Это гарантирует, что сборка версии программного обеспечения будет прекращена в случае нарушения архитектуры.

ArchUnit это бесплатная, простая и расширяемая библиотека для проверки архитектуры вашего Java кода для использования в любой простой среде модульного тестирования Java.То есть ArchUnit может проверять зависимости между пакетами и классами, уровенями и срезами, проверять циклические зависимости и многое другое.Он делает это путем анализа данного байт-кода Java и импорта всех классов в структуру кода Java.

ArchUnit позволяет вам реализовать правила для статических свойств архитектуры приложения в форме исполняемых тестов, таких как следующие:

  • Проверки зависимостей пакетов

  • Проверки зависимостей класса

  • Проверки содержания классов и пакетов

  • Проверки наследования

  • Проверка аннотаций

  • Проверка уровней

  • Проверки цикла

Примечание переводчика. Эта заметка дополняет предыдущую на тему ArchUnit.

Начнем

Для поддержки ArchUnit JUnit 5, просто добавьте следующую зависимость из Maven Central:

pom.xml

XML

<dependency>    <groupId>com.tngtech.archunit</groupId>    <artifactId>archunit-junit5</artifactId>    <version>0.14.1</version>    <scope>test</scope></dependency>

build.gradle

Groovy

dependencies {   testImplementation 'com.tngtech.archunit:archunit-junit5:0.14.1' } } 

Проверки зависимостей пакетов

Java

class ArchunitApplicationTests {  private JavaClasses importedClasses;  @BeforeEach  public void setup() {        importedClasses = new ClassFileImporter()                .withImportOption(ImportOption.Predefined.DO_NOT_INCLUDE_TESTS)                .importPackages("com.springboot.testing.archunit");    }  @Test  void servicesAndRepositoriesShouldNotDependOnWebLayer() {      noClasses()                .that().resideInAnyPackage("com.springboot.testing.archunit.service..")                .or().resideInAnyPackage("com.springboot.testing.archunit.repository..")                .should()                .dependOnClassesThat()                .resideInAnyPackage("com.springboot.testing.archunit.controller..")                .because("Services and repositories should not depend on web layer")                .check(importedClasses);    }}

Сервисы и репозитории не должны взаимодействовать с веб-уровнем.

Проверки зависимостей класса

class ArchunitApplicationTests {  private JavaClasses importedClasses;  @BeforeEach    public void setup() {        importedClasses = new ClassFileImporter()                .withImportOption(ImportOption.Predefined.DO_NOT_INCLUDE_TESTS)                .importPackages("com.springboot.testing.archunit");    }    @Test    void serviceClassesShouldOnlyBeAccessedByController() {        classes()                .that().resideInAPackage("..service..")                .should().onlyBeAccessed().byAnyPackage("..service..", "..controller..")                .check(importedClasses);    }}

ArchUnit предлагает абстрактный API-интерфейс, похожий на DSL, который, в частности, может оценивать импортируемые классы.Доступ к сервисам должен осуществляться только контроллерами.

Две точки представляют любое количество пакетов (сравните AspectJ Pointcuts).

Соглашение об именовании

Java

class ArchunitApplicationTests {    private JavaClasses importedClasses;  @BeforeEach  public void setup() {    importedClasses = new ClassFileImporter()        importedClasses = new ClassFileImporter()                .withImportOption(ImportOption.Predefined.DO_NOT_INCLUDE_TESTS)                .importPackages("com.springboot.testing.archunit");  }    @Test    void serviceClassesShouldBeNamedXServiceOrXComponentOrXServiceImpl() {        classes()                .that().resideInAPackage("..service..")                .should().haveSimpleNameEndingWith("Service")                .orShould().haveSimpleNameEndingWith("ServiceImpl")                .orShould().haveSimpleNameEndingWith("Component")                .check(importedClasses);    }    @Test    void repositoryClassesShouldBeNamedXRepository() {        classes()                .that().resideInAPackage("..repository..")                .should().haveSimpleNameEndingWith("Repository")                .check(importedClasses);    }    @Test    void controllerClassesShouldBeNamedXController() {        classes()                .that().resideInAPackage("..controller..")                .should().haveSimpleNameEndingWith("Controller")                .check(importedClasses);    }}

Общее правило это соглашение об именах.Например, все имена сервис классов должны заканчиваться на Service, Component и т. д.

Проверка аннотаций

Java

class ArchunitApplicationTests {  private JavaClasses importedClasses;  @BeforeEach  public void setup() {      importedClasses = new ClassFileImporter()              .withImportOption(ImportOption.Predefined.DO_NOT_INCLUDE_TESTS)              .importPackages("com.springboot.testing.archunit");  }  @Test  void fieldInjectionNotUseAutowiredAnnotation() {      noFields()              .should().beAnnotatedWith(Autowired.class)              .check(importedClasses);  }  @Test  void repositoryClassesShouldHaveSpringRepositoryAnnotation() {      classes()              .that().resideInAPackage("..repository..")              .should().beAnnotatedWith(Repository.class)              .check(importedClasses);  }  @Test  void serviceClassesShouldHaveSpringServiceAnnotation() {      classes()              .that().resideInAPackage("..service..")              .should().beAnnotatedWith(Service.class)              .check(importedClasses);  }}

API ArchUnit Lang может определять правила для членов классов Java.Это может быть актуально, например, если методы в определенном контексте необходимо аннотировать с помощью определенной аннотации или если типы возвращаемых данных реализуют определенный интерфейс.

Проверки уровней

class ArchunitApplicationTests {private JavaClasses importedClasses;@BeforeEach  public void setup() {        importedClasses = new ClassFileImporter()                .withImportOption(ImportOption.Predefined.DO_NOT_INCLUDE_TESTS)                .importPackages("com.springboot.testing.archunit");    }    @Test    void layeredArchitectureShouldBeRespected() {layeredArchitecture()                .layer("Controller").definedBy("..controller..")                .layer("Service").definedBy("..service..")                .layer("Repository").definedBy("..repository..")                .whereLayer("Controller").mayNotBeAccessedByAnyLayer()                .whereLayer("Service").mayOnlyBeAccessedByLayers("Controller")                .whereLayer("Repository").mayOnlyBeAccessedByLayers("Service")                .check(importedClasses);    }}

В приложении Spring Boot уровень сервиса зависит от уровня репозитория, уровень контроллера зависит от уровня сервиса.

ArchUnit предлагает набор функций, проверяющих соблюдение вашей многоуровневой архитектуры.Эти тесты обеспечивают автоматические гарантии того, что доступ и использование поддерживаются в установленных вами пределах.Поэтому можно писать собственные правила.В этой статье мы описали несколько правил.Официальная докумуентация ArchUnit представляет значительно больше различных возможностей.

Полный исходный код примеров можно найти в моемрепозитории GitHub.

Источник: habr.com
К списку статей
Опубликовано: 12.11.2020 18:15:59
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Java

Testing

Best practices

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru