카오스 엔지니어링 툴
프로덕션 환경, 특히 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..");
}
'WEB > Java Test' 카테고리의 다른 글
TestContainers (1) | 2022.11.11 |
---|---|
Mockito (0) | 2022.11.11 |
JUnit5 (0) | 2022.11.10 |