2009-04-17 7 views
1

방금 ​​일부 통합 테스트에서 잡힐 수있는 오류가 응용 프로그램에서 발생 했으므로 시간이 많이 걸렸습니다.통합 테스트 - 어떤 수준의 테스트를 거치고 어떻게 설정합니까?

제 질문은이 테스트의 설정과 코드의 어떤 레이어에서 테스트를 실행하는지에 관한 것입니다. 내가 통합 테스트를 많이해야한다 고려

설정

, 나는,이 (서사적으로 느린 것 생성하고 모든 테스트를 위해 테스트 데이터베이스를 삭제 될 수 없다하더라도 그 경우 SqlLite 인 - 메모리 1). 내 생각은 :

  1. 테스트하기 전에
  2. DB를 내 dev에 옆에 앉아있는 테스트 DB를 가지고, 제대로 내 스키마를 설정 몇 가지 리셋 스크립트를 실행하고 필요한 데이터를 삽입
  3. 을 (특정 케이스를 테스트하지)
  4. 이 테스트 db를 실제 db처럼 사용하십시오.

그러나 모든 [설치]에서 Fluent NHib 구성을 실행해야한다는 것은 매우 낭비스러운 것처럼 보입니다. 이건 그냥 힘든 일인가요? 내 옵션은 무엇입니까?

내 세션은 현재 각각 begin_request 및 end_request (MVC 웹 응용 프로그램)에서 생성 및 삭제 된 UoW 패턴으로 래핑됩니다. 이 문제를 해결하기위한 테스트와 잘 작동하도록 이걸 수정해야합니까?

테스트

실제로 몇 가지 테스트, 내가 어떻게해야합니까를 작성하기 위해 온다?

가능한 가장 높은 수준 (내 MVC 컨트롤러 동작) 또는 가장 낮은 수준 (리포지토리)에서 테스트해야합니까?

내가 가장 낮은 테스트를하면 모든 데이터를 수동으로 하드 코딩해야합니다. 이렇게하면 내 테스트가 코드 변경에 취약 해지며 런타임에 코드에서 실제로 발생할 내용을 나타내지 않게됩니다. 내가 가장 높은 테스트를하면 모든 IoCC 설정을 실행해야 종속성이 주입되고 모든 기능이 작동합니다 (다시 [모든 [SetUp]에서 이것을 반복합니까?)

Meh! 나는 길을 잃었다. 누군가 나를 올바른 방향으로 향하게했다. 세션 공장을 만드는

감사 안부에서

답변

2

, 내 테스트 프로젝트에 _AssemblyCommon라는 클래스를 만들고 거기에서 정적으로 세션 공장을 노출합니다. [SetupFixture] (NUnit) 속성으로 표시된 메소드는 세션 팩토리를 구성합니다.

일반적으로 통합 테스트는 리포지토리에서 CRUD 작업을 다루어야합니다. 이렇게하려면 객체 당 하나의 테스트 메소드 (또는 루트를 집계)를 가지고 그 메소드 내에서 삽입, 검색, 업데이트 및 삭제를 수행합니다. 또한 정의한 모든 계단식 삭제를 테스트합니다. 이러한 작업을 단일 메서드로 유지해도 데이터베이스에 아무런 흔적도 남기지 않습니다. 테스트 데이터를 남기는 통합 테스트가 있지만 문제는 아닙니다.

귀하의 상위 작업은 단위 테스트를 거쳐 가능한 한 저장소를 모의합니다 (가능한 경우 Moq).

1

내 현재 MVC 응용 프로그램에서 저장소와 데이터베이스 간의 상호 작용을 테스트하는 것으로 충분하다는 것을 알았습니다. 무엇보다도, 이것은 NHibernate 매핑의 주름을 제거하는 것입니다. 그 레이어 위에있는 모든 것은 (내가 모든 것을 말할 때 과장되어 있습니다.) 단위 테스트는 격리되어 있습니다. 컨트롤러에서부터 스택까지 데이터베이스에 대한 통합 테스트가 있었고 IoC 컨테이너 (StructureMap)를 사용하여 컨트롤러와 종속성을 구축했지만이 테스트는 실제로 아무것도 추가하지 않았으며 꽤 많은 테스트를 거쳤습니다. 오버 헤드를 유지하기 위해 지금부터는 '통합'테스트에서 제거했습니다.

어쨌든, 테스트 프로세스는이 같은 작품을 사용

데이터 액세스 레이어 테스트 어셈블리에 대한 빌드 프로세스는 FluentNHibernate 구성 ExposeSchema() 호출을 통해 테스트 데이터베이스를 만듭니다. 그런 다음 빌드 프로세스는 데이터베이스의 참조 테이블을 채우기 위해 일부 NHibernate 저장소 레벨 코드를 실행합니다.

실행되는 각 통합 테스트는() 문을 사용하여 System.Transactions.TransactionScope에 래핑되고 TransactionScope에는 Complete()가 호출되지 않으므로 각 테스트를 개별적으로 실행할 수 있고 결과를 다른 테스트 데이터의 상태를 변경하지 않고 ISession에 의해 scope를 사용한다. 예 :

using (new TransactionScope()) 
    { 
    var session = NHibernateTestSessionCreator.GetNHibernateSessionForIntegrationTesting(); 
    // This is an NHibernate ISession - setup any dependencies for the repository tests here 

    var testRepository = new NHibernateGenericRepository<NewsItem>(NHibernateTestSessionCreator.GetNHibernateSessionForIntegrationTesting()) 
    // repository test code goes here - the repository is using a different ISession 

    // Validate the results here directly with the ISession 
    } 

    // at this point the transaction is rolled back and we haven't changed the test data 

즉, 제가 사용하고있는 UnitOfWork 구현을 수정할 필요가 없습니다. 트랜잭션이 상위 레벨에서 롤백됩니다.

관련 문제