비즈니스 로직이 변경 될 때 단위 테스트가 실패하면 부서지기 쉬운 것으로 간주됩니까?


27

아래 코드를 참조하십시오; 그것은 여성의 성별을 가진 사람이 제안을받을 수 있는지 여부를 테스트합니다 1 :

[Fact]
public void ReturnsFalseWhenGivenAPersonWithAGenderOfFemale()
{
    var personId = Guid.NewGuid();
    var gender = "F";
    var person = new Person(personId, gender);

    var id = Guid.NewGuid();
    var offer1 = new Offer1(id,"Offer1");
    Assert.False(offer1.IsEligible(person));
}

이 단위 테스트가 성공합니다. 그러나 앞으로 여성에게 'Offer1'이 제공되면 실패 할 것입니다.

오퍼 1을 둘러싼 비즈니스 로직이 변경되면 단위 테스트가 변경되어야합니다. 경우에 따라 (일부 오퍼의 경우) 비즈니스 로직이 데이터베이스에서 다음과 같이 변경됩니다.

update Offers set Gender='M' where offer=1;

그리고 어떤 경우에는 다음과 같은 도메인 모델에서 :

if (Gender=Gender.Male)
{
  //do something
}

경우에 따라 도메인 논리 뒤에있는 규칙이 정기적으로 변경 사항을 제공하지만 경우에 따라 변경되지 않는 경우도 있습니다.


2
다른 각도에서 생각해보십시오 : 테스트중인 시스템에서 로직을 변경할 때 실패하지 않은 테스트를 원하십니까?
Fabio

답변:


77

이것은 일반적인 의미에서 취하지 않습니다. 테스트중인 동작에 영향을 미치지 않는 구현 변경으로 인해 단위 테스트가 중단되면 취약한 것으로 간주됩니다. 비즈니스 로직 자체가 변화하지만,이 논리의 테스트가되어 가정 파괴 할 수 있습니다.

즉, 비즈니스 로직이 실제로 자주 변경되면 기대치를 단위 테스트에 하드 코딩하는 것이 적절하지 않을 수 있습니다. 대신 데이터베이스의 구성이 오퍼에 영향을 미치는지 테스트 할 수 있습니다.

테스트 이름은 Returns False When Given A Person With A Gender Of Female비즈니스 규칙을 설명하지 않습니다. 비즈니스 규칙은 다음과 같습니다 Offers Applicable to M should not be applied to persons of gender F.

따라서 오퍼가 M 유형 개인에게만 적용 가능한 것으로 정의 된 경우 F 유형 사람이 해당 자격을 갖춘 것으로 표시되지 않음 을 확인하는 테스트를 작성할 수 있습니다. 이 테스트는 특정 오퍼 구성이 변경 되더라도 로직이 작동하는지 확인합니다.


@ JaquesB, 그렇다면 단위 테스트가 아니겠습니까? 아니면? 데이터베이스가 관련된 경우 통합 테스트가 될 것이라고 생각합니다. 맞습니까? 비즈니스 로직이 많이 바뀌면 단위 테스트를 사용하지 않는다고 말하는가?
w0051977

@ w0051977 : 테스트 작성 방법에 따라 다릅니다. 테스트에 실제로 데이터베이스에서 무언가를 변경하는 것이 포함되어 있으면 통합 테스트가됩니다.
JacquesB

3
@ w0051977 더 나은 아이디어-저장소가 비즈니스 규칙 구현을 담당하는 구성 요소의 종속성을 갖지 않아야합니다. 저장소를 호출 한 다음 비즈니스 규칙을 호출하는 상위 레벨 오케스트레이션이 있어야합니다. 이제 비즈니스 규칙을 개별적으로 단위 테스트 할 수 있습니다.
Ant P

5
물론 @ w0051977-테스트는 행동을 지정합니다. 구성 요소의 동작을 제어하는 ​​규칙이 변경되면 동작의 변화를 반영하도록 테스트가 변경되어야합니다. 무엇을 하지 말아야 변화에 필요한 것은 변화하는 것보다 다른 동작을 지정하는 시험이다. 동작이 데이터베이스에 의해 결정되면, 다른 코드를 다루는 테스트는 본질적으로 관련이 없으며 해당 데이터베이스 로직이 테스트 범위 내에 있지 않는 한 변경할 필요가 없습니다. 이 범위는 사용자가 정의하는 것이며 단위 테스트인지 통합 테스트인지의 의미는 실제로 중요하지 않습니다.
Ant P

3
비즈니스 로직이 변경되거나 버그가 수정되어 테스트를 조정할 필요가없는 경우 @ w0051977에서이 아이디어를 다소 확장하면 테스트가 충분한 경우를 다루지 않고 일반적으로 확장되어야한다는 신호입니다.
Morgen

14

속성이 프로덕션 데이터베이스 (또는 테스트 용 복제본)에 정의되어 있으면 단위 테스트 가 아닙니다 . 단위 테스트는 작업 단위를 확인하며 특정 외부 상태가 필요하지 않습니다. 이는 Offer1데이터베이스에 남성 전용 오퍼로 정의되어 있다고 가정 합니다. 외부 상태입니다. 따라서 이것은 통합 테스트 , 특히 시스템 또는 승인 테스트에 대한 것입니다. 승인 테스트는 종종 스크립팅되지 않습니다 (테스트 프레임 워크에서 실행되지 않고 사람이 수동으로 수행).

