단위 테스트가 실패한 이유는 무엇입니까?


93

일부 조직에서는 소프트웨어 릴리스 프로세스의 일부가 단위 테스트를 사용하는 것이지만 어느 시점에서든 모든 단위 테스트를 통과해야합니다. 예를 들어 모든 단위 테스트가 녹색으로 전달되는 화면이있을 수 있습니다.

개인적으로 나는 이것이 다음과 같은 이유가 아니라고 생각합니다.

  1. 그것은 코드가 완벽하고 버그가 없어야한다는 아이디어를 촉진합니다. 실제 세계에서는 어떤 크기의 프로그램에서도 불가능합니다.

  2. 실패 할 단위 테스트를 생각하는 것은 바람직하지 않습니다. 또는 수정하기 까다로운 단위 테스트를 확실히 제시하십시오.

  3. 어떤 시점에서 모든 단위 테스트가 통과하면 어느 시점에서나 소프트웨어 상태에 대한 큰 그림이 없습니다. 로드맵 / 목표가 없습니다.

  4. 구현 전에 단위 테스트를 미리 작성하는 것을 방지합니다.

심지어 단위 테스트에 실패한 소프트웨어를 릴리스하는 것조차 나쁘지 않다고 제안합니다. 최소한 소프트웨어의 일부 측면에는 한계가 있음을 알고 있습니다.

여기에 뭔가 빠졌습니까? 조직이 모든 단위 테스트를 통과해야하는 이유는 무엇입니까? 이것이 꿈의 세계에 살고 있지 않습니까? 그리고 실제로 코드의 실제 이해를 방해하지 않습니까?


의견은 긴 토론을위한 것이 아닙니다. 이 대화는 채팅 으로 이동 되었습니다 .
maple_shaft

답변:


270

이 질문에는 IMHO에 대한 몇 가지 오해가 포함되어 있지만, 내가 집중하고 싶은 주된 것은 로컬 개발 브랜치, 트렁크, 스테이징 또는 릴리스 브랜치를 구분하지 않는다는 것입니다.

로컬 개발 지점에서는 거의 항상 실패한 단위 테스트가있을 수 있습니다. 트렁크에서는 어느 정도만 받아 들일 수 있지만 이미 최대한 빨리 문제를 해결하는 강력한 지표입니다. 트렁크에서 단위 테스트에 실패하면 팀의 나머지 부분이 혼란에 빠질 수 있습니다. 팀의 최신 변경으로 인해 실패했는지 확인해야하기 때문입니다.

준비 또는 릴리스 분기에서 실패한 테스트는 "빨간색 경고"이며 일부 트렁크는 트렁크에서 릴리스 분기로 병합 될 때 일부 변경 세트에 전혀 문제가 있음을 나타냅니다.

심지어 단위 테스트에 실패한 소프트웨어를 릴리스하는 것조차 나쁘지 않다고 제안합니다.

특정 심각도 이하로 알려진 버그가있는 소프트웨어를 릴리스 하는 것이 반드시 나쁘지는 않습니다. 그러나 이러한 알려진 결함으로 인해 유닛 테스트가 실패해서는 안됩니다. 그렇지 않으면, 각 단위 테스트 실행 후, 20 개의 실패한 단위 테스트를 살펴보고 실패가 허용 가능한지 여부를 하나씩 확인해야합니다. 이는 번거롭고 오류가 발생하기 쉬우 며 단위 테스트의 자동화 측면을 상당 부분 버립니다.

수용 가능한 알려진 버그에 대한 테스트가 실제로있는 경우 단위 테스트 도구의 비활성화 / 무시 기능을 사용하십시오 (따라서 기본적으로 실행되지 않고 주문형으로 만 실행 됨). 또한 이슈 트래커에 우선 순위가 낮은 티켓을 추가하면 문제를 잊을 수 없습니다.


18
이것이 실제 답변이라고 생각합니다. OP는 빌드 서버처럼 들리는 "릴리스 프로세스"및 "일부 화면 [테스트 결과 표시]"를 언급합니다. 릴리스는 개발과 동일하지 않습니다 (제작에서 개발하지 마십시오!). 개발에 실패한 테스트를하는 것이 좋습니다. TODO와 같습니다. 빌드 서버로 푸시 될 때 모두 녹색 (DONE)이어야합니다.
Warbo

7
가장 많이 투표 한 것보다 훨씬 더 나은 답변입니다. 이상적인 세계 상황에 대해 강의하지 않고 op가 어디에서 왔는지에 대한 이해를 보여주고 알려진 버그의 가능성을 인정하고 (일부 드문 경우를 해결하기 위해 전체 로드맵을 삭제하지는 않음) 단위 테스트는 확실히해야한다고 설명합니다 릴리스 분기 / 프로세스에서 녹색이어야합니다.
세바스티안 반 덴 브 ek

5
@SebastiaanvandenBroek : 긍정적 인 답변에 감사드립니다. IMHO의 실패한 단위 테스트는 트렁크 에서조차 드물게 발생합니다. 그러한 실패를 너무 자주 얻는 것은 실패를 일으킨 변경을 한 사람뿐만 아니라 팀 전체를 방해하기 때문입니다.
Doc Brown

4
여기서 문제는 모든 자동화 테스트가 단위 테스트라고 생각합니다. 많은 테스트 프레임 워크에는 실패 할 것으로 예상되는 테스트를 표시하는 기능이 포함되어 있습니다 (종종 XFAIL이라고 함). (이는 오류 결과가 필요한 테스트와는 다릅니다. XFAIL 테스트는 이상적으로는 성공하지만 실패합니다.) 테스트 스위트는 여전히 이러한 실패로 통과합니다. 가장 일반적인 사용 사례는 일부 플랫폼에서만 실패하는 것 (및 해당 플랫폼에서는 XFAIL 만 해당)이지만이 기능을 사용하여 너무 많은 작업이 필요한 항목을 추적하는 것도 당연한 일입니다. 그러나 이러한 종류의 테스트는 일반적으로 단위 테스트가 아닙니다.
케빈 카스 카트

1
+1, 나는이 문장에 약간 굵은 글씨를 추가 할 것을 제안하지만, "이것은 성 가시고, 오류가 발생하기 쉬우 며, 사람들이 테스트 스위트의 실패를 노이즈로 무시하도록 조건을 설정하고 , 단위 테스트의 자동화 측면의 상당 부분을 버립니다. .
mtraceur

