Citigroup이 단위 실수로이 비싼 실수를 피하는 데 도움이 되었습니까?


86

나는이 snafu에 대해 읽었다 : 15 년 동안 테스트 데이터로 오해 한 합법적 인 거래 후 프로그래밍 버그 비용 Citigroup은 $ 7m 이다.

1990 년대 중반에 시스템이 도입되었을 때 프로그램 코드는 089에서 100까지 3 자리 분기 코드가 제공된 트랜잭션을 걸러 내고 테스트 목적으로 해당 접두사를 사용했습니다.

그러나 1998 년 회사는 사업을 확장하면서 영숫자 지점 코드를 사용하기 시작했습니다. 이 중 코드 10B, 10C 등은 시스템이 제외 범위 내에있는 것으로 간주되어 거래가 SEC로 전송 된 보고서에서 제거되었습니다.

(이것은 비명 시적 인 데이터 표시기를 사용하는 것이 ... 차선 책임을 보여줍니다. 의미 론적으로 명시 적 Branch.IsLive속성 을 채우고 사용하는 것이 훨씬 좋을 것 입니다.)

저의 첫 반응은 "단위 테스트가 여기에 도움이되었을 것입니다."였습니다.

나는 최근에 왜 대부분의 단위 테스트가 관심을 끌지 못하는지 읽습니다. 그래서 내 질문은 : 영숫자 분기 코드의 도입에 실패한 단위 테스트는 어떻게 생겼을까 요?



17
또한 SEC에 수출 한 거래량을 확인한 통합 테스트를 놓친 것 같습니다. 합리적인 점검이 될 내보내기 기능을 빌드하는 경우.
Luc Franken

31
이 기사의 저자는 단위 테스트를 이해하지 못하는 것 같습니다. 일부 주장은 (그냥 평범한 말도있다 "단위 테스트는 특정 방법의 기능 이상 일조분의 일을 테스트 할 가능성이있다" 다른 사람들이 (회귀 분석을 얻기의 기회를 파괴하는 것) 년에 실패 결코 한 검사보고 " 버리십시오 " ). 또는 런타임 예외에 대한 실패한 테스트를 변경해야하는 "단위 테스트를 어설 션으로 변환" 과 같은 제안 이 있습니까?
Groo

25
@gnat 외부 링크를 읽지 못했지만 여전히이 질문이 의미가 있음을 발견했습니다
Jeutnarg

23
가치가있는 것에 대해, 나는 "대부분의 단위 테스트가 왜 낭비인가"의 모든 것에 동의하지 않습니다. 나는 반박을 썼지 만,이 여백은 그것을 포함하기에는 너무 작다.
Robert Harvey

답변:


19

실제로 "단위 테스트가 도움이 되었습니까?"라고 묻거나 "모든 종류의 테스트가 여기에 도움이 되었습니까?"라고 묻고 있습니까?

가장 명백한 형태의 테스트는 코드 자체의 전제 조건 주장이며, 분기 식별자는 숫자로만 구성된다 (이것은 코드 작성시 코더가 가정 한 것으로 가정).

그런 다음 일종의 통합 테스트에서 실패했을 수 있으며 새로운 영숫자 분기 ID가 도입되는 즉시 어설 션이 폭발합니다. 그러나 이것은 단위 테스트가 아닙니다.

또는 SEC 보고서를 생성하는 절차에 대한 통합 테스트가있을 수 있습니다. 이 테스트는 모든 실제 지점 식별자가 해당 거래를보고하므로 사용중인 모든 지점 식별자 목록 인 실제 입력이 필요합니다. 따라서 단위 테스트도 아닙니다.

