paint-brush
완벽하게 격리된 End-To-End 환경 구축~에 의해@marcinwosinek
511 판독값
511 판독값

완벽하게 격리된 End-To-End 환경 구축

~에 의해 Marcin Wosinek5m2023/04/12
Read on Terminal Reader
Read this story w/o Javascript

너무 오래; 읽다

불안정한 테스트는 코드와 관련되지 않은 이유로 실패한 테스트입니다. 극단적인 경우 불안정한 테스트는 팀이 E2E 결과를 무시하도록 가르칠 것입니다. 이로 인해 품질 관리(QA) 자동화 노력이 무산될 수 있습니다. 여기에 제시된 접근 방식은 테스트 실행에서 잠재적인 문제의 두 가지 큰 소스를 해결합니다.
featured image - 완벽하게 격리된 End-To-End 환경 구축
Marcin Wosinek HackerNoon profile picture

안정적인 E2E(End-to-End) 테스트를 위해서는 외부와 최대한 격리된 환경이 필요합니다.

벗겨짐 감소

불안정한 테스트는 코드와 관련되지 않은 이유로 실패한 테스트입니다. 이로 인해 E2E를 애플리케이션의 정확성에 대한 신뢰할 수 있는 검사로 사용하기가 어렵습니다. 극단적인 경우 불안정한 테스트는 팀이 E2E 결과를 무시하도록 가르칠 것입니다. 이로 인해 품질 관리(QA) 자동화 노력이 사라질 수 있습니다.


여기에 제시된 접근 방식은 테스트 실행에서 잠재적인 문제의 두 가지 큰 원인을 해결합니다.


  • 다양한 테스트 작업에서 공유하는 백엔드에 저장된 상태


  • 귀하가 통제할 수 없는 외부 서비스.


이 접근 방식의 영향을 받지 않는 다른 벗겨짐 원인이 있습니다.


  • 실제 문제는 무작위로 나타나는 응용 프로그램에 있거나


  • 애플리케이션의 문제는 E2E가 애플리케이션과 상호 작용하는 부자연스러운 속도로 인해 발생합니다.

대안

저희 팀과 저는 전용 백엔드 컨테이너에 대해 테스트를 실행하기 전에 비프로덕션 서버 중 하나를 사용했습니다. 이 접근 방식은 E2E 솔루션의 실험 단계에서는 괜찮았습니다.


테스트가 몇 개밖에 없었을 때는 어차피 테스트 결과를 바탕으로 결정을 내릴 수 없었습니다.


그러나 계속해서 더 많은 테스트를 추가하고 실행 시간이 길어지면서 이 접근 방식은 무너지기 시작했습니다. 주요 쟁점은 다음과 같았습니다.


  • 테스트 내에서 데이터 변경 사항을 되돌리려고 시도했지만 일부 테스트 실패로 인해 예상치 못한 변경 사항이 발생했습니다.


  • 병렬 작업이 충돌했습니다. 다양한 테스트 작업이 동일한 상태를 변경하여 작업 중 하나가 실패하는 경우가 많았습니다.

모든 것을 Dockerize

이 문제에 대한 해결책은 각 테스트 작업에 대해 별도의 백엔드 서버와 데이터베이스를 전용으로 사용하는 것이었습니다. Docker가 아니었다면 이 접근 방식은 매우 어려울 것입니다.


Docker 컨테이너는 애플리케이션을 실행하는 데 필요한 모든 것을 갖춘 포함된 환경을 만드는 완벽한 도구입니다.


  • 올바른 운영 체제(또는 올바른 Linux 배포판),


  • 이미지 조작 라이브러리 등과 같은 시스템 종속성


  • 올바른 버전의 언어 해석기(Python, Node 등) 또는 데이터베이스 서버.

데이터 베이스

테스트를 위해 예측 가능한 테스트 데이터와 함께 제공되는 전용 데이터베이스 컨테이너를 준비할 수 있습니다. 이러한 방식으로 각 E2E 실행의 시작점을 정확하게 재현할 수 있어 테스트가 더욱 안정적으로 이루어집니다.


테스트 데이터베이스 버전 관리를 위해 Docker 이미지에 다양한 태그를 사용할 수 있습니다. 동일한 테스트 데이터베이스를 개발 환경에서도 사용할 수 있습니다. 개발 중인 수동 테스트의 경우 자동화된 테스트와 유사한 예제 엔터티가 필요합니다.

백엔드

백엔드 배포에 이미 Docker를 사용한 경우 E2E 실행에 동일한 이미지를 재사용하는 것이 매우 쉽습니다. 우리 팀에서는 백엔드를 컨테이너로 배포하고 데이터베이스 URL과 자격 증명을 환경 변수로 제공합니다.


