2009-08-25 3 views
16

우리 팀은 데이터베이스에 충돌하고 결과를 확인하는 수백 가지의 통합 테스트를 수행합니다. 모든 통합 테스트에 대해 두 가지 기본 클래스가 있는데 하나는 검색 전용 테스트 용이고 하나는 생성/업데이트/삭제 테스트 용 클래스입니다. 검색 전용 기본 클래스는 TestFixtureSetup 동안 데이터베이스를 다시 생성하므로 테스트 클래스 당 한 번만 실행됩니다. CUD 기본 클래스는 각 테스트 전에 데이터베이스를 다시 생성합니다. 각 저장소 클래스에는 고유 한 해당 테스트 클래스가 있습니다.통합 테스트 모범 사례

당신이 상상할 수있는 것처럼,이 모든 일에는 꽤 시간이 걸립니다 (빨리 달리고 빠르게 성장하려면 7-8 분이 걸립니다). 이 작업을 CI (CruiseControl.Net)의 일부로 실행하는 것은 문제가되지 않지만 로컬에서 실행하는 것은 오랜 시간이 걸리고 실제로 코드를 커밋하기 전에 실행하는 것을 실제로 금지합니다.

제 질문은 이러한 유형의 통합 테스트 실행 속도를 높이는 데 도움이되는 모범 사례입니까?

우리는 sqlite에서 지원되지 않는 데이터베이스 특정 기능 (계산 된 열 등)을 사용하기 때문에 메모리 내에서 (la sqlite) 실행할 수 없습니다.

또한 팀 전체가 실행할 수 있어야하므로 SQL Server Express 또는 로컬 인스턴스에서 실행하면 연결 문자열이 모두 동일하지 않으면 오류가 발생할 수 있습니다.

귀하의 상점에서 이것을 어떻게 완성하고 있습니까?

감사합니다.

답변

5

나는 자바 개발자이지만 비슷한 문제를 다뤘습니다. 로컬 데이터베이스 인스턴스를 실행하는 것이 속도 때문에 (네트워크를 통해 전송할 데이터가 없음) 잘 작동한다는 것과 통합 테스트 데이터베이스에서 경합이 발생하지 않는다는 것을 알게되었습니다.

이 문제를 해결하기 위해 우리가 사용하는 일반적인 접근 방법은 구성 스크립트에서 데이터베이스 연결 문자열을 구성 파일로 읽은 다음 환경별로 하나의 파일을 설정하는 것입니다. 예를 들어, WORKSTATION에 대한 파일 하나, CI에 대한 파일. 그런 다음 빌드 스크립트를 설정하여 지정된 환경을 기반으로 구성 파일을 읽습니다. 따라서 WORKSTATION 구성을 사용하여 실행되는 개발자 워크 스테이션에서 빌드를 빌드하고 CI 환경에서 실행하는 빌드는 CI 설정을 사용합니다.

또한 각 스크립트가 테스트를 위해 로컬 데이터베이스를 신속하게 설정할 수 있도록 단일 스크립트에서 전체 데이터베이스 스키마를 작성할 수 있으면 대단히 도움이됩니다. 이 개념을 다음 단계로 확장하고 데이터베이스 설치 스크립트를 빌드 프로세스에 추가 할 수도 있으므로 전체 데이터베이스 설정을 스크립팅하여 데이터베이스 스키마의 변경 사항을 따라 잡을 수 있습니다. 당신은 속성 예를 들어 당신의 테스트 클래스 (또는 메소드)을 장식 할 수 NUnit과에

11

:

[Category("Integration")] 
public class SomeTestFixture{ 
    ... 
} 
[Category("Unit")] 
public class SomeOtherTestFixture{ 
    ... 
} 
그런 다음 모든 범주를 실행 얻을하는 서버에 빌드 과정에서 규정하고 단지 개발자하도록 요구할 수 있습니다

사용 가능한 테스트 카테고리의 서브 세트를 실행하십시오. 그들이 실행하는 데 필요한 범주는 내가 이해할 수있는 것보다 더 잘 이해할 수있는 것에 달려 있습니다. 그러나 요점은 단위 수준에서 테스트 할 수 있으며 서버가 통합 테스트를 처리한다는 것입니다.

+1