228

... 모든 단위 테스트는 녹색으로 전달됩니다.

그것은 이다 좋아. 그것에 대해 "있는 것으로 추정되지 않음".

그것은 코드가 완벽하고 버그가 없어야한다는 아이디어를 촉진합니다. 실제 세계에서는 어떤 크기의 프로그램에서도 불가능합니다.

아니요. 코드를 테스트 했으므로이 시점까지 할 수 있습니다. 테스트가 모든 경우를 다룰 수는 없습니다. 그렇다면 오류가 결국 버그 보고서에 표시되고 [실패] 테스트를 작성하여 문제를 재현 한 다음 테스트가 통과하도록 응용 프로그램을 수정합니다.

실패 할 단위 테스트를 생각하는 것은 바람직하지 않습니다.

실패 또는 부정적 테스트는 귀하의 신청서가 받아들이고 받아들이지 않을 것에 대한 확실한 제한을합니다. 내가 아는 대부분의 프로그램은 2 월 30 일의 "날짜"에 반대합니다. 또한 우리가 사용하는 크리에이티브 유형 인 개발자는 "그들의 아기"를 깨뜨리고 싶지 않습니다. "행복한 경로"사례에 중점을두면 취약한 응용 프로그램이 자주 중단됩니다.

개발자와 테스터의 사고 방식을 비교하려면 :

  • 코드가 원하는대로 작동하면 개발자가 중지합니다.
  • 더 이상 코드를 만들 수 없으면 테스터가 중지됩니다.

이들은 근본적으로 다른 관점이며 많은 개발자들이 조정하기 어려운 관점입니다.

또는 수정하기 까다로운 단위 테스트를 확실히 제시하십시오.

당신은 자신을 위해 일하기 위해 테스트를 작성하지 않습니다. 당신은 것을, 당신의 코드가 더 중요하게 수행하고 해야하는 일을하는지 확인하는 테스트를 작성 계속 어떻게해야 무엇을 할 후에 는 내부 구현을 변경했습니다.

  • 디버깅은 코드가 오늘날 원하는 코드를 수행한다는 것을 "증명"합니다 .
  • 테스트는 코드 가 시간지남에 따라 원하는 작업을 계속 수행하는지 "증명"합니다 .

어떤 시점에서 모든 단위 테스트가 통과하면 어느 시점에서나 소프트웨어 상태에 대한 큰 그림이 없습니다. 로드맵 / 목표가 없습니다.

유일한 "그림"테스트는 테스트 시점에 코드가 "작동"하는 스냅 샷입니다. 그 이후에 어떻게 진화 하는가는 다른 이야기입니다.

구현 전에 단위 테스트를 미리 작성하는 것을 방지합니다.

그것이 바로 당신이 해야 할 일입니다. 테스트가 아직 구현되지 않았기 때문에 실패한 테스트를 작성한 다음 메소드 코드를 작성하여 메소드를 작동시키고 테스트에 통과 시키십시오. 그것은 테스트 주도 개발의 핵심입니다.

심지어 단위 테스트에 실패한 소프트웨어를 릴리스하는 것조차 나쁘지 않다고 제안합니다. 최소한 소프트웨어의 일부 측면에는 한계가 있음을 알고 있습니다.

테스트가 실패한 코드를 해제하면 해당 기능의 일부 가 이전처럼 작동하지 않습니다 . 버그를 수정했거나 기능을 향상 시켰기 때문에 의도적 인 조치 일 수 있습니다 (하지만 테스트를 먼저 변경하여 실패한 다음 수정 / 향상을 코딩하여 테스트 작업을 진행해야 함). 더 중요한 것은 : 우리는 모두 인간이며 실수를합니다. 코드를 위반하면 테스트를 중단해야하며 깨진 테스트에서 알람 벨이 울리도록 설정해야합니다.

이것이 꿈의 세계에 살고 있지 않습니까?

어떤 경우는에 살고 실제 세계 개발자는, 전지전능도 infallable 어느 것을 우리가 인정 하지 실수를하고 우리가 필요 안전망 우리를 잡을 경우 우리는 때 이렇게 난장판을!
테스트를 입력하십시오.

그리고 실제로 코드의 실제 이해를 방해하지 않습니까?

혹시. 테스트를 작성하기위한 구현을 반드시 이해할 필요는 없습니다 (그 시점의 일부). 테스트는 응용 프로그램의 동작과 한계를 정의하며 의도적으로 변경하지 않는 한 동일하게 유지되도록합니다.


7
@Tibos : 테스트를 비활성화하는 것은 함수를 주석 처리하는 것과 같습니다. 버전 관리가 있습니다. 그걸 써.
케빈

6
@ 케빈 나는 '사용'이 무슨 뜻인지 모르겠습니다. 테스트를 '건너 뛰기'또는 '보류 중'또는 테스트 실행자가 사용하는 규칙으로 표시하고 해당 건너 뛰기 태그를 버전 제어에 커밋합니다.
18:15

4
@ dcorking : 코드를 주석 처리하지 말고 삭제하십시오. 나중에 필요하다고 판단되면 버전 관리에서 복원하십시오. 비활성화 된 테스트를 커밋하는 것도 마찬가지입니다.
케빈

4
"귀하의 테스트가 모든 경우에 적용되는 것은 아닙니다." 지금까지 테스트 한 모든 사소한 코드 조각에 대해 모든 사례를 다룰 수 는 없습니다 .
corsiKa

6
@Tibos 단위 테스트 제안자는 실패한 테스트 작성에서 코드 작성에 이르는주기 시간이 짧아야합니다 (예 : 20 분, 일부는 30 초 주장). 코드를 즉시 작성할 시간이 없다면 너무 복잡 할 것입니다. 복잡하지 않은 경우 삭제 된 기능이 다시 추가되면 다시 작성할 수 있으므로 테스트를 삭제하십시오. 왜 주석을 달지 않습니까? 기능 다시 추가 될 것이라는 것을 모르므로 주석 처리 된 테스트 (또는 코드)는 노이즈 일뿐입니다.
CJ 데니스

32

