통합 테스트에 인 메모리 데이터베이스를 사용해야하는 이유는 무엇입니까?


18

테스트에 사용되는 많은 인 메모리 데이터베이스 구현이 테스트에 사용되는 환경이 운영 체제를 포함하여 프로덕션 환경과 최대한 비슷해야한다는 통합 테스트 모범 사례에서 많은 소식을 들었 기 때문에 실제로 혼란스러워합니다. , 라이브러리, 데이터베이스 엔진 등

내가 여기서 무엇을 놓치고 있습니까?


프로그래밍 방식으로 데이터 일관성을 보장하고 일반적으로 합리적으로 빠르기 때문에 많이 보았습니다. 특히 테스트가 단위 테스트 인 경우 닫힌 시스템이 되길 원합니다. 테스트가 테스트에 완전히 포함되기를 원합니다.
Rig

사전에 외부 데이터베이스를 설정하지 않고도 개발자가 최신 코드를 모두 가져 와서 테스트를 실행할 수있는 것이 좋습니다.
Jason Evans

1
프로덕션 환경과 매우 유사한 측면은로드 테스트 및 스트레스 테스트에 속하며 이는 내 테스트에서 코드 테스트 게이트 기준과 같은 단위 테스트와 별도로 수행해야합니다.
rwong

답변:


19

일반적인 소프트웨어 개발 상황에서 테스트는 개발 중과 개발 체인을 따라 제품을 이동하기 전에 두 가지 지점에서 사용됩니다.

개발 중 테스트를 실행하는 첫 번째 상황은 단기 목표 : 태스크 정의 (TDD에서와 같이 실패한 테스트 작성 후 통과), 회귀 방지, 변경 사항이 다른 사항을 위반하지 않도록하는 등의 단기 목표를 제공합니다. 테스트는 매우 빨라야합니다. 이상적으로 전체 테스트 스위트는 5 초 이내에 실행되며 코딩하는 동안 IDE 또는 텍스트 편집기 옆의 루프에서 실행할 수 있습니다. 소개 한 모든 회귀가 몇 초 내에 나타납니다. 이 단계에서는 회귀 및 버그를 100 % 잡는 것보다 빠른 테스트 실행이 더 중요하며, 프로덕션 시스템의 정확한 사본을 개발하는 것은 실용적이지 못하거나 (불가능하게 불가능하므로) 완벽한 테스트를 수행하는 데 필요한 노력은 가치가 없습니다. 그것. 인 메모리 데이터베이스를 사용하는 것은 트레이드 오프입니다. 프로덕션 시스템의 정확한 사본이 아닙니다. 그러나 테스트 실행을 5 초 한도 미만으로 유지하는 데 도움이됩니다. 데이터베이스 관련 테스트를 위해 약간 다른 데이터베이스 설정을 선택하고 전혀 테스트하지 않는 경우, 내가 선택한 것을 알고 있습니다.

그러나 개발 체인을 따라 코드를 이동하는 두 번째 상황 에는 광범위한 테스트 필요합니다. 우리는 개발 프로세스의이 부분을 자동화 할 수 있고 자동화해야하기 때문에 훨씬 더 느린 테스트를 감당할 수 있습니다. 전체 테스트 실행에 몇 시간이 걸리더라도 야간 빌드를 예약하더라도 여전히 어제의 코드베이스를 정확하게 파악할 수 있습니다. 프로덕션 환경을 최대한 정확하게 시뮬레이션하는 것이 중요하지만 이제는 여유가 있습니다. 따라서 우리는 인 메모리 데이터베이스 트레이드 오프를 만들지 않습니다. 프로덕션 시스템과 정확히 동일한 DBMS 버전을 설치하고 가능한 경우 테스트를 시작하기 전에 실제 프로덕션 데이터로 채 웁니다.


6

나는 그것이 절충 속도 / 환경과 일치하는 것 같아요. 테스트는 자주 실행되어야하며, 따라서 테스트 속도가 빨라야합니다. 특히 단위 테스트는 몇 초 이상 걸리지 않아야합니다.

통합 테스트는 느리게 실행되지만 빠르면 더 자주 실행할 수 있습니다. 예를 들어, 모든 커밋 전에. 물론 전체 환경만큼 완벽하지는 않지만 최소한 매핑 계층, 생성 된 SQL, 파트 간의 상호 작용 방식 등을 테스트하고 있습니다. 비용이 많이 드는 데이터베이스의 경우 모든 사람을 위해 라이센스를 구매할 필요가 없습니다. 코드 테스트의 100 %를 하루에 한 번 또는 최악의 주 단위로 처리하는 것보다 시간당 한 번 테스트를 실행하면 코드의 90 %를 처리하는 데 더 많은 오류가 발생할 수 있습니다.