+1 그게 우리가 내 작업에서하는 일입니다. CIS에서는 단위 테스트가 하루에 한 번씩 모든 체크인 및 통합 테스트를 실행합니다. – mezoid

+2

여기서 모든 빌드에서 통합 테스트를 실행합니다. 통합 테스트를 자주 실행할수록 좋습니다. –

+1

@Ken_Liu - 물론입니다. CI 서버의 사용 가능한 CPU주기와 모멘트의 커밋 수를 비교하는 경우가 종종 있습니다. 이는 모든 개발 팀/환경에 따라 다릅니다. – grenade

3

타이머 나 그와 비슷한 방법으로 측정 한 결과 대부분의 시간을 테스트에서 테스트 한 적이 있습니까?

데이터베이스 레크 리 에이션이 시간 낭비하는 이유를 이미 알고 있다면 다른 방법은 데이터베이스를 한 번 재생성하고 트랜잭션을 사용하여 테스트간에 상태를 보존하는 것입니다.각 CUD 유형 테스트는 설정에서 트랜잭션을 시작하고 해체에서 롤백을 수행합니다. 이렇게하면 트랜잭션 롤백이 전체 데이터베이스 레크레이션보다 저렴하기 때문에 각 테스트에 대한 데이터베이스 설정에 소요되는 시간을 크게 줄일 수 있습니다.

+0

네, 전에이 아이디어를 보았습니다.하지만 테스트하는 코드 중 일부가 트랜잭션 자체를 사용한다면 (통합 테스트라는 것을 기억하십시오)? 그러면 모든 것이 망가질 것이기 때문에 이것이 일반적으로 실용적이지 않다고 생각합니다. – sleske

+1

메소드 내에서 명시적인 트랜잭션 관리를 수행하고 있다면 절대적으로 옳습니다. 이 접근법은 측면 또는 프록시를 사용하여 트랜잭션을 처리하는 경우에 가장 효과적입니다. 우리는 Spring 기반 프로젝트에서이 접근법을 사용했고 통합 테스트 설정은 프록시를 단위 테스트 관리 트랜잭션으로 대체했습니다. 매력처럼 일했습니다. – henrik

3

dev 환경의 일부로 모든 dev 컴퓨터에서 동일한 DB 정의를 실행하는 SQL Server Express 인스턴스가 있습니다. Windows 인증을 사용하면 연결 문자열이 안정적입니다. 문자열에는 사용자 이름/암호가 없습니다.

우리가 실제로하고 싶지만 아직 성취하지 못한 것은 SQL Server Compact Edition에서 시스템을 실행할 수 있는지를 알 수 있습니다. 이는 SQL Server의 엔진이있는 SQLite와 같습니다. 그런 다음 메모리 내에서 실행할 수 있으며, 여러 프로세스를 사용하여 병렬로 실행할 수도 있습니다.

+0

mmm SQL Compact. 그게 * 달콤한 될 것입니다! – grenade

+0

나는 그 생각을 확실히 좋아한다! –

13

빠른 (유닛) 테스트와 느린 (통합) 테스트를 별도로 실행하여 별도로 실행할 수 있습니다. 테스트 프레임 워크에서 테스트를 그룹화/분류하는 데 필요한 모든 방법을 사용하십시오. 테스트 프레임 워크가 테스트 그룹화를 지원하지 않으면 통합 테스트 만 통합 테스트가있는 별도의 모듈로 이동하십시오.

빠른 테스트는 모든 코드를 실행하는 데 불과 몇 초가 걸리고 코드 범위가 커야합니다. 이러한 종류의 테스트는 개발자가 작은 변경을 수행하고 모든 테스트를 실행하고 변경으로 인해 아무 것도 깨뜨리지 않았 음을 확신 할 수 있기 때문에 무자비하게 리팩토링 할 수 있습니다.

느린 테스트를 실행하는 데 많은 시간이 걸릴 수 있으며 개별 구성 요소가 올바르게 작동하는지 확인할 수 있습니다. 개발자가 단위 테스트가 아닌 통합 테스트에 의해 테스트 된 것을 무너 뜨릴 수있는 변경 작업을 수행하면 커밋하기 전에 통합 테스트를 실행해야합니다. 그렇지 않으면 느린 테스트가 CI 서버에서 실행됩니다.