단위 테스트가 실패한 이유는 무엇입니까?

테스트 중심 개발은 실패한 테스트 개념에 기반을두고 있습니다. 개발을 추진하기위한 유닛 테스트 실패, 스토리를 추진하기위한 수용 테스트 실패 ...

당신이 빠진 것은 문맥입니다 ; 단위 테스트는 어디에서 실패 할 수 있습니까?

일반적인 대답은 개인 샌드 박스에서만 단위 테스트가 실패한다는 것입니다.

기본 개념은 다음과 같습니다. 실패한 테스트가 공유되는 환경에서는 프로덕션 코드 변경으로 인해 새로운 오류가 발생했는지 이해하기 위해 추가 노력이 필요합니다. 0과 0이 아닌 차이는 N과 N이 아닌 차이보다 감지하고 관리하기가 훨씬 쉽습니다.

또한 공유 코드를 깨끗하게 유지하면 개발자가 작업을 계속할 수 있습니다. 내가 코드를 병합 할 때, 나는 얼마나 많은 시험에 대한 이해 교정으로 해결하기 위해 지급되고있어 문제에서 컨텍스트를 전환 할 필요가 없습니다 해야 실패 할 수 있습니다. 공유 코드가 모든 테스트를 통과하는 경우 변경 사항을 병합 할 때 나타나는 오류는 코드와 기존의 깨끗한 기준선 간의 상호 작용의 일부 여야합니다 .

마찬가지로, 탑승하는 동안 새로운 개발자는 어떤 실패한 테스트가 "허용 가능한지"발견하는 데 시간을 들일 필요가 없기 때문에 생산성이 더 빨라질 수 있습니다.

더 정확하게 말하면, 훈련은 빌드 중에 실행되는 테스트를 통과해야한다는 것입니다.

내가 알 수있는 한, 실패한 테스트를 사용 하지 못하게하는 데 아무런 문제가 없습니다 .

예를 들어 "연속 통합"환경에서는 높은 케이던스에서 코드를 공유하게됩니다. 통합 자주하는 것은 반드시 변경 사항이 준비가 해제되어야한다는 것을 의미하지 않는다. 코드가 준비 될 때까지 코드 섹션으로 트래픽이 방출되지 않도록하는 다양한 다크 배포 기술이 있습니다.

동일한 기술을 사용하여 실패한 테스트를 비활성화 할 수도 있습니다.

포인트 릴리스에서 겪은 연습 중 하나는 여러 가지 실패한 테스트가있는 제품 개발을 다루는 것이 었습니다. 우리가 생각 해낸 답은 단순히 스위트를 살펴보고 실패한 테스트를 비활성화하고 각각을 문서화 하는 것이 었습니다 . 이를 통해 모든 가능한 테스트가 통과 된 시점에 신속하게 도달 할 수 있었고 관리 / 목표 기증자 / 금 소유자는 해당 시점에 도달하기 위해 어떤 거래를했는지 확인할 수 있으며 정리 대 새로운 작업에 대한 정보에 근거한 결정을 내릴 수있었습니다.

한마디로 : 실행중인 제품군에 여러 가지 실패한 테스트를 남기는 외에 수행되지 않은 작업 을 추적하는 다른 기술이 있습니다 .


나는 "없다 ... 말한 것 아무것도 가진 문제 실패한 테스트 입니다 장애인 ".
CJ 데니스

그 변화는 확실히 의미를 명확하게합니다. 감사합니다.
VoiceOfUnreason

26

많은 훌륭한 답변이 있지만 아직 잘 다루지 않은 다른 각도를 추가하고 싶습니다. 정확히 테스트의 요점은 무엇입니까?

코드에 버그가 없는지 확인하기 위해 단위 테스트가 없습니다.

이것이 주요 오해라고 생각합니다. 이것이 그들의 역할이라면, 실제로 모든 곳에서 테스트에 실패했을 것으로 예상됩니다. 대신에

단위 테스트는 코드가 생각한대로 작동하는지 확인합니다.

극단적 인 경우 알려진 버그가 수정 되지 않았는지 확인하는 것이 포함될 수 있습니다 . 요점은 코드베이스를 제어하고 우발적 인 변경을 피하는 것입니다. 변경하면 문제가 없으며 실제로 일부 테스트가 중단 될 것으로 예상됩니다. 코드의 동작이 변경됩니다. 새로 고장난 테스트는 이제 변경 한 내용의 훌륭한 흔적입니다. 모든 파손이 원하는 변경 내용과 일치하는지 확인하십시오. 그렇다면 테스트를 업데이트하고 계속 진행하십시오. 그렇지 않은 경우 새 코드가 반드시 버그가있는 경우 제출하기 전에 돌아가서 수정하십시오!

이제 위의 모든 테스트는 녹색 테스트에서만 유효하며 긍정적 인 결과를 얻을 수 있습니다. 이것이 바로 코드 작동 방식입니다. 빨간색 테스트에는 해당 속성이 없습니다. "이 코드가하지 않는 것"은 유용한 정보가 아닙니다.

합격 시험이 원하는 것일 수 있습니다.

합격 시험과 같은 것이 있습니다. 다음 이정표를 호출하기 위해 수행해야하는 일련의 테스트를 작성할 수 있습니다. 이것들은 그들이 디자인 된 것이기 때문에 빨간색으로 괜찮습니다. 그러나 단위 테스트와는 매우 다르므로 대체 할 수 없으며 대체 할 수도 없습니다.


2
한때 도서관을 다른 도서관으로 교체해야했습니다. 단위 테스트를 통해 모든 코너 사례가 여전히 새 코드로 동일하게 취급되는지 확인할 수있었습니다.
Thorbjørn Ravn Andersen

24

나는 그것을 깨진 창 증후군 과 동등한 소프트웨어로 본다 .

작업 테스트에 따르면 코드의 품질이 우수하고 코드 소유자가 코드를 관리한다고합니다.

품질에 관심을 가져야 할 시점은 작업중인 소스 코드 분기 / 저장소에 따라 다릅니다. 개발 코드는 진행중인 작업을 나타내는 테스트를 잘 깨 뜨렸을 것입니다.