관련 인터페이스에 대한 정의 나 문서를 볼 수 없지만 장치에 결함이 없기 때문에 장치 테스트에서 오류를 감지하지 못할 수 있습니다 . 기기 식별자는 숫자로 구성되어 해당 분기를 가정하는 것이 허용되고, 개발자가 코드가 경우에 무엇을해야하는지 결정을하지 않을 경우 한하지, 그들은 영숫자 분기 식별자를 올바르게 처리 한 장치의 가정에 유효한 구현을 거부하고 일반적으로 유효한 것을 방지하는 단위 테스트를 작성하고 싶지 않기 때문에 숫자가 아닌 식별자의 경우 특정 동작을 강제하기 위해 단위 테스트를 작성하십시오. 향후 구현 및 확장. 또는 40 년 전에 작성된 문서 중 10B는 실제로 089와 100 사이에 있기 때문에 10B는 테스트 식별자라고 암시 적으로 정의되어 있습니다 (보다 인간 친화적 인 조합 규칙 대신 원시 EBCDIC의 일부 사전 범위를 통해). 15 년 전 누군가가이 식별자를 실제 식별자로 사용하기로 결정했기 때문에 "고장"은 원래 정의를 올바르게 구현하는 장치에 있지 않습니다. 10B가 테스트 식별자로 정의되어 브랜치에 할당되어서는 안된다는 것을 알아 차리지 못한 프로세스에 있습니다. 089-100을 테스트 범위로 정의한 다음 식별자 10 $ 또는 1.0을 도입 한 경우 ASCII에서도 마찬가지입니다. EBCDIC에서 숫자는 문자 뒤에옵니다.

상상할 수있는 단일 단위 테스트 (또는 기능 테스트)하루를 저장했을 수도 있습니다. 새로운 분기 식별자를 생성하거나 확인하는 단위의 테스트입니다. 이 테스트는 식별자에 숫자 만 포함해야하며 분기 식별자 사용자가 동일하게 사용할 수 있도록 작성됩니다. 또는 실제 분기 식별자를 가져 오지만 테스트 식별자를 보지 못하는 단위가있을 수 있으며 모든 테스트 식별자를 거부하도록 단위 테스트를 수행 할 수 있습니다 (식별자가 3 자이면 모두 열거 할 수 있으며 동작을 비교할 수 있습니다) 일치하는지 확인하기 위해 테스트 필터의 유효성 검사기에 대한 유효성 검사기 (스팟 테스트에 대한 일반적인 이의 제기). 그런 다음 누군가 규칙을 변경했을 때 단위 테스트는 새로 요구되는 동작과 모순되기 때문에 실패했을 것입니다.

적절한 이유로 테스트가 있었기 때문에 변경된 비즈니스 요구 사항으로 인해 테스트를 제거해야하는 시점은 누군가가 작업을 수행 할 수있는 기회가됩니다. "코드에서 우리가 원하는 행동에 의존하는 모든 위치를 찾습니다. 변화". 물론 이것은 어렵고 신뢰할 수 없으므로 하루를 절약 할 수는 없습니다. 그러나 속성을 가정하는 단위의 테스트에서 가정을 포착하면 기회가 생겨 노력이 완전히 낭비 되지 않습니다 .

물론 단위가 "재미 모양"입력으로 정의되지 않았다면 테스트 할 것이 없다는 것에 동의합니다. 난해한 정의를 구현하는 데 어려움이 없기 때문에 이름 공간 분할을 제대로 테스트하기가 어려울 수 있습니다. 모든 사람이 재미있는 정의를 이해하고 존중하도록하는 데 있습니다. 이것은 하나의 코드 단위의 로컬 속성이 아닙니다. 또한 일부 데이터 유형을 "숫자 문자열"에서 "영숫자 문자열"로 변경하는 것은 ASCII 기반 프로그램이 유니 코드를 처리하는 것과 유사합니다. 코드가 원래 정의에 크게 연결되어 있으면 언제든 간단하지 않습니다. 데이터 유형은 프로그램이 수행하는 작업의 기본 요소이며 종종 밀접하게 연결됩니다.

많은 노력을 낭비한다고 생각하는 것은 약간 혼란 스럽습니다.

단위 테스트가 때때로 실패하고 (예를 들어 리팩토링하는 동안) 유용한 정보를 제공하는 경우 (예를 들어 변경 사항이 잘못됨) 노력이 낭비되지 않았습니다. 그들이하지 않는 것은 시스템이 작동하는지 테스트하는 것입니다. 따라서 기능 및 통합 테스트 대신 단위 테스트 작성하는 경우 시간을 차분하게 사용하는 것일 수 있습니다.


주장은 좋다!

3
@nocomprende : 레이건이 말했듯이 "신뢰하지만 확인".
Steve Jessop

1
또한 "단위 테스트가 잘못되었습니다!"라고 말하려고했습니다. 그러나 나는 대부분의 사람들이 Animal Farm에 대한 언급을 놓치고 내가 말한 것에 대해 생각하는 대신에 나를 비판 하기 시작했다고 생각했습니다 (무릎 부끄러운 반응은 효과가 없습니다). 그러나 나는 그렇게 말하지 않았습니다. 더 똑똑하고 더 건전한 사람이 그 점을 지적 할 수 있습니다.

