WEB/Java Test

운영 이슈 + 아키텍처 테스트

Tony Lim 2022. 11. 14. 12:21
728x90

카오스 엔지니어링 툴

프로덕션 환경, 특히 msa에서 불확실성을 파악하고 해결 방안을 모색하는데 사용하는 툴이다.

가령 Controller의 특정 api를 호출 했을때 일부러 응답을 지연시켜서 써킷이 의도한대로 동작을 하는지 테스트할 수 있다.

spring.profiles.active=chaos-monkey

management.endpoint.chaosmonkey.enabled=true
management.endpoints.web.exposure.include=health,info,chaosmonkey

chaos.monkey.watcher.repository=true

chaos-monkey dependency 를 추가한후에 profile 을 chaos-monkey를 적용시켜줘야한다.

spring boot actuator depdendency 를 추가한 후에 actuator 를 통해 쓸 endpoint (health, info ,chaosmonkey) 를 expose 해줘야한다.

repository annotation이 붙은 빈들을 테스트 하겠다는 의미이다.  기본적으로 service 도 활성화 되어 있다. 이렇게 되면 해당 클래스의 모든 메서드에 설정이 적용이 된다.

http POST localhost:8080/actuator/chaosmonkey/assults level=3 latencyRangeStart=2000 latencyRangeEnd=5000 latencyActive=true

level3 = 3번 요청마다 latency를 주도록 설정을 하는것이다. 

설정 후에 Jmeter ,nGrinder같은 부하를 주는 툴로 테스트 해볼 수 있다.

 

http POST localhost:8080/actuator/chaosmonkey/assults level=3 latencyActive=false exceptionsActive=true exception.type=java.lang.RuntimeException

latency 뿐만 아니라 에러를 발생시킬 수 도 있다.


Archunit 

앱의 아키텍처를 테스트할 수 있는 오픈 소스 라이브러리로 , 패키지 , 클래스 ,레이어 ,슬라이스간의 의존성을 확인할 수 있는 기능을 제공한다.

Circular Dependency 같은 것을 없앨 수 있게 테스트를 도와준다. 

1) ..domain.. 패키지에 있는 클래스는 ..study.., ..memeber.. , ..domain에서 참조 가능.

2) ..member.. 패키지에 있는 클래스는 ..study.. 와 ..member.. 에서만 참조 가능

3) ..study.. 패키지에 있는 클래스는 ..study.. 에서만 참조 가능

순환참조는 없어야 한다. 

 

@Test
void packageDependencyTests() {
    JavaClasses classes = new ClassFileImporter().importPackages("me.whiteship.inflearnthejavatest");

    ArchRule domainPackageRule = classes().that().resideInAPackage("..domain..")
            .should().onlyBeAccessed().byClassesThat()
            .resideInAnyPackage("..study..", "..member..", "..domain..");
    domainPackageRule.check(classes);

    ArchRule memberPackageRule = noClasses().that().resideInAPackage("..domain..")
            .should().accessClassesThat().resideInAPackage("..member..");
    memberPackageRule.check(classes);

    ArchRule studyPackageRule = noClasses().that().resideOutsideOfPackage("..study..")
            .should().accessClassesThat().resideInAnyPackage("..study..");
    studyPackageRule.check(classes);

    ArchRule freeOfCycles = slices().matching("..inflearnthejavatest.(*)..")
            .should().beFreeOfCycles();
    freeOfCycles.check(classes);
}

1. 특정 패키지에 해당하는 클래스를 (바이트 코드를 통해) 읽어들이고(JavaClasses)

2. 확인할 규칙(ArchRule) 를 정의를 하고

3. 읽어들인 클래스들이 그 규칙을 잘 따르는지 확인 한다.

위 순서대로 계속 반복해서 진행된다. 하지만 JUnit5 의 확장팩(ArchUnit 용) 을 사용하면 간추릴 수 있다.

@AnalyzeClasses(packagesOf = App.class)
public class ArchTests {

    @ArchTest
    ArchRule domainPackageRule = classes().that().resideInAPackage("..domain..")
            .should().onlyBeAccessed().byClassesThat()
            .resideInAnyPackage("..study..", "..member..", "..domain..");

    @ArchTest
    ArchRule memberPackageRule = noClasses().that().resideInAPackage("..domain..")
            .should().accessClassesThat().resideInAPackage("..member..");

    @ArchTest
    ArchRule studyPackageRule = noClasses().that().resideOutsideOfPackage("..study..")
            .should().accessClassesThat().resideInAnyPackage("..study..");

    @ArchTest
    ArchRule freeOfCycles = slices().matching("..inflearnthejavatest.(*)..")
            .should().beFreeOfCycles();

}

동일한 테스트에서 룰은 그대로 하고 수동으로 check 하는 메소드가 사라졌다.

ArchTest 같은 경우에는 Extension 을 하는 방법을 사용하는것이아니라 engine api를 확장한것이다. 아예 vintage 처럼 arch vintage와 같은 엔진구현체가 따로 존재하는것이라 
저번에 배웠던 Extension 관련 Annotation이 존재하지 않는것이다.


ArchUnit 클래스 의존성 확인

@AnalyzeClasses(packagesOf = App.class)
public class ArchClassTests {

    @ArchTest
    ArchRule controllerClassRule = classes().that().haveSimpleNameEndingWith("Controller")
            .should().accessClassesThat().haveSimpleNameEndingWith("Service")
            .orShould().accessClassesThat().haveSimpleNameEndingWith("Repository");

    @ArchTest
    ArchRule repositoryClassRule = noClasses().that().haveSimpleNameEndingWith("Repository")
            .should().accessClassesThat().haveSimpleNameEndingWith("Service");

    @ArchTest
    ArchRule studyClassesRule = classes().that().haveSimpleNameStartingWith("Study")
            .and().areNotEnums()
            .and().areNotAnnotatedWith(Entity.class)
            .should().resideInAnyPackage("..study..");
}

 

728x90

'WEB > Java Test' 카테고리의 다른 글

TestContainers  (1) 2022.11.11
Mockito  (0) 2022.11.11
JUnit5  (0) 2022.11.10