매우 동일한 컨테이너 버전을 프로덕션에 배포하거나 테스트 실행을 위해 CI(지속적 통합)에 사용할 수 있습니다. 각 환경은 DB 연결에 적합한 값을 제공합니다.

프런트엔드

배포 전략에 따라 다음 중 하나를 수행할 수 있습니다.


  1. 프런트엔드 빌드의 일부로 빌드한 컨테이너를 사용하세요.


  2. 컴파일된 파일을 가져오고 테스트를 위해 HTTP를 통해 사용할 수 있는지 확인하세요.


우리의 경우 옵션 2를 사용합니다. 애플리케이션을 정적 파일로 배포하므로 E2E 작업 실행 중에 빌드된 파일을 제공하기 위한 전용 컨테이너를 만들었습니다.

GitLab의 작업 서비스

우리는 CI를 실행하기 위한 플랫폼으로 GitLab을 사용합니다. GitLab의 각 작업은 선택한 이미지가 포함된 컨테이너 내에서 실행됩니다. 기본 컨테이너 외에도 서비스를 정의할 수 있습니다. 테스트와 함께 실행되는 추가 컨테이너입니다. 구성은 다음과 같이 쉽습니다.

 <job-name>: services: - name: <image> alias: <container-url>


사용 가능한 옵션은 Docker Compose의 옵션과 유사하지만 더 제한적입니다.

GitLab 구성에서 한 가지 "문제"는 테스트 실행 중에 서비스가 서로 액세스할 수 있도록 하려면 변수 FF_NETWORK_PER_BUILD 1로 설정하는 것입니다.

직무 내 격리를 위한 임시 데이터 고려

어느 시점에서 우리는 하나의 작업 내에서 모든 테스트를 병렬로 실행하고 있었습니다. 당시에는 각 테스트가 동일한 백엔드와 데이터베이스를 사용했기 때문에 더욱 강력한 격리를 적용해야 했습니다.


이 문제를 해결하기 위해 우리는 테스트의 before 섹션 바로 내부에 주입하는 무작위 데이터에 주로 의존하도록 테스트를 업그레이드했습니다. 이를 통해 다른 스레드에서 발생하는 다른 변경 사항에 영향을 받지 않고 테스트를 실행할 수 있었습니다.


이 접근 방식은 처음에는 약간 까다로울 수 있지만 상황에 따라 의미가 있을 수 있습니다.

각 테스트 후 정리

각 테스트 작업에 대해 새로운 데이터베이스를 시작하더라도 여전히 테스트가 애플리케이션을 발견한 것과 동일한 상태로 유지하도록 노력하고 있습니다. 어쩌면 공유된 환경에서 테스트를 진행하던 시절의 흔적이 조금 남아있는지도 모르겠습니다.


더 이상 중요하지는 않지만 다음과 같은 경우 테스트 개발 중에 여전히 도움이 될 수 있습니다.


  • 하나의 테스트만 실행하는 경우 - 따라서 테스트에서 발생하는 상태는 파일에서 모든 테스트를 실행할 때와 다르지 않습니다.


  • 동일한 테스트를 로컬에서 반복해서 다시 실행하면 데이터베이스가 이전 실행의 영향을 받지 않습니다.

모의 외부 서비스

서비스를 컨테이너로 이동하는 것이 선택 사항이 아닌 경우가 있습니다. 예를 들어:


  • 애플리케이션이 직접 또는 일부 백엔드 프록시를 통해 사용하는 외부 서버가 있는 경우


  • 기술적인 문제로 인해 컨테이너 내부에서 실행할 수 없는 서버를 소유하고 있습니다.


두 경우 모두 테스트 실행을 격리하기 위해 해당 서비스로 이동하는 요청을 모의할 수 있습니다. 이렇게 하면 예측할 수 없는 외부 서비스가 테스트 결과에 영향을 미치는 것을 방지할 수 있습니다. 이 접근 방식의 단점은 테스트가 애플리케이션이 작동하는 컨텍스트와 연결이 끊어진다는 것입니다.


모의 테스트를 사용하면 해당 서비스의 변경 사항이 애플리케이션에 영향을 미치는 경우를 테스트에서 포착할 수 없습니다 .

계속해서 배우세요

테스트 또는 기타 프로그래밍 관련 주제에 대해 더 자세히 알아보고 싶다면 여기에서 등록하여 관련 콘텐츠를 게시할 때 업데이트를 받을 수 있습니다.