응용 프로그램의 CRUD 레이어에서 단위 테스트를 만들 때 테스트를 어떻게 독립적으로 만들 수 있습니까?


14

따라서 단위 테스트를 가능한 한 책별로 만들려고하지만 간단한 추가 / 삭제 방법을 테스트 할 때 문제가됩니다.

add 메소드의 경우 기본적으로 더미 오브젝트를 작성하여 추가해야합니다. 그런 다음 테스트가 완료되면 더미 오브젝트를 삭제해야합니다.

그리고 삭제 테스트를 위해 분명히 삭제할 수 있도록 더미 객체를 만들어야합니다.

하나의 테스트가 실패하면 다른 테스트도 모두 실패하므로 실패합니다.

"주문 취소"라는 테스트를 작성해야하는 시스템과 동일합니다. 우선 일부 더미 주문이 먼저 취소되어야하는데 이것이 단위 테스트 지침에 위배되지 않습니까?

이와 같은 사례를 어떻게 처리해야합니까?


답변:


13

글쎄, 당신이하고있는 일에는 아무런 문제가 없습니다. 여러 테스트에서 동일한 코드를 처리 할 수 ​​있습니다. 그것은 단지 하나의 문제로 여러 테스트가 실패한다는 것을 의미합니다. 피하고 싶은 것은 다른 테스트 결과에 의존하는 테스트입니다. 즉, 삭제 테스트는 실행 된 추가 테스트에 따라 달라 지므로 추가 테스트 전에 삭제 테스트를 실행하면 실패합니다. 이 문제를 방지하려면 각 테스트 시작시 "빈 슬레이트"가 있어야 특정 테스트에서 발생하는 일이 후속 테스트에 영향을 미치지 않도록해야합니다.

이를 수행하는 가장 좋은 방법은 인 메모리 데이터베이스에 대해 테스트를 실행하는 것입니다.

추가 테스트에서 빈 데이터베이스를 작성하고 오브젝트를 추가 한 후 실제로 추가되었는지 확인하십시오.

삭제 테스트에서 이미 삭제하려는 객체로 데이터베이스를 만듭니다. 오브젝트를 삭제하고 삭제되었다고 주장하십시오.

분해 코드에서 데이터베이스를 날려 버립니다.


인 메모리 데이터베이스는 빠르며 (메모리에서) 간단합니다 (프로세스 중). 모든 데이터 저장소에서이 작업을 수행 할 수 있습니다.
Paul Draper

3

거래를 사용하십시오.

트랜잭션을 지원하는 데이터베이스를 사용하는 경우 트랜잭션에서 각 테스트를 실행하십시오. 테스트가 끝나면 트랜잭션을 롤백하십시오. 그런 다음 각 테스트는 데이터베이스를 변경하지 않은 채로 둡니다.

예, 주문을 취소하려면 먼저 주문을 만들어야합니다. 괜찮아. 테스트는 먼저 주문을 생성 한 다음 취소 한 다음 주문이 취소되었는지 확인합니다.


이 아이디어를 좋아하십시오. 오늘 큰 효과로 구현했습니다.
pimbrouwers

3

잘하고 있어요 단위 테스트의 유일한 기본 원칙은 모든 코드 경로를 다루는 것이므로 코드가 수행해야 할 작업을 수행하고 변경 및 리팩토링 후에도 계속 수행 할 수 있습니다. 단위 테스트를 작고 단순하며 단일 목적으로 유지하는 것이 가치있는 목표이지만 근본적인 것은 아닙니다. API의 두 가지 관련 메소드를 호출하는 테스트를 갖는 것은 실제로 의심의 여지가 없지만 실제로 지적한 것처럼 종종 필요합니다. 중복 테스트의 단점은 작성하는 데 시간이 더 걸린다는 것입니다. 그러나 거의 모든 개발 과정에서이 방법은 항상 상충 관계를 유지해야하며 최상의 솔루션은 거의 극단적 인 포인트 중 하나가 아닙니다.


2

소프트웨어 테스팅 기술은 매우 다양하며, 이에 대한 교육을 많이받을수록 서로 다른 (때로는 상충되는) 지침을 많이 보게 될 것입니다. 지나갈 '책'은 하나도 없습니다.

나는 당신이 같은 것을 말하는 단위 테스트에 대한 지침을 본 상황에 있다고 생각합니다.

  • 각 테스트는 독립형이어야하며 다른 테스트의 영향을받지 않아야합니다.
  • 각 단위 테스트는 한 가지만 테스트해야합니다.
  • 단위 테스트는 데이터베이스에 맞지 않아야합니다

