통합 테스트를 덜 불안정하게 만드는 방법
8158 단어 tutorialdevopstestingopensource
그러나 일반적으로 인터페이스에서 문제가 발생합니다. 내 코드가 데이터베이스, 파일 시스템 또는 다른 서비스와 통신할 때 문제가 발생합니다. 이러한 이유로 통합 테스트가 유용합니다. 파일 시스템, 데이터베이스 또는 원격 시스템에서 쓰기 및 읽기를 테스트할 수 있습니다. 코드 적용 범위 측면에서 통합 테스트는 이길 수 없습니다.
하지만 문제가 있습니다. 그것들을 실행하는 것이 더 어렵습니다. 특히 팀에 속해 있고 병렬 개발의 각 분기에 대해 실행하려는 경우.
예
다음은 간단한 예입니다. 알파벳순으로 상위 5개 국가를 인쇄하는 애플리케이션이 있습니다. 국가는 Postgres에서 왔습니다. 예는 Scala에 있지만 내 요점은 희망적으로 더 보편적입니다.
> sbt run
The first 5 countries are Afghanistan, Albania, Algeria, American Samoa, Andorra
또한 데이터베이스에 5개 국가를 성공적으로 들어오고 나갈 수 있는 간단한 통합 테스트도 있습니다. 이 예제의 전체 코드is here .
class DatabaseIntegrationTest extends FlatSpec {
implicit val cs = IO.contextShift(ExecutionContext.global)
...
"A table" should "have country data" in {
val dal = new DataAccessLayer()
assert(dal.countries(5).transact(xa).unsafeRunSync.size == 5)
}
}
산출:
>sbt it:test
[info] DatabaseIntegrationTest:
[info] A table
[info] - should have country data
[info] Run completed in 2 seconds, 954 milliseconds.
[info] Total number of tests run: 1
로컬에서 이것을 개발하는 동안 docker-compose 파일을 사용하여 데이터베이스 및 기타 종속성을 시작합니다.
version: "3"
services:
postgres:
container_name: local-postgres
image: aa8y/postgres-dataset:iso3166
ports:
- 5432:5432
hostname: postgres
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
postgres-ui:
container_name: local-postgres-ui
image: adminer:latest
depends_on:
- postgres
ports:
- 8080:8080
hostname: postgres-ui
하지만 이 테스트와 다른 테스트를 빌드 파이프라인의 일부로 실행하고 싶습니다. 변경 사항이 이 테스트를 중단하는 경우 나중에 GitHub Actions 또는 Jenkins에서 알려 주기를 원합니다. 그러나 어떤 데이터베이스를 가리키고 있습니까?
테스트 환경 솔루션
이에 대한 한 가지 해결책은 테스트 환경을 사용하는 것입니다. 실제 생산 세계가 어떤 모습이든 간에 테스트를 위해 사본을 만들고 이에 대해 테스트를 실행하십시오.
이 솔루션은 더 많은 문제를 가져옵니다. 한 가지 문제는 재현성입니다. 단 한 사람이 단일 서비스에서 하나의 종속성으로 작업하는 경우 테스트 환경이 적합할 것입니다. 그러나 더 많은 사람들이 병렬 브랜치에서 작업하기 시작하고 더 많은 서비스가 등장하면 상황이 무너지기 시작할 것입니다.
다음은 실제 경험을 기반으로 한 몇 가지 문제입니다.
문제의 핵심은 병렬로 테스트하고 싶지만 테스트 환경이 하나뿐이라는 것입니다. 서비스 수가 증가함에 따라 문제는 더욱 악화될 것입니다.
솔루션
이러한 각 문제에 대한 특정 솔루션이 있습니다. 그러나 귀하의 서비스가 더 많은 다른 서비스에 의존함에 따라 깨끗한 상태를 유지하기가 점점 더 어려워집니다. 잠재적인 해결책이 있습니다.
여기서 문제의 핵심은 통합 테스트 실행 사이에 진정한 격리가 없다는 것입니다.
솔루션은 통합 테스트를 실행하기 위해 로컬 및 빌드에서 종속성의 docker-compose 파일을 사용하는 것입니다.
이것은 make 파일이나 bash 스크립팅을 사용하여 수행할 수 있지만 earthly로 수행할 수 있는 방법을 보여 드리겠습니다.
저는 일종의 docker 파일과 make 파일의 조합과 같은 Earthfile을 만듭니다. 여기에서 소스를 복사하고 docker-compose up을 시작하고 테스트를 실행하는 통합 대상을 만듭니다.
integration-test:
FROM +project-files
COPY src src
COPY docker-compose.yml ./
WITH DOCKER --compose docker-compose.yml
RUN sbt it:test
END
그런 다음 로컬 또는 빌드 파이프라인에서 실행할 수 있으며 모든 실행은 서로 격리됩니다. 어디에서 실행되든 컨테이너화를 통해 모든 테스트 실행이 격리됩니다.
> earth -P +integration-test
+integration-test | Creating local-postgres ... done
+integration-test | Creating local-postgres-ui ... done
+integration-test | +integration-test | [info] Loading settings for project scala-example-build from plugins.sbt ...
+integration-test | [info] DatabaseIntegrationTest:
+integration-test | [info] An table
+integration-test | [info] - should have country data
+integration-test | [info] Run completed in 2 seconds, 923 milliseconds.
+integration-test | [info] Tests: succeeded 1, failed 0, canceled 0, ignored 0, pending 0
+integration-test | Stopping local-postgres-ui ... done
+integration-test | Stopping local-postgres ... done
+integration-test | Removing local-postgres-ui ... done
+integration-test | Removing local-postgres ... done
+integration-test | Removing network scala-example_default
+integration-test | Target github.com/earthly/earthly-example-scala/integration:master+integration-test built successfully
...
이 패턴을 사용하면 서비스가 docker-compose에서 종속성을 선언하고 통합 테스트가 덜 불안정해집니다.
더 완전한 기능을 갖춘 버전example here과 더 긴 가이드 버전here이 있습니다.
단위 테스트와 통합 테스트의 차이점에 대해 알아보고 싶다면 이에 대해서도 설명했습니다here .
이것이 제가 이 문제를 해결하는 방법입니다. 어떤 솔루션을 보았습니까?
Reference
이 문제에 관하여(통합 테스트를 덜 불안정하게 만드는 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/adamgordonbell/how-to-make-integration-tests-less-flaky-bel텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)