2
"모든 테스트는 통과하지만 일부 테스트는 다른 테스트보다 더 통과합니다!"
Graham

1
테스트는 붉은 청어입니다. 이 사람들은 단지 "분기 코드"가 어떻게 정의되었는지 몰랐습니다. 미국 우체국은 우편 번호가 4 자리 숫자를 추가 할 때 우편 번호의 정의를 변경하고 있다는 사실을 모르는 것과 같습니다.
radarbob

120

단위 테스트에서 분기 코드 10B 및 10C가 "테스트 분기"로 잘못 분류되었다는 사실을 발견했을 수 있지만 해당 분기 분류에 대한 테스트가 그 오류를 포착하기에 충분히 광범위했을 것 같지는 않습니다.

반면에, 생성 된 보고서의 스팟 검사는 분기 된 10B 및 10C가 버그가 현재 존재하도록 허용 된 15 년보다 훨씬 빨리 보고서에서 지속적으로 누락 된 것으로 나타났습니다.

마지막으로, 테스트 데이터를 실제 프로덕션 데이터와 하나의 데이터베이스에 혼합하는 것이 좋지 않은 이유는 좋은 예입니다. 테스트 데이터가 포함 된 별도의 데이터베이스를 사용한 경우 공식 보고서에서이를 필터링 할 필요가 없었으며 너무 많이 필터링 할 수 없었습니다.


80
+1 단위 테스트는 믹싱 테스트 및 실제 데이터와 같은 열악한 설계 결정을 절대 보상 할 수 없습니다
Jeutnarg

5
테스트 데이터와 실제 데이터의 혼합을 피하는 것이 가장 좋지만 실제 데이터를 수정해야하는 경우 프로덕션 시스템을 검증하기가 어려울 수 있습니다. 예를 들어, 프로덕션에서 은행 계좌 총계를 수정하여 뱅킹 시스템의 유효성을 검사하는 것은 좋지 않습니다. 코드 범위를 사용하여 의미를 지정하는 것은 문제가됩니다. 레코드의보다 명확한 속성이 더 나은 선택 일 수 있습니다.
JimmyJames

4
@Voo 실제 배포 된 프로덕션 시스템을 테스트하는 것이 가치가 있거나 필요한 것으로 간주되는 수준의 복잡성 또는 안정성 요구 사항이 존재한다는 암묵적인 가정이 있다고 생각합니다. (잘못된 구성 변수로 인해 얼마나 잘못 될 수 있는지 고려하십시오.) 이것이 큰 금융 기관의 경우임을 알 수 있습니다.
jpmc26

4
@Voo 나는 테스트에 대해 이야기하고 있지 않다. 시스템의 유효성 검사에 대해 이야기하고 있습니다. 실제 프로덕션 시스템에는 코드와 관련이없는 여러 가지 방법으로 실패 할 수 있습니다. 새 뱅킹 시스템을 프로덕션에 배치하는 경우 거래가 계정에 적용되지 못하게하는 DB 또는 네트워크 등에 문제가있을 수 있습니다. 나는 은행에서 일한 적이 없지만 가짜 거래로 실제 계정을 수정하기 시작하는 것에 대해 멍청한 확신이 있습니다. 따라서 가짜 계정을 설정하거나 기다렸다가기도 할 수 있습니다.
JimmyJames

12
@JimmyJames 건강 관리에서는 프로덕션 데이터베이스를 테스트 환경에 정기적으로 복사하여 가능한 한 실제에 가까운 데이터에 대한 테스트를 수행하는 것이 일반적입니다. 은행이 똑같이 할 수 있다고 생각합니다.
dj18

75

소프트웨어는 특정 비즈니스 규칙을 처리해야했습니다. 단위 테스트가있는 경우 단위 테스트는 소프트웨어가 비즈니스 규칙을 올바르게 처리했는지 확인했을 것입니다.

비즈니스 규칙이 변경되었습니다.

비즈니스 규칙이 변경되었다는 사실을 아무도 모르고 새로운 비즈니스 규칙을 적용하기 위해 소프트웨어를 변경 한 사람은 없었습니다. 단위 테스트가 있었다면 해당 단위 테스트를 변경해야했지만 아무도 비즈니스 규칙이 변경되었음을 인식하지 못했기 때문에 아무도 그렇게하지 않았습니다.