물론 실제 데이터베이스와 완전히 통합 된 환경에서 테스트해야합니다. 이러한 테스트를 자주 실행하지는 않을 수도 있지만 이전 테스트에서 이미 확신을 가지고 있었기 때문에 남은 것은 이상한 플랫폼 특정 버그입니다.


3

간단한 테스트를 위해 데이터베이스 액세스 계층을 조롱하는 것은 완벽하게 허용됩니다. 당신은 getName()그것을 조롱 한 DAO를 호출하고 이름은 "John", 성은 "Smith"를 반환하고 조립하고 모든 것이 완벽합니다. 실제로 데이터베이스를 단위 테스트 할 필요가 없습니다.

논리가 조금 더 복잡해지면 상황이 조금 더 커집니다. "createOrUpdateUser (...)"메소드가 있으면 어떻게됩니까? 데이터베이스를 모의 한 경우, 모의가 오브젝트를 리턴하지 않고 기존 오브젝트를 리턴 할 때 데이터베이스에서 다른 메소드가 호출 될 때 특정 매개 변수를 사용하여 지정된 메소드가 한 번 호출되었는지 확인할 수 있습니다. 그러면 전문화 된 메모리 데이터베이스를 스핀 업하고 미리 구성된 데이터로 해당 코드를 테스트하는 것이 더 쉬운 퍼지 라인에 도달하기 시작합니다.

내가 작업 한 실제 코드 (판매 시점)에는 resumeSuspededTransaction(...)방법이 있습니다. 이것은 트랜잭션을 데이터베이스에서 오브젝트 (및 해당 구성 요소)로 가져 와서 데이터베이스를 갱신합니다. 우리는 데이터베이스에가는 데이터의 직렬화 및 역 직렬화와 함께 어딘가에 코드를 모의하고 버그를 숨겼습니다 (데이터베이스에서 다르게 직렬화 된 유형을 변경했습니다).

이 모의는 행복한 경로를 반환했기 때문에 버그를 보여주지 않았습니다. 트랜잭션을 직렬화하고, 모의에 저장하고, 모의에서 역 직렬화하고, 동일한 지 테스트하십시오. 그러나 선행 0을 가진 객체를 데이터베이스에 직렬화하면 객체가 삭제되고 0이없는 문자열로 다시 결합됩니다. 우리는 문제 해결을 통해 데이터베이스없이 버그를 발견했습니다.

나중에 우리는 데이터베이스를 거기에 넣고 메모리 데이터베이스에 들어가면 버그가 junit 테스트를 거치지 않았 음을 깨달았습니다.


메모리 데이터베이스에서 다음과 같은 장점이 있습니다.

  • 테스트를 위해 계정, 테이블 등을 설정하기 위해 DBA가 필요없이 신속하게 회전 할 수 있습니다.
  • 해당 테스트에 대해 데이터를 사전 구성 할 수 있습니다
  • 테스트가 완료되면 테스트 롤백에 대해 걱정할 필요가 없습니다.
  • 각 테스트마다 자체 메모리 데이터베이스가 있으므로 두 개의 테스트가 동시에 실행되는지 걱정할 필요가 없습니다.
  • 실제 데이터베이스에 연결되지 않은 시스템에서 실행될 수 있습니다.

1

이것은 사용중인 데이터베이스 시스템에 따라 다릅니다. db 시스템이 거의 100 % API 이며 디스크 기반 데이터베이스 구성 호환되는 동작 ( 메모리 속도 대안 속도 안전 및 코스 제외)을 제공하는 메모리 내 대안을 제공하는 경우 메모리 내 변형을 사용하는 것이 좋습니다. .

그러나 DB 시스템에 메모리 내 구성과 메모리 내 비 사용간에 큰 차이가있는 경우에는 옳습니다.이 경우 통합 테스트로 인해 버그가 발생할 위험이 높아집니다. 그러나 DB 시스템과 그 차이점을 잘 알고 있으면 스스로 "차이를 없앨 수 있습니다".


1

평신도의 말로 :

아키텍처의 중요한 부분을 조롱하는 것은 단위 테스트에 적합 합니다.

그러나 통합 테스트의 경우 귀하에게 강력하게 동의합니다. 조롱을하지 말고 가능한 한 실제 환경과 유사한 환경을 제공해야합니다.

결국 통합 테스트는 아키텍처의 다른 부분이 어떻게 동작하는지 테스트하는 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.