라이브 시스템의 브랜치 / 리포지토리에서 끊어진 테스트는 즉시 알람 벨 울림을 설정해야합니다. 고장난 테스트가 계속 실패 할 수 있거나 영구적으로 "무시"로 표시되는 경우 시간이 지남에 따라 숫자가 줄어 듭니다. 이것들이 정기적으로 검토되지 않는다면, 선례는 깨진 시험이 남아도 괜찮도록 설정 될 것입니다.

고장난 테스트는 많은 상점에서 심각하게 검토되어 고장난 코드를 커밋 할 수 있는지 여부에 대한 제한이 있습니다 .


9
테스트가 시스템의 상태를 문서화하면 항상 통과해야합니다. 그렇지 않은 경우 불변이 깨 졌음을 의미합니다. 그들은 시스템이되는 방법 문서화하지만 가정 하여 단위 테스트 프레임 워크는 "알려진 문제"로 마킹하는 좋은 방법을 지원하는만큼, 당신은 항목을 링크하는 경우 - 수를, 실패 테스트뿐만 아니라 사용을 할 수 있습니다 이슈 트래커에서. 두 가지 접근법 모두 장점이 있다고 생각합니다.
Luaan

1
@Luaan 예, 모든 단위 테스트가 동일하게 생성되었다고 가정합니다. 빌드 관리자가 실행 시간, 취성 정도 및 다양한 다른 기준에 따라 일부 속성을 통해 테스트를 분리하고 주사위를 던지는 것은 드문 일이 아닙니다.
로비 디

이 답변은 제 자신의 경험에 의해 훌륭합니다. 일부 사람들이 실패한 여러 테스트를 무시하거나 특정 시점에서 모범 사례를 어기는 데 익숙해지면 몇 개월이 지나면 무시 된 테스트의 비율이 크게 높아지고 코드 품질이 "해킹 스크립트"수준으로 떨어지게됩니다 . 그리고 그 과정을 모두를 상기시키는 것은 매우 어려울 것입니다.
usr-local-ΕΨΗΕΛΩΝ

11

기본적인 논리적 오류는 다음과 같습니다.

모든 테스트가 통과 될 때 좋은 경우 테스트가 실패하면 나빠 야합니다.

단위 테스트, 그것은 IS 모든 테스트를 통과 할 때 좋은. 그것은이다 도 좋은 테스트가 실패 할 때. 두 사람은 반대 할 필요가 없습니다.

테스트 실패는 사용자에게 도달하기 전에 툴링에서 발견 된 문제입니다. 실수를 게시하기 전에 고칠 수있는 기회입니다. 그리고 그것은 좋은 것입니다.


재미있는 생각의 선. 이 질문의 오류는 다음과 같다 : "단위 테스트가 실패하면 좋기 때문에 모든 테스트가 통과하면 나쁘다".
Doc Brown

마지막 문단은 좋은 점이지만 문제는 "모든 단위 테스트가 통과해야하는 시점"(허용 된 답변이 나타내는대로)과 단위 테스트의 포인트를 더 잘 이해하지 못하는 것 같습니다.
Dukeling

9

필 W의 대답은 훌륭합니다. 교체 할 수 없습니다.

그러나 나는 혼란의 일부였던 다른 부분에 초점을 맞추고 싶습니다.

일부 조직에서 소프트웨어 릴리스 프로세스의 일부는 단위 테스트를 사용하는 것이지만 어느 시점에서든 모든 단위 테스트는 통과해야합니다.

"언제든지"는 귀하의 사건을 과장하고 있습니다. 중요한 것은 다른 변경을 구현 하기 전에 특정 변경이 구현 된 후에 단위 테스트가 통과한다는 것입니다. 이것이 버그를 일으킨 변경을 추적하는 방법입니다. 단위 테스트가 실패 시작한 경우 이후 변화 (25)을 구현하지만 전에 변화 (26)을 구현, 당신은 변화 (25)이 버그의 원인 것을 알고있다.

물론 변경을 구현 하는 동안 단위 테스트는 실패 할 수 있습니다. tat는 변화가 얼마나 큰지에 달려 있습니다. 사소한 조정 이상의 핵심 기능을 다시 개발하는 경우 새 버전의 로직 구현이 완료 될 때까지 잠시 테스트를 중단 할 수 있습니다.


이는 팀 규칙과 관련하여 충돌을 일으킬 수 있습니다. 몇 주 전에 실제로이 문제가 발생했습니다.

  • 모든 커밋 / 푸시는 빌드를 유발합니다. 빌드는 절대 실패하지 않아야합니다 (실패하거나 테스트가 실패하면 커밋 개발자가 책임을집니다).
  • 모든 개발자는 하루가 끝날 무렵 변경 사항을 푸시해야하므로 아침에 팀 리더가 코드 검토를 수행 할 수 있습니다.

어느 쪽이든 괜찮을 것입니다. 그러나 규칙을 함께 사용할 수는 없습니다. 완료하는 데 며칠이 걸리는 주요 변경 사항이 할당되면 두 규칙을 동시에 준수 할 수 없습니다. 내가 매일 변경 사항에 대해 언급하지 않고 모든 작업이 완료된 후에 만 ​​주석 처리를하지 않는 한; 그건 말도 안되는 일입니다.

이 시나리오에서 문제는 단위 테스트가 목적이 없다는 것이 아닙니다. 그것은 것을의 회사가 비현실적인 기대를 가지고 . 그들의 임의의 규칙 세트가 모든 경우를 다루지는 않으며, 규칙을 준수하지 못하면 규칙 실패 (제 경우에는)가 아니라 개발자 실패로 간주됩니다.


3
이것이 작동 할 수 있는 한 가지 방법 은 분기를 사용하여 개발자가 불완전한 동안 깨끗하게 빌드 할 필요가 없지만 핵심 분기에 대한 커밋이 빌드를 트리거하여 깨끗하게 빌드 해야하는 기능 분기를 커밋하고 푸시하는 것입니다.
Gwyn Evans

1
불완전한 변화를 강요하는 것은 터무니없는 일입니다. 변경이 완료되었을 때 코드 검토를하지 않는 이유는 무엇입니까?
Callum Bradbury

예를 들어, 하드 디스크가 작동을 멈추거나 다른 방법으로 잃어버린 경우 코드가 개발자의 랩톱 / 워크 스테이션에만있을뿐만 아니라 작업 도중에도 커밋 정책이있는 경우 코드를 확인하는 빠른 방법입니다. 제한된 양의 작업이 위험합니다.
Gwyn Evans