아니, 단위 테스트는 그것을 잡을 수 없었습니다.

단위 테스트와 소프트웨어가 독립적 인 팀에 의해 작성되었고 단위 테스트를 수행하는 팀이 새로운 비즈니스 규칙을 적용하기 위해 테스트를 변경 한 경우는 예외입니다. 그런 다음 단위 테스트가 실패하여 소프트웨어가 변경되었을 수 있습니다.

물론 단위 테스트가 아닌 소프트웨어 만 변경 한 경우 단위 테스트도 실패합니다. 단위 테스트가 실패 할 때마다 소프트웨어가 잘못되었다는 의미는 아니며 소프트웨어 또는 단위 테스트 (때로는 둘 다)가 잘못되었음을 의미합니다.


2
하나는 코드 단위로 작업하고 다른 하나는 "단위"테스트로 작업하는 다른 팀을 갖는 것이 가능합니까? 어떻게 가능합니까? ... 항상 코드를 리팩토링하고 있습니다.
Sergio

2
@Sergio를 한 관점에서 보면 리팩토링은 동작을 유지하면서 내부를 변경하므로 내부에 의존하지 않고 동작을 테스트하는 방식으로 테스트를 작성하면 업데이트 할 필요가 없습니다.
데니스

1
나는 이것이 여러 번 일어나는 것을 보았다. 소프트웨어는 불만없이 생산되고 있으며, 갑자기 모든 사용자는 더 이상 작동하지 않고 점차적으로 실패하고 있다는 불만으로 폭발합니다. 표준 통지 절차를 따르지 않고 내부 절차를 변경하기로 결정할 때 이런 일이 발생합니다.
Brian Knoblauch

42
"비즈니스 규칙이 변경되었습니다"는 중요한 관찰입니다. 단위 테스트 는 논리가 정확 하지 않은 것으로 생각한 논리를 구현했는지 검증 합니다 .
Ryan Cavanaugh

5
내가 일어난 일에 대해 정확하다면, 이것을 잡기위한 단위 테스트가 작성되지는 않을 것입니다. 테스트 선택의 기본 원칙은 일부 "좋은"사례, 일부 "나쁜"사례 및 경계를 묶는 사례를 테스트하는 것입니다. 이 경우 "099", "100"및 "101"을 테스트합니다. "10B"는 기존 시스템에서 "비 숫자 거부"테스트에 포함되어 있고 새 시스템에서 101보다 크므로 (테스트에 포함) 테스트되므로 테스트 할 이유가 없습니다. EBCDIC, "10B"는 "099"와 "100"사이에서 정렬됩니다.
Mark

29

아니요. 이것은 단위 테스트의 큰 문제 중 하나입니다. 잘못된 보안 감각으로 사용자를 유혹합니다.

모든 테스트가 통과되었다고해서 시스템이 올바르게 작동하는 것은 아닙니다. 그것은 모든 테스트가 통과 되었음을 의미 합니다 . 그것은 당신이 의도적으로 생각하고 테스트를 작성한 디자인 부분들이 당신이 의도적으로 생각한대로 작동하고 있다는 것을 의미합니다. 어쨌든 당신이 그것을 올바르게 얻을 가능성이 큽니다! 그러나 테스트를 작성하려고 생각하지 않았기 때문에이 사례와 같이 전혀 생각하지 않은 사례는 포착 할 수 없습니다 . (그렇다면 코드 변경이 필요하다는 것을 알고 있었을 것입니다.)


17
아버지는 저에게 이렇게 물으 셨습니다. 왜 당신은 생각하지 않은 것을 생각하지 않았습니까? (그는 "만약 당신이 모른다면 물어보십시오 !" 라고 말함으로써 혼동을 일으켰습니다 .) 그러나 내가 모르는 것을 어떻게 알 수 있습니까?

7
"의식적으로 생각하고 테스트를 작성한 디자인 부분이 의도적으로 생각했던대로 작동한다는 것을 의미합니다." 정확히 맞습니다. 이 정보는 리팩토링 중이거나 시스템의 어떤 부분이 가정을 어 기고 변경되는 경우 매우 중요합니다. 잘못된 보안 감각에 빠져있는 개발자는 단순히 단위 테스트의 한계를 이해하지 못하지만 단위 테스트를 쓸모없는 도구로 만들지는 않습니다.
Robert Harvey