등등. 'unit test'정의 방법에 따라 모든 것이 맞습니다 .

나는 "단위 테스트"를 다음과 같이 정의 할 것이다 : "다른 의존적 컴포넌트들과 분리 된 하나의 코드 단위에 대해 하나의 기능을 수행하는 테스트".

이 정의에 따라 수행중인 작업 (테스트를 실행하기 전에 데이터베이스에 레코드를 추가해야하는 경우)은 '단위 테스트'가 아니라 일반적으로 '통합 테스트'라고하는 것 이상의 것입니다. 내 정의에 따르면 실제 단위 테스트는 데이터베이스에 충돌하지 않으므로 삭제하기 전에 레코드를 추가 할 필요가 없습니다.

통합 테스트 (예 : 사용자 인터페이스 등의 여러 구성 요소 사용 기능 행사할 데이터베이스) 및 단위 테스트에 적용될지도는 반드시 통합 테스트에 적용되지 않습니다.

다른 사람들이 그들의 답변에서 언급했듯이, 단위 테스트 지침에 위배되는 일을하더라도 당신이하는 일은 반드시 틀린 것은 아닙니다. 대신, 각 테스트 방법에서 실제로 테스트하는 대상을 추론하고 테스트를 충족하기 위해 여러 구성 요소가 필요하고 일부 구성 요소는 사전 구성이 필요한 경우 계속 진행하십시오.

그러나 무엇보다도 많은 종류의 소프트웨어 테스트 (단위 테스트, 시스템 테스트, 통합 테스트, 탐색 테스트 등)가 있다는 것을 이해하고 한 유형의 지침을 다른 유형에 모두 적용하려고하지 마십시오.


데이터베이스에서 단위 삭제를 테스트 할 수 없다고 말하는가 ?
ChrisF

데이터베이스에 충돌하면 단위 테스트가 아닌 통합 테스트입니다. 그래서 그런 의미에서 아닙니다. 데이터베이스에서 '단위 테스트'를 삭제할 수 없습니다. 단위 테스트 할 있는 것은 테스트중인 코드가 일부 데이터를 삭제하라는 요청을 받으면 데이터 액세스 모듈과 올바르게 상호 작용한다는 것입니다.
Eric King

그러나 요점은 일부 사람들은 '단위 테스트'를 다르게 정의 할 수 있으므로 '단위 테스트'지침을 적용 할 때 지침이 적용되는 방식에 적용되지 않을 수 있으므로주의를 기울여야한다는 것입니다.
Eric King

1

이것이 바로 다른 지침 중 하나가 인터페이스를 사용하는 이유입니다. 메소드가 특정 클래스 구현 대신 인터페이스를 구현하는 오브젝트를 사용하는 경우 나머지 코드베이스에 의존하지 않는 클래스를 작성할 수 있습니다.

또 다른 대안은 조롱 프레임 워크를 사용하는 것입니다. 이를 통해 테스트중인 메소드에 전달할 수있는 이러한 유형의 더미 오브젝트를 쉽게 작성할 수 있습니다. 더미 클래스에 대한 일부 스텁 구현을 작성해야 할 수도 있지만 실제 구현과 테스트와 관련이 있습니다.


1

하나의 테스트가 실패하면 다른 테스트도 모두 실패하므로 실패합니다.

그래서?

... 이것이 단위 테스트 지침에 위배되지 않습니까?

아니.

이와 같은 사례를 어떻게 처리해야합니까?

동일한 테스트로 인해 여러 테스트가 독립적 일 수 있으며 모두 실패합니다. 실제로 정상입니다. 많은 테스트가 일반적인 기능을 간접적으로 테스트 할 수 있습니다. 공통 기능이 손상되면 모두 실패합니다. 아무 문제가 없습니다.

단위 테스트는 클래스로 정확하게 정의 되므로 업데이트 및 삭제 테스트에 사용되는 일반적인 더미 레코드와 같이 코드를 쉽게 공유 할 수 있습니다.


1

모의 프레임 워크를 사용하거나 메모리 내 데이터베이스와 함께 '환경'을 사용할 수 있습니다. 마지막 클래스는 테스트를 실행하기 전에 테스트에 필요한 모든 것을 만들 수있는 클래스입니다.

나는 마지막 것을 선호합니다-사용자는 테스트를 실제 세계에 가장 가깝게하기 위해 일부 데이터를 입력하도록 도울 수 있습니다.


사실이지만 실제 데이터베이스 연결을 실제로 테스트하지는 않습니다. 그것이 항상 작동한다고 가정하지 않으면 가정은 위험합니다.
ChrisF
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.