1
기능 플래그는 명백한 역설을 수정합니다.
RubberDuck

1
기존 논리를 재 작업 한 @Flater 예.
RubberDuck

6

모든 단위 테스트를 수정하지 않으면 깨진 테스트를 수정 한 사람이없는 상태가됩니다.

  1. 단위 테스트를 통과해도 코드가 완벽하지 않음으로 잘못되었습니다

  2. 테스트하기 어려울 코드를 생각해내는 것은 바람직하지 않습니다. 이것은 디자인 관점에서 좋습니다.

  3. 만병 통치약은 아니지만 코드 적용 범위가 도움이 될 수 있습니다. 또한 단위 테스트는 테스트의 한 측면 일뿐입니다. 통합 / 수락 테스트도 원합니다.


6

이미 좋은 답변에 몇 가지 요점을 추가하려면 ...

그러나 어느 시점에서나 모든 단위 테스트는 통과해야합니다

이는 릴리스 프로세스에 대한 이해가 부족함을 나타냅니다. 테스트 실패는 아직 구현되지 않은 TDD에서 계획된 기능을 나타낼 수 있습니다. 또는 향후 릴리스에 대한 수정 계획이있는 알려진 문제를 나타낼 수 있습니다. 또는 단순히 경영진이 결정한 부분 일 수도 있습니다. 고객이 눈치 채지 못할 가능성이 있기 때문에이 문제를 해결하기에는 충분하지 않습니다. 이 모든 공유의 핵심은 경영진이 실패에 대해 판단해야한다는 것입니다.

그것은 코드가 완벽하고 버그가 없어야한다는 아이디어를 촉진합니다. 실제 세계에서는 어떤 크기의 프로그램에서도 불가능합니다.

다른 답변은 테스트의 한계를 다루었습니다.

그래도 버그 제거가 단점이라고 생각하는 이유를 이해하지 못합니다. 확인한 코드를 최선을 다해 전달하지 않으려면 소프트웨어를 사용하는 이유는 무엇입니까?

어떤 시점에서 모든 단위 테스트가 통과하면 어느 시점에서나 소프트웨어 상태에 대한 큰 그림이 없습니다. 로드맵 / 목표가 없습니다.

로드맵이 필요한 이유는 무엇입니까?

단위 테스트는 처음에 기능이 작동하는지 확인한 다음 (회귀 테스트로) 실수로 아무 것도 손상하지 않았는지 확인합니다. 기존 단위 테스트의 모든 기능 에는 로드맵이 없습니다 . 모든 기능은 테스트 한도 내에서 작동하는 것으로 알려져 있습니다. 해당 코드가 완료되면 더 이상 작업 할 필요가 없으므로 로드맵이 없습니다.

전문 엔지니어로서 금도금의 함정을 피해야합니다. 애호가들은 작동하는 무언가로 가장자리를 어루 만지는 시간을 낭비 할 수 있습니다. 전문가로서 우리는 제품을 제공해야합니다. 그것은 우리가 일을하고, 일을하고 있는지, 다음 일로 넘어가는 것을 의미합니다.


6

그것은 코드가 완벽하고 버그가 없어야한다는 아이디어를 촉진합니다. 실제 세계에서는 어떤 크기의 프로그램에서도 불가능합니다.

사실이 아니다. 왜 불가능하다고 생각합니까? 작동하는 프로그램의 예는 다음과 같습니다.

public class MyProgram {
  public boolean alwaysTrue() {
    return true;
  }

  @Test
  public void testAlwaysTrue() {
    assert(alwaysTrue() == true);
  }
}

실패 할 단위 테스트를 생각하는 것은 바람직하지 않습니다. 또는 수정하기 까다로운 단위 테스트를 확실히 제시하십시오.

이 경우 단위 테스트가 아닐 수 있지만 복잡한 경우 통합 테스트

어떤 시점에서 모든 단위 테스트가 통과하면 어느 시점에서나 소프트웨어 상태에 대한 큰 그림이 없습니다. 로드맵 / 목표가 없습니다.

사실, 단위 테스트 라고 불리는 이유는 작은 코드 단위를 확인하는 것입니다.

구현 전에 단위 테스트를 미리 작성하는 것을 방지합니다.

개발자 의지쓰기 방지 어떤 사람들이 그 혜택을 이해하지 않는 경우 테스트를특성상 (QA에서 온 경우 제외)


“개발자들은 본질적으로 테스트를 작성하는 것을 막을 것입니다.”– 그것은 전혀 말도 안됩니다. TDD 및 BDD를 연습하는 전체 개발자 회사에서 근무합니다.
RubberDuck

@RubberDuck 문제의 "사실"에 대답하려고했는데 과장되었습니다. 업데이트하겠습니다
user7294900

"X가 Y의 이점을 이해하지 못하면 X는 Y를 수행하지 못하도록 막을 것입니다."는 거의 모든 X와 Y에 적용되므로 그 설명은 특히 유용하지 않을 것입니다. 테스트를 작성하고 구체적으로 선구자의 이점을 설명하는 것이 더 합리적 일 것입니다.
Dukeling

2
"어떤 크기의 프로그램에도 불가능하다"는 "어떤 크기에 관계없이"모든 프로그램을 의미하는 것은 아니며 "모든 중요한 프로그램 (가장 중요한 길이를 가짐)"을 의미합니다. 중요하고 유용한 프로그램.
Ben Voigt

@ BenVoigt 나는 "중요한 프로그램"을 답으로 줄 것으로 기대하지 않는다.
user7294900

4

코드가 완벽하고 버그가 없어야한다는 아이디어를 촉진합니다.

가장 확실하지 않습니다. 그것은 당신의 테스트가 실패해서는 안된다는 생각을 촉진합니다. 테스트를 받더라도 (완전히 많은 경우에도) "완벽"또는 "버그 없음"에 대한 내용은 오류라고 생각합니다. 테스트가 얼마나 얕거나 깊어 야 하는지를 결정하는 것은 좋은 테스트를 작성하는 데 중요한 부분이며, 우리가 테스트 범주 ( "단위"테스트, 통합 테스트, 오이 의미의 "시나리오"등)를 뚜렷하게 분리 한 이유입니다.