12
@MasonWheeler : 저자와 마찬가지로 저자는 단위 테스트가 프로그램이 작동한다는 것을 증명해야한다고 생각합니다. 그렇지 않습니다. 반복하겠습니다 : 단위 테스트는 프로그램이 작동한다는 것을 증명하지 않습니다. 단위 테스트는 분석법이 테스트 계약을 이행한다는 것을 증명하며 그게 전부입니다. 나머지 단일 전제에 놓여 있기 때문에 나머지 용지는 쓰러집니다.
Robert Harvey

5
당연히, 잘못된 믿음을 가진 개발자는 단위 테스트가 완전히 실패했을 때 실망 할 것이지만, 이는 단위 테스트가 아닌 개발자의 잘못이며 단위 테스트가 제공하는 진정한 가치를 무효화하지 않습니다.
Robert Harvey

5
o_O @ 첫 문장. 운전대에 손을 대는 것과 같이 코딩하는 동안 단위 테스트는 잘못된 보안 감각을 제공하며 운전 중 잘못된 보안 감각을 제공합니다.
djechlin

10

반드시 그런 것은 아닙니다.

원래 요구 사항은 숫자 분기 코드를 사용해야했기 때문에 다양한 코드를 허용하고 10B와 같이 거부 한 구성 요소에 대해 단위 테스트를 수행했을 것입니다. 시스템이 작동 한 상태로 전달되었을 것입니다.

그런 다음 요구 사항이 변경되고 코드가 업데이트되었지만 잘못된 데이터를 제공 한 단위 테스트 코드 (지금은 올바른 데이터)를 수정해야했습니다.

이제 우리는 시스템을 관리하는 사람들이 이것이 사실임을 알고 새로운 코드를 처리하기 위해 단위 테스트를 변경할 것이라고 가정합니다. 어쨌든 코드 .. 그들은 그렇게하지 않았다. 원래 코드 10B를 거부 한 단위 테스트는 테스트를 업데이트 할 줄 모르는 경우 실행할 때 "여기에 괜찮습니다"라고 기꺼이 말했습니다.

단위 테스트는 원래 개발에는 좋지만 시스템 테스트에는 적합하지 않습니다. 특히 요구 사항을 오랫동안 잊어 버린 후 15 년이 지나지 않습니다.

이러한 상황에서 필요한 것은 종단 간 통합 테스트입니다. 작업 할 것으로 예상되는 데이터를 전달할 수있는 데이터를 전달할 수 있습니다. 누군가는 새로운 입력 데이터가 보고서를 생성하지 않았다는 사실을 알아 차리고 더 조사 할 것입니다.


에 딱 맞다. 그리고 단위 테스트의 주요 (단독?) 문제. 나는 정확히 같은 것을 말한 것 같이, 내 자신의 대답은 나를 표현 저장된 :) (하지만 아마 더!)
밝기 경주 궤도에

8

유형 테스트 (Haskell 테스트 라이브러리 QuickCheck 및 다른 언어에서 영감을 얻은 다양한 포트 / 대안 으로 예시 된대로 무작위로 생성 된 유효한 데이터를 사용하여 변형을 테스트하는 프로세스 )에서이 문제를 파악했을 수 있습니다. .

이는 분기 코드의 유효성에 대한 규칙이 업데이트 될 때 해당 범위를 올바르게 테스트하기 위해 이러한 특정 범위를 테스트 할 사람이 없었기 때문입니다.

유형 테스트가 사용했던 경우, 누군가는 해야 할 때 구현 된 원래의 시스템 속성의 한 쌍, 하나가 다른 코드를 확인하지 하나를 테스트 지점에 대한 특정 코드가 테스트 데이터로 취급하고 있는지 확인하고 작성했습니다 ... 분기 코드에 대한 데이터 유형 정의가 업데이트되었을 때 (분기에서 숫자로 변경 한 것이 작동하는지 테스트하기 위해 필요한)이 테스트는 다음에서 값 테스트를 시작했습니다. 새로운 범위와 결함을 식별했을 가능성이 높습니다.

물론 QuickCheck는 1999 년에 처음 개발되었으므로 이미이 문제를 포착하기에는 너무 늦었습니다.


1
나는이 속성 기반 테스트를 호출하는 것이 더 일반적이라고 생각합니다. 물론이 변경 사항이 주어지면 여전히 속성 기반 테스트를 작성하는 것이 가능합니다.
jk.

5