특성이 if명령문 과 함께 도메인 모델에 정의 된 경우 동일한 테스트는 단위 테스트입니다. 그리고 취하기 쉬울 수 있습니다. 그러나 실제 문제는 코드가 취약하다는 것입니다. 일반적으로 비즈니스 행동을 하드 코딩하는 대신 구성 할 수 있으면 코드의 탄력성이 향상됩니다. 작은 코딩 오류를 해결하기위한 급한 배포가 드물기 때문입니다. 그러나 사전 통지없이 변경되는 비즈니스 요구 사항은 화요일 (매주 발생하는 일)입니다.

테스트를 실행하기 위해 단위 테스트 프레임 워크를 사용 중일 수 있습니다. 그러나 단위 테스트 프레임 워크는 단위 테스트 실행으로 제한되지 않습니다. 통합 테스트도 수행 할 수 있습니다.

당신이 단위 테스트를 작성한다면, 당신은 둘을 만들 것입니다 personoffer1데이터베이스 상태에 의존하지 않음으로 처음부터. 같은 것

[Fact]
public void ReturnsFalseWhenGivenAPersonWithAGenderOfFemale()
{
    var personId = Guid.NewGuid();
    var gender = "F";
    var person = new Person(personId, gender);

    var id = Guid.NewGuid();
    var offer1 = new Offer1(id, "ReturnsFalseWhenGivenAPersonWithAGenderOfFemale");
    offer1.markLimitedToGender("M");

    Assert.False(offer1.IsEligible(person));
}

이것은 비즈니스 로직에 따라 변경되지 않습니다. offer1여성 을 거부 한다고 주장하는 것은 아닙니다 . offer1여성을 거부하는 제안 유형을 만들고 있습니다.

테스트의 일부로 데이터베이스를 작성하고 구성 할 수 있습니다. C #에서 NUnit을 사용하거나 Java의 JUnit에서 Setup메소드로 데이터베이스를 설정합니다 . 아마도 당신의 테스트 프레임 워크는 비슷한 개념을 가지고있을 것입니다. 이 방법에서는 SQL을 사용하여 데이터베이스에 레코드를 삽입 할 수 있습니다.

프로덕션 데이터베이스를 테스트 데이터베이스로 대체하는 코드를 작성하기 어려운 경우 애플리케이션의 테스트 취약점처럼 들립니다. 테스트의 경우 대체를 허용하는 종속성 주입과 같은 것을 사용하는 것이 좋습니다. 그런 다음 현재 비즈니스 규칙과 독립적 인 테스트를 작성할 수 있습니다.

이것의 부수적 인 이점은 종종 비즈니스 소유자 (회사 계층에서이 제품을 담당하는 사람과 같은 회사 소유자 일 필요는 없음)가 비즈니스 규칙을 직접 구성하는 것이 더 쉽다는 것입니다. 이러한 종류의 기술 프레임 워크가있는 경우 비즈니스 소유자가 UI (사용자 인터페이스)를 사용하여 오퍼를 구성하기가 쉽습니다. 비즈니스 소유자는 UI에서 제한을 선택하고 markLimitedToGender("M")호출을 발행합니다 . 그런 다음 오퍼가 데이터베이스에 지속되면이를 저장합니다. 그러나 오퍼를 사용하기 위해 오퍼를 저장하지 않아도됩니다. 따라서 테스트에서 데이터베이스에 존재하지 않는 오퍼를 작성하고 구성 할 수 있습니다.

설명 된대로 시스템에서 비즈니스 소유자는 기술 그룹에 요청하여 적절한 SQL을 발행하고 테스트를 업데이트해야합니다. 또는 기술 그룹에서 코드와 테스트를 편집해야합니다 (또는 테스트 한 다음 코드). 다소 무거운 접근법입니다. 넌 할 수있어. 그러나 테스트하지 않아도 소프트웨어는 덜 취하기 쉽습니다.

TL; DR : 이와 같은 테스트를 작성할 수 있지만 소프트웨어를 작성하지 않아도되기 때문에 소프트웨어를 작성하는 것이 좋습니다.


귀하의 답변에서 약간의 세부 사항을 개선 할 수있는 자유를 제공합니다. 당신의 의도가 맞는지 확인하십시오.
Doc Brown

원래 게시물에는 데이터베이스가 관련되어 있다는 표시가 없습니다. 따라서 Offer1이 이미 데이터베이스에 있다고 가정하면 기괴합니다.
Winston Ewert

2
@WinstonEwert : 명확한 표시가 있으므로 질문을 더주의 깊게 읽어야합니다. 처음 읽을 때도 그것을 알지 못했지만 실제로 OP가 말하고있는 것입니다.
Doc Brown

@ mdfst13, 미안합니다. 그러나 OP가 말하는 것은 조건이 때때로 데이터베이스 및 때로는 도메인 모델에 있다는 것입니다. 귀하의 답변은 첫 번째 경우에는 완벽하고 두 번째 경우에는 끝이 없습니다. 그 요점을 명확히하기 위해 답을 편집하면 성급한 공세를 제거 할 것입니다.
Winston Ewert
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.