단일 어설 션 단위 테스트가 DRY 원칙을 위반하지 않습니까?


12

단위 테스트를 작성할 때마다 테스트가 실패 할 때 디버깅을 쉽게하기 위해 항상 테스트마다 단일 어설 션을 시도했습니다 . 그러나이 규칙을 따르면 각 테스트에서 동일한 코드를 지속적으로 복사하고 더 많은 테스트를 통해 다시 읽고 유지 관리하기가 더 어려워집니다.

단일 어설 션 테스트는 DRY를 위반합니까?

그리고 방법마다 하나의 테스트를하는 것과 같이 좋은 균형을 찾기 위해 따라야좋은 규칙이 있습니까? *

* 단일 크기가 모든 솔루션에 적합하지는 않지만이 방법을 권장하는 방법이 있습니까?


5
당신은 당신이 방법에 복사 코드를 추출 할 수
이스마일 바다 위

좋은 생각 인 것 같은 @IsmailBadawi. 나는이 메소드들이 내가 테스트하고있는 클래스 객체의 인스턴스를 반환해야한다고 가정 할 것이다
Korey Hinton

1
주어진 상태에서 테스트 할 무언가를 만들고 있습니까? 그것은 비품처럼 들립니다.
Dave Hillier

@DaveHillier 네, 오늘 새로운 단어를 배웠습니다. 감사합니다 :)
Korey Hinton

하나의 Assert * 호출을 의미하는 경우 테스트 당 1 개의 assert를 해석하는 방법에 따라 달라집니다. 그래도 불변 값이 계속 유지되도록하고 (그런 다음 메소드로 추출) 여러 가지 효과가있을 수 있습니다. t 단 하나의 Assert에서 테스트 (또는 당신이 그렇다면 왜 실패했는지 분명하지 않을 것입니다)
ratchet freak

답변:


14

적절한 단위 테스트에는 명명 규칙 이있어 실패한 것을 즉시 식별 할 수 있습니다.

public void AddNewCustomer_CustomerExists_ThrowsException()

따라서 테스트마다 하나의 어설 션이 있으므로 각 방법 (및 이름)이 어설 션중인 조건에 해당합니다.

올바르게 지적했듯이, 각각의 새로운 테스트에는 비슷한 설정 코드가 있습니다. 모든 코드와 마찬가지로 공통 코드를 자체 메서드로 리팩터링하여 중복을 줄이거 나 제거하고 코드를 더 건조하게 만들 수 있습니다. 일부 테스트 프레임 워크는 설치 코드를 한 곳에 배치 할 수 있도록 특별히 설계되었습니다 .

TDD에서는 YAGNI 테스트가 없습니다. 코드에 필요한 작업 만 기반으로 테스트를 작성하기 때문입니다. 필요하지 않으면 테스트를 작성하지 않습니다.


단일 방법으로 리팩토링하는 것이 좋습니다. 클래스의 인스턴스가 특정 상태에 있어야하는 경우 리팩토링 된 메소드에서 해당 객체의 새 인스턴스를 작성하고 반환하거나 초기 테스트 설정을 위해 테스트 프레임 워크에서 제공하는 메소드를 사용하는 것이 좋습니다.
Korey Hinton

마지막 시점에, 난 내가 줄 기능에 대한 테스트를 쓸 수 있습니다 확신 같은 것이 필요하지 않고 기능보다 코드가 가질를
joelb

5

단일 어설 션 테스트는 DRY를 위반합니까?

아니요, 그러나 위반을 조장합니다.

즉, 좋은 객체 지향 디자인은 단위 테스트의 창을 여는 경향이 있습니다. 단위 테스트를 서로 분리하여 테스트를 격리하여 심문 할 수 있고 필요한 경우 다른 테스트를 중단하지 않을 것이라는 확신을 가지고 고정하는 것이 더 중요합니다. 기본적으로 테스트 정확성과 가독성은 크기 나 유지 관리 성보다 중요합니다.

솔직히, 나는 당신이 묘사하는 이유 때문에 테스트 규칙 당 한 가지 주장을 한 적이 없었습니다. (리팩터링을 줄입니다).

함수가 주어진 입력에 대해 "foo"와 "bar"의 목록을 반환해야한다면, 어떤 순서로든 두 개의 assert를 사용하여 둘 다 결과 세트에 있는지 확인하는 것이 좋습니다. 문제가 발생하는 곳은 단일 테스트에서 두 개의 입력 또는 두 개의 부작용을 확인하고 두 원인 중 어느 것이 고장을 유발했는지 알 수없는 경우입니다.

나는 단일 책임 원칙에 대한 변형으로 본다 : 테스트를 실패하게 할 수있는 것은 단 하나뿐이어야하고, 이상적인 세상에서는 변화가 하나의 테스트 만 중단해야한다.

그러나 결국 그것은 트레이드 오프입니다. 모든 복사 붙여 넣기 코드를 유지 관리하는 데 더 많은 시간을 할애하거나 테스트가 여러 소스에 의해 중단 될 수있는 근본 원인을 찾아내는 데 더 많은 시간을 할애합니까? -some- 테스트를 작성하는 한, 그다지 중요하지 않을 것입니다. 단일 어설 션 테스트에 대한 경멸에도 불구하고 더 많은 테스트 측면에서 실수를 저지르는 경향이 있습니다. 귀하의 마일리지가 다를 수 있습니다.


1
테스트의 경우 DRY (Descriptive And Meaningful Phrase)보다 DAMP가 더 중요합니다.
Jörg W Mittag

2

아니요. 이것은 당신이하는 방식 일 것 같습니다. 그들이 좋은 사례라고 주장하는 곳에서 주목할만한 언급을 찾지 못했다면.

테스트 픽스처를 사용하십시오 (XUnit 용어에서는 테스트 세트, 설정 및 해제는 픽스처 임). 즉, 모든 테스트에 적용되는 일부 설정 또는 예제입니다.

일반적으로 코드를 구성 할 때와 같은 방법을 사용하십시오. 리팩토링 테스트시 일반적인 TDD Red-Green-Refactor 는 적용되지 않고 대신 "Red에서 리팩토링"을 적용하십시오. 그건,

  1. 고의로 테스트를 중단하고
  2. 리팩토링
  3. 시험을 고치다

이런 식으로 테스트가 여전히 긍정적이고 부정적인 결과를 제공한다는 것을 알 수 있습니다.

테스트를위한 몇 가지 표준 형식이 있습니다. 예를 들어, 정렬, 작동, 어설 션 또는 제공된시기, 다음 (BDD) . 각 단계마다 별도의 기능을 사용하십시오. 상용구를 줄이기 위해 함수를 호출 할 수 있어야합니다.

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