실패 할 단위 테스트를 생각하는 것은 바람직하지 않습니다. 또는 수정하기 까다로운 단위 테스트를 확실히 제시하십시오.

테스트 중심 개발에서는 코딩을 시작하기 전에 모든 단위 테스트가 먼저 실패해야합니다. 바로 이런 이유로 "빨간색 녹색주기"(또는 "적색 녹색 리 팩터주기")라고합니다.

  • 테스트가 실패하지 않으면 코드가 실제로 테스트에 의해 테스트되는지 알 수 없습니다. 이 둘은 전혀 관련이 없을 수도 있습니다.
  • 테스트 를 정확하게 빨간색에서 녹색으로 바꾸도록 코드를 변경하면 더 이상 아무것도하지 않아도되므로 코드가 수행해야하는 작업을 수행 할 수 있으며 더 이상 필요하지 않을 것입니다.

어떤 시점에서 모든 단위 테스트가 통과하면 어느 시점에서나 소프트웨어 상태에 대한 큰 그림이 없습니다. 로드맵 / 목표가 없습니다.

테스트는 좀 더 소소한 목표입니다. 테스트 중심 개발에서 프로그래머는 먼저 테스트 (단일)를 작성한 다음 일부 코드를 구현할 명확한 목표를 갖습니다. 다음 테스트 등.

코드가 작성되기 전에 테스트 기능이 완전하지 않아야합니다.

이 접근 방식에 적합한 언어 및 테스트 라이브러리를 사용하여 올바르게 수행하면 오류 메시지 (예외 / 스택 추적)가 개발자가 작업을 수행해야하는 위치를 직접 가리킬 수 있기 때문에 실제로 개발 속도를 크게 높일 수 있습니다. 다음.

구현 전에 단위 테스트를 미리 작성하는 것을 방지합니다.

나는이 진술이 어떻게 진실인지 알지 못한다. 테스트 작성은 이상적으로 구현 의 일부 여야합니다 .

여기에 뭔가 빠졌습니까? 조직이 모든 단위 테스트를 통과해야하는 이유는 무엇입니까?

조직은 테스트가 코드와 관련이 있기를 기대하기 때문입니다. 성공한 테스트 작성은 애플리케이션의 일부를 문서화했으며 애플리케이션이 테스트 (테스트)의 기능을 수행함을 입증했음을 의미합니다. 더 이상 아무것도 없습니다.

또한 테스트를하는 데있어 매우 중요한 부분은 "회귀"입니다. 자신있게 새 코드를 개발하거나 리팩토링하려고합니다. 많은 양의 녹색 테스트를 수행하면 그렇게 할 수 있습니다.

이것은 조직에서 심리적 수준으로 진행됩니다. 자신의 오류가 테스트에 의해 포착 될 가능성이 높다는 것을 아는 개발자는 자신이 해결해야하는 문제에 대한 지능적이고 대담한 솔루션을 훨씬 더 자유롭게 얻을 수 있습니다. 반면에 테스트를 거치지 않은 개발자는 일정 시간이 지나면 변경 사항이 응용 프로그램의 나머지 부분에 영향을 미치는지 알 수 없기 때문에 중단 될 가능성이 있습니다.

이것이 꿈의 세계에 살고 있지 않습니까?

아닙니다. 테스트 중심 응용 프로그램으로 작업하는 것은 순수한 기쁨입니다. 다른 질문에서 논의 할 수있는 어떤 이유로 든 ( "더 많은 노력"등) 개념이 마음에 들지 않는 한 그렇지 않습니다.

그리고 실제로 코드의 실제 이해를 방해하지 않습니까?

물론 그렇지 않은 이유는 무엇입니까?

테스트를 제외하고 실제로 테스트를 소프트웨어의 주요 문서로 사용하는 대규모 오픈 소스 프로젝트 (코드에 대한 "이해"및 노하우 관리가 매우 시급한 주제 임)가 많이 있습니다. 또한 응용 프로그램 / 라이브러리의 사용자 나 개발자에게 실제적이고 작동하며 구문 적으로 올바른 예제를 제공합니다. 이것은 종종 훌륭하게 작동합니다.

분명히 나쁜 테스트를 작성하는 것은 나쁘다. 그러나 이것은 테스트 자체와는 아무런 관련이 없습니다.


3

(내 원래 의견에서)

필요한 기능과 미래의 목표에는 차이가 있습니다. 테스트는 필요한 기능에 대한 것입니다. 정확하고 공식적이며 실행 가능하며 실패하면 소프트웨어가 작동하지 않습니다. 미래의 목표는 실행 가능할뿐 아니라 정확하거나 공식적이지 않을 수도 있으므로 이슈 / 버그 추적기, 문서, 주석 등의 자연 언어로 유지하는 것이 좋습니다.

연습으로, 질문의 "unit test"구를 "compiler error"(또는 컴파일러가없는 경우 "syntax error")로 바꾸십시오. 릴리스에는 컴파일러 오류가 없어야합니다. 릴리스에는 사용할 수 없기 때문입니다. 그러나 컴파일러 오류와 구문 오류는 개발자 컴퓨터에서 코드를 작성할 때 발생하는 정상적인 상태입니다. 오류는 완료된 후에 만 ​​사라집니다. 그때는 코드를 정확히 눌러야합니다. 이제이 단락에서 "컴파일러 오류"를 "unit test"로 바꿉니다. :)


2

자동화 된 테스트의 목적은 가능한 빨리 무언가 깨 뜨렸을 때 알려주는 것 입니다. 워크 플로는 다음과 같습니다.

  1. 변경
  2. 변경 사항 빌드 및 테스트 (이상적으로 자동)
  3. 테스트가 실패하면 이전에 작동했던 것을 위반했음을 의미합니다.
  4. 테스트가 통과되면 변경 사항에 새로운 회귀가 발생하지 않았 음을 확신해야합니다 (테스트 범위에 따라 다름)

