2010-08-18 2 views
2

누구나 단위 테스트를 좋아합니다. 그러나 엔티티의 테스트 지속성은 약간 다릅니다. 서로 다른 언어를 사용하여 여러 레이어에서 발생하는 프로세스를 테스트하고 있습니다. 테스트에는 부작용이 있습니다 (행이 추가/수정되는 등의 의미에서).엔티티의 지속성을 테스트하기위한 방법 및 권장 사항

나는 어떻게하는지 알고 싶습니다. 예를 들어, 테스트에서 완전히 새로운 데이터베이스 스키마를 만들고 매번 삭제합니까? 테스트 스키마 생성을 위해 SQL 스크립트를 유지 관리하고 프로덕션 데이터베이스와 함께 유지해야합니까? 프로덕션 환경에서 사용하는 데이터베이스 제품과 동일한 테스트를 수행합니까? 무작위로 엔티티의 상태를 생성합니까, 아니면 항상 같은 값을 사용합니까? 테스트가 프로덕션 데이터베이스가 아닌 테스트 데이터베이스에 대해 실행되도록하려면 어떻게 구성합니까?

아마도이 분야에서 내가 생각하지 못했던 중요한 질문이있을 것입니다. 포인트 체이서 (point-chasers)의 이익을 위해 가장 부작용이 적고 구현하기 쉬운 것으로 보이는 대답을 표시 할 것입니다.

+0

와우, 나는 단지 두 사람보다 더 많은 의견을 기다리고있었습니다. 아마도 완전한 불꽃 전쟁이 아니었지만 어쩌면 교육상의 의견 차이가있을 수 있습니다. – David

답변

1

테스트 데이터 지속성을 단위 화하는 것은 거의 불가능하므로 일반적으로 통합 수준에서 수행합니다.

현재 프로젝트에서 통합 테스트 슈트는 실제로 전체 스키마를 삭제하고 모든 것을 처음부터 다시 만듭니다 (빌드 서버에서 테스트를 실행할 때 사용됨). 그러나 이미 생성 된 데이터베이스에 대해 테스트를 실행할 수도 있습니다. 이는 머신에서 테스트/디버깅을하고 시간을 낭비하거나 테스트 데이터를 낭비하지 않으려는 경우에 유용합니다. 데이터베이스 스크립트 (프로덕션 스크립트와 동일해야 함)를 유지해야합니다. 이렇게하면 스크립트와 .NET 코드를 테스트 할 수 있습니다. 일반적으로 스크립트는 정적 데이터와 별도로 데이터를 생성하지 않습니다. 테스트 데이터를 작성하고 일부 작업을 수행하며 기대를 확인하는 테스트의 일부 여야합니다. 그러면 모든 데이터베이스에 대해 테스트를 실행할 수 있습니다. 정확한 스키마. 테스트 데이터를 만들 때 우리는 일반적으로 임의의 식별자와 고유 한 필드를 취하여 다른 모든 것을 하드 코딩합니다.

환경 관리와 관련하여 Microsoft 제품 및 사내 솔루션을 비롯하여 다양한 방법으로 테스트 및 프로덕션 환경을 구축 할 수 있도록 데이터베이스 연결을 구성 할 수있는 메커니즘이 이미 갖추어져 있어야합니다. 빌드 머신을 설정하는 데 같은 방법을 사용해야합니다.

+0

이게 내가 상상 한 것 같아. 구현해야 할 공정한 비트와, 잠재적으로는 유지하기가 짜증이납니다. 하지만 아무런 고통도 없습니다! – David

0

내 접근 방식은 데이터 액세스 계층 (리포지토리 및 매핑)을 테스트하는 데 사용되는 통합 테스트 집합을 만드는 것입니다. EF에서 POCO 매핑과 같은 "컨벤션 오버 컨버전"방식을 사용하는 ORM 도구를 사용하면 이것이 매우 중요하다고 생각합니다. 새로운 데이터베이스 (현재 개발 DB와 동일)를 생성하고 테스트 데이터의 초기 세트를 생성하는 DB 초기화 스크립트를 가지고 있습니다. 이 스크립트는 테스트를 시작할 때 한 번만 실행됩니다. 테스트가 끝날 때 데이터베이스가 삭제됩니다. 각 통합 테스트는 테스트가 끝날 때 롤백되는 트랜잭션을 사용하므로 모든 테스트에서 테스트 데이터가 동일합니다. DB에서 데이터의 유효성을 검사하기 위해 표준 SqlCommand 접근 방식으로 도우미 클래스를 사용하고 있습니다. SqlCommand를 사용하려면 일반적으로 SqlCommand와 EF 컨텍스트 간의 연결을 공유하지 않기 때문에 테스트에 ReadUncommited 트랜잭션 격리 수준을 사용해야합니다.

+0

감사합니다. 흥미 롭습니다. 나는 왜 당신이 거래를 롤백하는지 약간 확신 할 수 없다. 말한대로 ReadUncommitted 격리 수준을 사용해야합니다. SQL을 실행하여 SqlCommand 도우미 클래스를 사용하여 관련 테이블에서 행을 삭제하지 않는 것이 어떻습니까? – David

+0

이 경우 롤백과 동일한 결과를 갖는 각 테스트에 대해 정리 코드를 만들어야하기 때문입니다. –

1

지난 6 년 동안 나는 주로 지속성을 위해 NHibernate를 사용 해왔다.

단위 테스트 레벨에서 SQLite in-memory를 사용하여 지속성/엔티티 매핑을 테스트하고 통합 테스트 수준에서 실제 데이터베이스 서버 (로컬 및 빌드 서버 모두)를 사용했습니다.

두 경우 모두 NHibernate/Fluent NHibernate가 각각 테스트를 위해 만들 수있는 스크립트로 데이터베이스를 설정합니다 (통합 케이스에서 DB를 나중에 죽일 수 있습니다).이것은 실행하는 데 더 오래 걸리지 만 IMHO는 코드 정리의 위험성이 더 나쁩니다 (BTU, xUnit 테스트 패턴 책에서 이에 대한 토론이 있습니다).

+0

하지만이 방법은 모델의 첫 번째 방법을 사용하는 경우에만 사용할 수 있습니다. –

+0

예. 나는 DDD/"Model + POCOs first"녀석입니다. –