단위 테스트 가이 문제에 영향을 줄 것이라고 의심합니다. 새로운 분기 코드를 지원하도록 기능이 변경 되었기 때문에 터널 비전 상황 중 하나 인 것 같지만 시스템의 모든 영역에서 수행 된 것은 아닙니다.

우리는 수업을 디자인하기 위해 단위 테스트를 사용합니다. 디자인이 변경된 경우에만 단위 테스트를 다시 실행해야합니다. 특정 단위가 변경되지 않으면 변경되지 않은 단위 테스트는 이전과 동일한 결과를 반환합니다. 단위 테스트는 다른 단위에 대한 변경의 영향을 보여주지 않습니다 (그렇다면 단위 테스트를 작성하지 않는 경우).

다음을 통해서만이 문제를 합리적으로 감지 할 수 있습니다.

  • 통합 테스트 – 그러나 시스템의 여러 유닛을 통해 피드하려면 새로운 코드 형식을 구체적으로 추가해야합니다 (즉, 원래 테스트에 현재 유효한 분기가 포함 된 경우에만 문제를 보여줍니다)
  • 엔드-투-엔드 테스트-비즈니스는 기존 및 새로운 지사 코드 형식을 통합 한 엔드-투-엔드 테스트를 실행해야합니다.

엔드-투-엔드 테스트가 충분하지 않으면 더 걱정이됩니다. 시스템 변경에 대한 유일한 테스트 또는 MAIN 테스트로 단위 테스트에 의존 할 수 없습니다. 새로 지원되는 지점 코드 형식에 대한 보고서 만 실행하면된다고 들립니다.


2

런타임에 내장 된 어설 션이 도움이되었을 수 있습니다. 예를 들면 다음과 같습니다.

  1. 같은 함수를 만듭니다 bool isTestOnly(string branchCode) { ... }
  2. 필터링 할 보고서를 결정하려면이 기능을 사용하십시오.
  3. 분기 생성 코드에서 어설 션에서 해당 함수를 재사용하여이 유형의 분기 코드를 사용하여 분기를 만들 수 없는지 확인하거나 주장 할 수 있습니다.
  4. 이 어설 션을 실제 런타임에서 활성화하고 "디버그 전용 개발자 버전의 코드를 제외하고 최적화하지 마십시오"‼

또한보십시오:


2

이것에서 테이크 아웃은 Fail Fast 입니다.

코드가 없거나 코드에 따라 분기 접두사를 테스트하거나 포함하지 않는 접두사에 대한 많은 예제가 없습니다. 우리가 가진 전부는 이것입니다 :

  • 089-100 => 테스트 브랜치
  • 10B, 10C => 테스트 브랜치
  • <088 => 아마도 실제 분기
  • > 100 => 아마도 실제 분기

코드가 숫자와 문자열을 허용한다는 사실은 조금 이상합니다. 물론 10B와 10C는 16 진수로 간주 될 수 있지만 접두사가 모두 16 진수로 처리되면 10B와 10C는 테스트 범위를 벗어나 실제 분기로 처리됩니다.