테스트가 이미 실패한 경우 3 단계가 효과적으로 작동하지 않습니다. 테스트는 실패하지만 조사하지 않고 무언가를 파산했는지 여부는 알 수 없습니다. 실패한 테스트 수를 셀 수 있지만 변경으로 인해 하나의 버그가 수정되고 다른 버그가 발생하거나 테스트가 다른 이유로 실패 할 수 있습니다. 즉, 모든 문제가 해결 될 때까지 또는 실패한 각 테스트를 조사 할 때까지 문제가 있는지 알기 전에 일정 시간 동안 기다려야합니다.

단위 테스트가 가능한 빨리 새로 도입 된 버그를 찾을 수있는 기능은 자동화 된 테스트에서 가장 귀중한 것입니다. 결함이 발견 될수록 발견하는 데 더 많은 비용이 소요됩니다.

코드가 완벽하고 버그가 없어야한다는 생각을 고취합니다.
실패 할 단위 테스트를 생각하는 것은 소극적입니다.

당신이 아무 말도하지 않는 작동하지 않는 것들에 대한 테스트 - 것들에 대한 단위 테스트를 작성 일을하거나 해결하려고하는 것이 있습니다. 소프트웨어에 결함이 없음을 의미하지는 않으며, 이전에 단위 테스트를 작성했던 결함이 다시 발생하지 않았 음을 의미합니다.

단위 테스트 작성을 사전에 방지합니다.

그것이 효과가 있다면 미리 테스트를 작성하십시오. 테스트가 통과 될 때까지 마스터 / 트렁크로 검사하지 마십시오.

어떤 시점에서 모든 단위 테스트가 통과하면 어느 시점에서나 소프트웨어 상태에 대한 큰 그림이 없습니다. 로드맵 / 목표가 없습니다.

단위 테스트는 로드맵 / 목표를 설정하기위한 것이 아니라 백 로그를 대신 사용할 수 있습니까? 모든 테스트를 통과하면 "큰 그림"은 소프트웨어가 고장 나지 않은 것입니다 (테스트 범위가 양호한 경우). 잘 했어!


2

기존 답변은 확실히 좋지만 질문에 대한이 근본적인 오해를 다루는 사람은 없습니다.

어느 시점에서나 모든 단위 테스트는 통과해야합니다

가장 확실하게 이것은 사실이 아닙니다. 소프트웨어를 개발하는 동안 NCrunch는 대개 갈색 (빌드 실패) 또는 빨간색 (테스트 실패)입니다.

NCrunch가 녹색 이어야하는 곳 (모든 테스트 통과)은 소스 제어 서버에 커밋을 푸시 할 준비가되었을 때입니다. 그 시점에서 다른 사람들이 내 코드에 의존 할 수 있기 때문입니다.

이것은 또한 새로운 테스트를 만드는 주제를 제공합니다 : 테스트는 코드의 논리와 행동을 표명해야합니다. 경계 조건, 결함 조건 등 새로운 테스트를 작성할 때 코드에서 이러한 "핫스팟"을 식별하려고합니다.

단위 테스트는 전제 조건, 예상 출력 등 내 코드 호출 방법을 문서화합니다.

변경 후 테스트가 중단되면 코드 또는 테스트에 오류가 있는지 확인해야합니다.


참고로, 단위 테스트는 때때로 테스트 주도 개발과 함께 진행됩니다. TDD의 원칙 중 하나는 깨진 테스트가 이정표라는 것입니다. 테스트가 실패하면 테스트를 통과하도록 코드를 수정해야합니다. 이번 주 초의 구체적인 예는 다음과 같습니다.

배경 : 필자는 개발자가 Oracle 쿼리를 검증하는 데 사용하는 라이브러리를 작성하여 지원합니다. 우리는 쿼리가 예상 값과 일치한다고 주장한 테스트를 받았으며, 이는 Oracle이 아닌 대소 문자를 중요하게 만들고 예상 값과 완전히 일치하는 한 유효하지 않은 쿼리를 적절하게 승인했습니다.

대신 내 라이브러리는 Antlr과 Oracle 12c 구문을 사용하여 쿼리를 구문 분석 한 다음 구문 트리 자체에서 다양한 어설 션을 래핑합니다. 예를 들어, 유효하고 (구문 분석 오류가 발생하지 않았 음) 모든 매개 변수가 매개 변수 콜렉션에 의해 충족되며 데이터 리더가 읽은 모든 예상 열이 쿼리에 존재합니다. 다양한 시간에 생산.

동료 엔지니어 중 한 명이 월요일에 주말에 실패했거나 실패했을 때 성공한 쿼리를 보냈습니다. 내 라이브러리는 구문이 훌륭하다고 말했지만 서버가 구문을 실행하려고 할 때 폭발했습니다. 그리고 그가 그 질문을 보았을 때, 이유가 분명했습니다.

UPDATE my_table(
SET column_1 = 'MyValue'
WHERE id_column = 123;

프로젝트를로드 하고이 쿼리가 유효하지 않아야한다고 주장하는 단위 테스트를 추가했습니다. 분명히 테스트는 실패했습니다.

다음으로, 실패한 테스트를 디버깅하고 예외를 발생시킬 것으로 예상되는 코드를 단계별로 살펴 보았 으며 Antlr 이전 코드가 예상 한 방식이 아니라 열린 paren에서 오류를 발생시키는 것으로 나타났습니다 . 코드를 수정하고 테스트가 이제 친환경 (통과)하고 프로세스에서 중단되고 커밋되고 푸시 된 다른 사람이 없음을 확인했습니다.

이 작업은 20 분 정도 걸렸으며이 과정에서 이전에는 무시했던 전체 범위의 오류를 지원했기 때문에 실제로 라이브러리를 크게 개선했습니다. 라이브러리에 대한 단위 테스트가 없다면 문제를 조사하고 수정하는 데 몇 시간이 걸릴 수 있습니다.


0

이전 답변에서 나온 것으로 생각하지 않는 한 가지 점은 내부 테스트와 외부 테스트 사이에 차이가 있다는 것입니다. 내부 테스트는 일부 내부 구성 요소가 정상적으로 작동하는지 테스트합니다. 외부 테스트는 시스템 전체가 정상적으로 작동하고 있음을 보여줍니다. 물론 시스템 장애를 일으키지 않는 구성 요소에 장애가있을 가능성이 있습니다 (아마도 시스템이 사용하지 않거나 구성 요소의 장애로부터 시스템이 복구하는 구성 요소의 기능이있을 수 있음) 구성 요소). 시스템 고장을 초래하지 않는 구성 요소 고장으로 인해 릴리스가 중단되지 않아야합니다.

내부 구성 요소 테스트가 너무 많아 마비 된 프로젝트를 보았습니다. 성능 향상을 시도하고 구현할 때마다 실제로 시스템의 외부에서 보이는 동작을 변경하지 않고 구성 요소의 동작을 변경하기 때문에 수십 가지 테스트를 중단합니다. 이로 인해 프로젝트 전체의 민첩성이 떨어집니다. 외부 시스템 테스트에 대한 투자는 일반적으로 매우 낮은 수준의 구성 요소에 대해 이야기 할 때 내부 구성 요소 테스트에 대한 투자보다 훨씬 더 나은 보상을 얻는다고 생각합니다.

실패한 단위 테스트가 실제로 중요하지 않다고 제안 할 때 이것이 당신이 염두에두고 있는지 궁금합니다. 아마도 단위 테스트의 가치를 평가하고 가치가있는 것보다 더 많은 문제를 일으키는 것을 버리고, 외부에서 볼 수있는 애플리케이션의 동작을 검증하는 테스트에 더 집중해야 할 것입니다.


"외부 테스트"라고 설명하는 내용이 종종 "통합"테스트라고 설명됩니다.
GalacticCowboy

예,하지만 용어의 차이점을 발견했습니다. 어떤 사람들에게는 통합 테스트가 배포 된 소프트웨어 / 하드웨어 / 네트워크 구성에 관한 것이지만 개발중인 소프트웨어의 외부 동작에 대해 이야기하고 있습니다.
Michael Kay

0

"그러나 모든 시점에서 모든 단위 테스트를 통과해야합니다"

그것이 회사의 태도라면 문제입니다. CERTAIN시, 즉 코드가 다음 환경으로 이동할 준비가되었다고 선언하면 모든 단위 테스트를 통과해야합니다. 그러나 개발 과정에서 일상적으로 많은 단위 테스트가 실패 할 것으로 예상합니다.

합리적인 사람은 프로그래머가 첫 번째 시도에서 자신의 작업을 완벽하게 수행 할 것으로 기대하지 않습니다. 우리가 합리적으로 기대하는 것은 알려진 문제가 없을 때까지 계속 노력할 것입니다.

"실패 할 수있는 단위 테스트를 생각하는 것은 바람직하지 않다. 또는 수정하기 까다로운 단위 테스트를 생각 해낼 수있다." 조직의 누군가가 가능한 테스트를 언급하지 않아야한다고 생각한다면 실패 할 수 있고 더 많은 문제를 해결하기 위해 노력할 경우, 그 사람은 자신의 직업에 대한 자격이 없습니다. 이것은 비참한 태도입니다. "내가 수술을 할 때, 바늘이 옳은지를 고의로 확인하지 않는 의사가 필요하니? 작업 완료 속도가 느려질까요? "

코드가 프로덕션에 들어가기 전에 오류를 식별하는 프로그래머에게 팀이 적대적이라면 해당 팀의 태도에 문제가있는 것입니다. 경영진이 배달 속도를 늦추는 오류를 식별하는 프로그래머를 처벌 할 경우, 회사가 파산해야 할 가능성이 높습니다.

그렇습니다. 때때로 합리적 사람들이 "마감일이 다가오고 있습니다. 이것은 사소한 문제이며 지금 해결하기 위해 자원을 바칠 가치가 없습니다."라고 말하는 것은 사실입니다. 하지만 모르는 경우 합리적으로 결정을 내릴 수 없습니다. 오류 목록을 시원하게 검사하고 우선 순위 및 일정을 지정하여 수정하는 것이 합리적입니다. 고의로 자신에게 문제를 모르고 있기 때문에이 결정을 내릴 필요가 없습니다. 알고 싶지 않다고해서 고객이 찾지 못할 것이라고 생각하십니까?


-7

이것은 사람들이 기존의 신념을 확인하는 정보를 찾는 경향이있는 확인 편향 의 구체적인 예입니다 .

이 사건의 유명한 예는 2,4,6 게임입니다.

  • 나는 머리 속에 일련의 세 숫자가 통과하거나 실패한다는 규칙을 가지고 있습니다.
  • 2,4,6은 패스입니다
  • 당신은 세 개의 숫자 집합을 나열 할 수 있으며, 나는 그것이 합격 또는 불합격인지 알려줄 것입니다.

대부분의 사람들은 규칙을 선택합니다. "첫 번째와 두 번째 숫자의 간격은 두 번째와 세 번째 숫자의 간격과 같습니다."

그들은 몇 가지 숫자를 테스트 할 것입니다 :

  • 4, 8, 12? 패스
  • 20, 40, 60? 패스
  • 2, 1004, 2006? 패스

"예, 모든 관찰은 내 가설을 확인시켜줍니다. 사실입니다." 그리고 수수께끼를주는 사람에게 규칙을 발표하십시오.

그러나 그들은 세 개의 숫자 집합에 대해 하나의 '실패'를받지 못했습니다. 규칙은 그들이 실제로 가지고있는 모든 정보에 대해 '세 개의 숫자는 숫자 여야합니다'일 수 있습니다.

규칙은 실제로 숫자가 오름차순이라는 것입니다. 사람들은 일반적으로 실패를 테스트하는 경우에만이 수수께끼를 얻습니다. 대부분의 사람들은 더 구체적인 규칙을 선택하고이 특정 규칙을 만족하는 숫자 만 테스트함으로써 잘못을받습니다.

왜 사람들이 확인 편견에 빠지고 단위 테스트가 문제의 증거로 실패하는 것을 볼 수 있을지 모르지만, 나보다 확인 편향을 더 잘 설명 할 수있는 많은 심리학자들이 있습니다. 자신을 잘못 증명합니다.


2
질문과 어떤 관련이 있습니까? 실패한 단위 테스트 정의상 문제의 증거입니다.
Frax

1
당신은 절대적으로 단위 테스트 할 수 있습니다 요구하는 고장 모드를 입력 테스트중인 시스템. 테스트 실패를 보지 못하는 것과는 다릅니다. 또한 TDD가 "
적색
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.