이는 접두사가 문자열로 저장되지만 경우에 따라 숫자로 처리됨을 의미합니다. 내가 생각할 수있는 가장 간단한 코드는 다음과 같습니다 (설명 목적으로 C # 사용).

bool IsTest(string strPrefix) {
    int iPrefix;
    if(int.TryParse(strPrefix, out iPrefix))
        return iPrefix >= 89 && iPrefix <= 100;
    return true; //here is the problem
}

영어에서 문자열이 숫자이고 89와 100 사이이면 테스트입니다. 숫자가 아닌 경우 테스트입니다. 그렇지 않으면 테스트가 아닙니다.

코드가이 패턴을 따르는 경우 코드를 배포 할 때 단위 테스트에서이를 발견하지 못했을 것입니다. 다음은 몇 가지 단위 테스트 예입니다.

assert.isFalse(IsTest("088"))
assert.isTrue(IsTest("089"))
assert.isTrue(IsTest("095"))
assert.isTrue(IsTest("100"))
assert.isFalse(IsTest("101"))
assert.isTrue(IsTest("10B")) // <--- business rule change

단위 테스트에 따르면 "10B"는 테스트 분기로 취급되어야합니다. 위의 @ gnasher729 사용자는 비즈니스 규칙이 변경되었으며 위의 마지막 어설 션이 표시됩니다. 어떤 시점에서 assert가로 바뀌 었어 야 isFalse하지만 그 일은 일어나지 않았습니다. 단위 테스트는 개발 및 빌드 타임에 실행되지만 나중에는 실행되지 않습니다.


여기서 교훈은 무엇입니까? 이 코드는 예상치 못한 입력을 받았다는 신호를 보내는 방법이 필요합니다. 다음은이 코드를 작성하는 다른 방법으로 접두어가 숫자 일 것으로 예상합니다.

// Alternative A
bool TryGetIsTest(string strPrefix, out bool isTest) {
    int iPrefix;
    if(int.TryParse(strPrefix, out iPrefix)) {
        isTest = iPrefix >= 89 && iPrefix <= 100;
        return true;
    }
    isTest = true; //this is just some value that won't be read
    return false;
}

C #을 모르는 경우 반환 값은 코드가 주어진 문자열에서 접두사를 구문 분석 할 수 있는지 여부를 나타냅니다. 반환 값이 true이면 호출 코드는 isTest out 변수를 사용하여 분기 접두사가 테스트 접두사인지 확인할 수 있습니다. 반환 값이 false이면 호출 코드는 주어진 접두사가 예상되지 않는다고보고해야하며 isTest out 변수는 의미가 없으므로 무시해야합니다.

예외가 있으면 괜찮을 수 있습니다.

// Alternative B
bool IsTest(string strPrefix) {
    int iPrefix = int.Parse(strPrefix);
    return iPrefix >= 89 && iPrefix <= 100;
}

이 대안은 더 간단합니다. 이 경우 호출 코드는 예외를 포착해야합니다. 두 경우 모두, 코드는 정수로 변환 할 수없는 strPrefix를 예상하지 않았 음을 호출자에게보고하는 방법이 있어야합니다. 이런 식으로 코드가 빨리 실패하고 은행은 SEC의 훌륭한 당황없이 문제를 신속하게 찾을 수 있습니다.


1

많은 답변과 Dijkstra의 인용문은 하나도 없습니다.

테스트는 버그가 아닌 존재를 보여줍니다.

따라서 다릅니다. 코드가 제대로 테스트 되었다면이 버그가 없을 가능성이 높습니다.


-1

여기에서 단위 테스트를 통해 문제가 처음부터 존재하지 않았을 것이라고 생각합니다.

bool IsTestData(string branchCode)함수를 작성했습니다 .

첫 번째 단위 테스트는 null 및 빈 문자열에 대한 것이어야합니다. 그런 다음 길이가 틀린 문자열은 정수가 아닌 문자열입니다.

모든 테스트를 통과하려면 함수에 매개 변수 확인을 추가해야합니다.

10A의 가능성에 대해 생각하지 않고 '좋은'데이터 001-> 999 만 테스트하더라도 매개 변수 검사는 예외를 피하기 위해 영숫자를 사용하기 시작할 때 함수를 다시 작성하도록합니다.


1
이것은 도움이되지 않았을 것입니다. 기능이 변경되지 않았으며 동일한 테스트 데이터가 주어지면 테스트가 실패하지 않습니다. 누군가는 테스트를 실패로 만들기 위해 테스트를 변경해야한다고 생각했지만, 생각했다면 아마도 기능 변경도 생각했을 것입니다.
헐크

(혹은 "매개 변수 확인"의 의미가 무엇인지 잘 모르겠 기 때문에 뭔가
Hulk

이 함수는 단순 에지 단위 테스트를 통과하기 위해 정수가 아닌 문자열에 대한 예외를 강제로 발생시킵니다. 따라서 특정 프로그래밍없이 영숫자 분기 코드를 사용하기 시작하면 생산 코드 오류가 발생합니다
Ewan

그러나 IsValidBranchCode함수 가이 검사를 수행하기 위해 일부 기능을 사용하지 않았 습니까? 그리고이 기능은 아마도 IsTestData? 를 수정하지 않고도 변경되었을 것입니다 . 따라서 '좋은 데이터'만 테스트하는 경우 테스트가 도움이되지 않습니다. 엣지 케이스 테스트는 실패하기 시작하기 위해 현재 유효한 브랜치 코드를 포함해야했습니다.
헐크

1
검사가 IsValidCode에있어서 함수가 명시 적으로 검사하지 않고 통과하면 놓칠 수는 있지만 그래도 더 많은 테스트, 모의 유효성 검사기 등을 추가 할 수 있습니다. 테스트 번호 "
Ewan
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.