저장소 테스트에 대한 요구 사항으로도 단위 테스트에 대한 최소 백분율 코드 적용을 의무화해야한다면 무엇입니까?
당신이 당신의 대답에 어떻게 도달했는지 설명하십시오 (당신이 한 모든 것이 숫자를 고르면 나 혼자서 할 수 있었을 것입니다).
답변
Alberto Savoia의이 글은 그 질문에 정확하게 답합니다 (그것에 아주 재미있는 방식으로)!
http://www.artima.com/forums/flat.jsp?forum=106&thread=204677
테스트 범위에 대한 Testivus
어느 날 아침, 프로그래머는 위대한 주인에게 물었습니다.
“일부 단위 테스트를 작성할 준비가되었습니다. 어떤 코드 범위를 목표로 삼아야합니까?”
위대한 주인이 대답했다.
“범위에 대해 걱정하지 말고 좋은 테스트를 작성하십시오.”
프로그래머는 미소를 지으며 절을하고 떠났다.
…
그날 나중에 두 번째 프로그래머가 같은 질문을했습니다.
위대한 주인은 끓는 물 냄비를 가리키며 말했습니다.
“그 냄비에 몇 쌀의 쌀을 넣어야합니까?”
프로그래머가 당황스럽게 보며 대답했다.
“어떻게 말할 수 있습니까? 먹이를 줄 사람의 수, 배고픈 사람, 다른 음식을 제공하는 것, 사용할 수있는 쌀의 양 등에 달려 있습니다.”
“정확하게”라고 위대한 주인이 말했습니다.
두 번째 프로그래머는 미소를 지으며 절을하고 떠났다.
…
하루가 끝날 무렵, 세 번째 프로그래머가 와서 코드 범위에 대해 같은 질문을했습니다.
“80 % 이상!” 주인이 맹렬한 목소리로 대답하여 주먹을 탁자 위에 두드렸다.
세 번째 프로그래머는 미소를 지으며 절을하고 떠났다.
…
이 마지막 답변 후, 젊은 견습생이 위대한 주인에게 다가 갔다.
“훌륭한 주인님, 오늘 저는 코드 적용에 관한 동일한 질문에 세 가지 다른 답변을 들었습니다. 왜?”
위대한 주인이 의자에서 일어 섰습니다.
“나와 함께 신선한 차를 마시고 그것에 대해 이야기합시다.”
그들이 뜨거운 녹차를 마시면서 컵을 채운 후 위대한 주인이 대답하기 시작했습니다.
“첫 번째 프로그래머는 새롭고 테스트를 시작했습니다. 지금은 코드가 많고 테스트가 없습니다. 그는 갈 길이 멀다. 현재 코드 범위에 초점을 맞추는 것은 우울하고 쓸모가 없습니다. 그는 테스트를 작성하고 실행하는 데 익숙해지는 것이 좋습니다. 그는 나중에 보험 적용에 대해 걱정할 수 있습니다.”
반면에 두 번째 프로그래머는 프로그래밍과 테스트에 모두 상당한 경험이 있습니다. 냄비에 쌀을 몇 개나 넣어야하는지 대답하면서 필요한 검사 량은 여러 가지 요인에 달려 있으며, 그녀는 내가하는 것보다 더 잘 알고 있다는 사실을 알게되었습니다. 결국 그녀의 코드입니다. . 하나의 단순하고 답이 없으며, 그녀는 진실을 다루고 그와 함께 일할만큼 똑똑합니다.”
젊은 견습생은 이렇게 말했습니다.“단순한 대답이 없다면 왜 세 번째 프로그래머에게 ’80 % 이하로 대답하셨습니까? ‘
위대한 주인은 그의 배가 너무 강하게 크게 웃었고, 녹차보다 더 많이 마셨다는 증거가 위아래로 퍼졌다.
“세번째 프로그래머는 간단한 답변 만 원합니다 – 간단한 답변이없는 경우에도…
젊은 견습생과 어리석은 위대한 주인은 명상적인 침묵 속에서 차를 마셨다.
답변
100 % 적용 범위를 목표로하는 경우 (모든 기능의 100 % 테스트 대신) Code Coverage는 잘못된 측정 기준입니다.
- 모든 라인을 한 번 치면 100 % 얻을 수 있습니다. 그러나 여전히 해당 행에 도달하는 특정 시퀀스 (논리 경로) 테스트를 놓칠 수 있습니다.
- 100 %를 얻을 수는 없지만 여전히 모든 80 % / freq 사용 코드 경로를 테스트했습니다. 당신이 넣은 모든 ‘throw ExceptionTypeX’또는 이와 유사한 방어 적 프로그래밍 가드를 테스트하는 테스트를받는 것은 ‘필수품’이 아닌 ‘좋은 것’입니다
따라서 자신이나 개발자가 자신의 코드를 통해 모든 경로를 철저히 준수해야합니다. 실용적이고 마법의 100 % 적용 범위를 쫓지 마십시오. 코드를 추가하면 90 % 이상의 적용 범위를 보너스로 받아야합니다. 코드 커버리지를 사용하여 놓친 코드 덩어리를 강조 표시하십시오 (TDD를 사용하는 경우에는 발생하지 않아야합니다.
답변
코드 적용 범위는 크지 만 기능 적용 범위가 훨씬 좋습니다. 나는 내가 쓰는 모든 한 줄을 다루는 것을 믿지 않습니다. 그러나 나는 내가 제공하고자하는 모든 기능에 대해 100 % 테스트 범위를 작성한다고 믿습니다.
테스트에서 다루지 않은 코드가 있는지는 신경 쓰지 않지만 코드를 리팩터링하고 다른 동작을하게 될지 걱정합니다. 따라서 100 % 기능 범위가 유일한 목표입니다.
답변
받아 들여진 대답은 좋은 지적입니다. 모든 프로젝트에 표준으로 적합한 단일 숫자는 없습니다. 그러한 표준이 필요없는 프로젝트가 있습니다. 제 생각에 수용 된 답변이 부족한 부분은 주어진 프로젝트에 대해 어떻게 결정을 내릴 수 있는지 설명하는 것입니다.
그렇게하겠습니다. 저는 테스트 엔지니어링 전문가가 아니며 더 많은 정보에 대한 답변을 보게되어 기쁩니다.
코드 범위 요구 사항을 설정하는시기
첫째, 왜 그러한 표준을 먼저 적용하고 싶습니까? 일반적으로 프로세스에 경험적 신뢰를 도입하려고 할 때. “경험적 확신”이란 무엇입니까? 글쎄, 진짜 목표 정확성 . 대부분의 소프트웨어의 경우 모든 입력에서이를 알 수 없으므로 코드가 잘 테스트 되었다고 말합니다 . 이것은 더 잘 알려져 있지만 여전히 주관적인 표준입니다. 표준을 충족했는지 여부에 대해 항상 논의 할 수 있습니다. 이러한 토론은 유용하고 발생해야하지만 불확실성을 드러냅니다.
코드 적용 범위 는 객관적인 측정입니다. 일단 적용 범위 보고서를 보면 표준을 충족했는지 여부에 대한 모호성이 없습니다. 정확성을 증명합니까? 전혀 그렇지는 않지만 코드가 얼마나 잘 테스트되었는지와 분명한 관계가 있으며, 이는 정확성에 대한 신뢰를 높이는 가장 좋은 방법입니다. 코드 적용 범위는 우리가 관심을 갖는 측정 할 수없는 특성에 대한 측정 가능한 근사치입니다.
경험적 표준이 가치를 추가 할 수있는 몇 가지 구체적인 사례 :
- 이해 관계자 만족 많은 프로젝트의 경우, 소프트웨어 개발에 관여하지 않을 수있는 소프트웨어 품질에 관심이있는 다양한 행위자가 있습니다 (매니저, 기술 책임자 등). 우리가 정말로 필요로하는 시험 “은 설득력이 없습니다 : 그들은 전적으로 신뢰하거나 지속적으로 긴밀한 감독으로 검증해야합니다 (기술적 인 이해가 있다고 가정하더라도).
- 팀 행동을 정상화합니다. 이해 관계자 여러분, 여러 사람이 코드와 테스트를 작성하는 팀에서 일하는 경우 “잘 테스트 된”자격을 갖추기위한 모호성이 있습니다. 모든 동료가 어느 수준의 테스트가 충분한 지에 대한 동일한 아이디어를 가지고 있습니까? 아마 아닙니다. 이것을 어떻게 조정합니까? 모두 동의 할 수있는 측정 항목을 찾고 합리적인 근사값으로 수락하십시오. 예를 들어 리드가 주니어 개발자를 직접 감독하지 않는 대규모 팀에 특히 유용합니다. 신뢰 네트워크도 중요하지만 객관적인 측정이 없으면 모든 사람이 선의로 행동하더라도 그룹 행동이 일관성이 없어지기 쉽습니다.
- 자신을 정직하게 유지하십시오. 프로젝트의 유일한 개발자이자 유일한 이해 관계자 인 경우에도 소프트웨어의 특정 특성을 염두에 둘 수 있습니다. 소프트웨어의 성능에 대해 지속적으로 주관적인 평가를 수행하는 대신 (작업이 필요한) 코드 적용 범위를 합리적인 근사치로 사용하여 기계가이를 대신 할 수 있습니다.
사용할 측정 항목
코드 적용 범위는 단일 메트릭이 아닙니다. 적용 범위를 측정하는 방법에는 여러 가지가 있습니다. 표준을 설정할 수있는 것은 어느 표준을 만족시키기 위해 사용하고 있는지에 따라 다릅니다.
표준을 설정하는 데 사용할 수있는 두 가지 일반적인 측정 항목을 예로 사용하겠습니다.
- 명세서 범위 : 테스트 중에 실행 된 명세서의 몇 퍼센트입니까? 코드 의 실제 적용 범위 를 이해하는 데 유용합니다 . 실제로 작성한 코드의 양은 실제로 테스트 했습니까?
- 이러한 종류의 적용 범위는 더 약한 정확성 주장을 지원하지만 달성하기도 더 쉽습니다. 방금 확인하기 위해 코드 커버리지를 사용하는 경우 있음 일들이 (그 이상 시험 품질의 지표로하지) 테스트를받을 다음 문 범위 아마 충분합니다.
- 분기 범위 : 분기 논리 (예 🙂
if
가있는 경우 두 분기를 모두 평가 했습니까? 이렇게하면 코드 의 논리적 적용 범위 를 더 잘 이해할 수 있습니다. 코드에서 가능한 경로 중 몇 개를 테스트 했습니까?- 이러한 종류의 적용 범위는 프로그램이 포괄적 인 입력 세트에서 테스트되었음을 훨씬 더 잘 나타내는 지표입니다. 정확성을 확신하기 위해 코드 적용 범위를 최상의 경험적 근사법으로 사용하는 경우 지점 적용 범위 또는 이와 유사한 기준에 따라 표준을 설정해야합니다.
다른 측정 항목이 있습니다 (줄 적용 범위는 명령문 적용 범위와 유사하지만 예를 들어, 여러 줄 명령문에 대해 다른 숫자 결과를 생성합니다. 조건부 적용 범위 및 경로 적용 범위는 분기 적용 범위와 유사하지만, 프로그램 실행이 발생할 수 있습니다.)
필요한 비율
마지막으로, 원래 질문으로 돌아갑니다. 코드 적용 표준을 설정하면 그 숫자는 무엇입니까?
이 시점에서 우리가 시작할 근사치에 대해 이야기하고 있음을 분명히 알기 때문에 우리가 선택한 숫자는 본질적으로 근사치입니다.
어떤 숫자를 선택할 수 있습니다 :
- 100 % . 모든 것이 테스트되었는지 확인하기 위해 이것을 선택할 수 있습니다. 이것은 테스트 품질에 대한 통찰력을 제공하지는 않지만 일부 품질 테스트가 모든 진술 (또는 지점 등)에 영향을 미쳤다는 것을 다시 말해줍니다. , 당신은 알고 코드의 어떤 부분 집합이 안된 것입니다.
- 일부는 이것이 어리석은 것이라고 주장 할 수 있으며, 실제로 중요한 코드 부분 만 테스트해야합니다. 코드의 일부만 유지해야한다고 주장합니다. 테스트되지 않은 코드를 제거하여 코드 적용 범위를 향상시킬 수 있습니다.
- 99 % (또는 95 %, 90 년대의 다른 숫자) 100 % 와 비슷한 수준의 신뢰를 전달하고자 하지만 때때로 테스트하기 어려운 코너에 대해 걱정하지 않으려면 약간의 여유를 두십시오. 암호.
- 80 % . 이 숫자를 몇 번 사용하는 것을 보았으며 그것이 어디에서 왔는지 완전히 알지 못합니다. 나는 생각 이 80-20 규칙의 이상한 남용 수 있습니다; 일반적으로 여기서 의도는 대부분 의 코드가 테스트 되었음을 보여주기위한 것입니다 . (예, 51 %는 “가장 많음”이지만 80 %는 대부분의 사람들 이 가장 의미 하는 바를 더 잘 반영 합니다. 이는 “잘 테스트 된”이 우선 순위가 아닌 중간 사례에 적합합니다 ( 낮은 가치의 테스트에 노력을 낭비하고 싶지는 않지만 여전히 표준을 정하고 싶은 우선 순위로 충분합니다.
실제로 80 % 미만의 숫자는 보지 못했고 숫자를 설정할 사례를 상상하기가 어렵습니다. 이러한 표준의 역할은 정확성에 대한 신뢰를 높이는 것이며 80 % 미만의 숫자는 특히 자신감을 불러 일으키지는 않습니다. (예, 이것은 주관적이지만 다시 한 번 표준을 설정할 때 주관적인 선택을 한 다음 앞으로 객관적인 측정을 사용하는 것이 좋습니다.)
기타 노트
위의 내용은 정확성이 목표라고 가정합니다. 코드 범위는 정보 일뿐입니다. 다른 목표와 관련이있을 수 있습니다. 예를 들어, 유지 보수성에 관심이있는 경우 느슨한 결합에 관심이있을 수 있습니다. 느슨한 결합은 테스트 가능성에 의해 입증 될 수 있으며, 코드 커버리지에 의해 (특정 방식으로) 측정 될 수 있습니다. 따라서 코드 커버리지 표준은 “유지 보수성”의 품질을 근사화하기위한 경험적 기초를 제공합니다.
답변
내가 가장 좋아하는 코드 범위는 별표로 100 %입니다. 별표는 특정 줄을 “카운트하지 않는”줄로 표시 할 수있는 도구를 선호하기 때문에 발생합니다. “계산 된”라인의 100 %를 커버하면 완료됩니다.
기본 프로세스는 다음과 같습니다.
- 필자는 생각할 수있는 모든 기능과 엣지 사례 (일반적으로 문서에서 작업)를 연습하기 위해 테스트를 작성합니다.
- 코드 커버리지 도구를 실행합니다
- 다루지 않은 라인이나 경로 및 중요하지 않거나 도달 할 수없는 것으로 간주되는 (방어 적 프로그래밍으로 인해) 조사하지 않습니다.
- 누락 된 줄을 다루기 위해 새로운 테스트를 작성하고 해당 사례를 언급하지 않은 경우 설명서를 개선합니다.
이렇게하면 나와 공동 작업자가 새 코드를 추가하거나 나중에 테스트를 변경하는 경우 중요한 내용을 놓쳤는 지 알려주는 밝은 선이 있습니다. 적용 범위가 100 % 아래로 떨어졌습니다. 그러나 다양한 테스트 우선 순위를 처리 할 수있는 유연성도 제공합니다.
답변
공유하고 싶은 테스트 범위에 대한 또 다른 열망이 있습니다.
우리는 트위터를 통해 700 단위 테스트로 20 %의 코드 범위 만 가지고있는 거대한 프로젝트를 가지고 있습니다 .
Scott Hanselman 은 지혜로운 말로 대답했습니다 .
20 %가 맞습니까? 사용자가 가장 많이 이용하는 코드를 나타내는 것이 20 %입니까? 테스트를 50 개 더 추가하고 2 % 만 추가 할 수 있습니다.
다시, 그것은 코드 범위 답변 에 대한 내 Testivus 로 돌아갑니다 . 냄비에 밥을 얼마나 넣어야합니까? 때에 따라 다르지.
답변
단위 테스트가 처음부터 개발을 주도한 잘 설계된 시스템의 경우 85 %가 매우 적습니다. 테스트 가능하도록 설계된 소규모 수업은 그보다 더 잘 다루기가 어렵지 않아야합니다.
이 질문을 다음과 같이 무시하는 것은 쉽습니다.
- 해당 라인은 테스트 된 로직과 같지 않으며 백분율로 너무 많이 읽지 않아야합니다.
사실이지만 코드 범위에 대해 몇 가지 중요한 사항이 있습니다. 내 경험상이 지표는 올바르게 사용될 때 실제로 매우 유용합니다. 나는 모든 시스템을 보지 못했으며 실제 범위를 추가하는 코드 범위 분석을보기 어려운 곳에 많은 시스템이 있다고 확신합니다. 코드는 다르게 보일 수 있으며 사용 가능한 테스트 프레임 워크의 범위는 다를 수 있습니다.
또한, 나의 추론은 주로 매우 짧은 테스트 피드백 루프에 관한 것입니다. 가장 짧은 피드백 루프를 개발하는 제품의 경우 클래스 테스트에서 프로세스 간 신호에 이르는 모든 것을 다루는 매우 유연합니다. 전달 가능한 하위 제품을 테스트하는 데 일반적으로 5 분이 걸리며 이러한 짧은 피드백 루프의 경우 실제로 테스트 결과 (특히 여기에서보고있는 코드 범위 메트릭)를 사용하여 저장소에서 커밋을 거부하거나 수락 할 수 있습니다.
코드 커버리지 메트릭을 사용할 때 반드시 충족되어야하는 고정 된 (임의의) 백분율을 가져서는 안됩니다. 이렇게한다고해서 코드 커버리지 분석의 실질적인 이점은 제 생각에는 없습니다. 대신 다음 측정 항목을 정의하십시오.
- LWM (Low Water Mark), 테스트중인 시스템에서 가장 적은 수의 노출 된 라인
- 테스트중인 시스템에서 가장 높은 코드 적용률 인 High Water Mark (HWM)
새로운 코드는 LWM보다 높지 않고 HWM보다 낮은 경우에만 추가 할 수 있습니다. 즉, 코드 적용 범위 를 줄일 수 없으며 새로운 코드를 적용해야합니다. 내가 말해야한다고 말해야하는 것을 주목하라 (아래 설명).
그러나 이것이 더 이상 사용하지 않는 오래된 잘 테스트 된 쓰레기를 치울 수 없다는 것을 의미하지 않습니까? 그렇기 때문에 이런 것들에 대해 실용적이되어야합니다. 규칙을 위반해야하는 상황이 있지만 일반적인 일상적인 통합을 위해서는 이러한 메트릭스가 매우 유용하다는 경험이 있습니다. 다음 두 가지 의미를 내포합니다.
-
테스트 가능한 코드가 승격됩니다. 새 코드를 추가 할 때는 코드를 테스트 할 수 있도록 노력해야합니다. 테스트 케이스로 코드를 모두 처리해야하기 때문입니다. 테스트 가능한 코드는 일반적으로 좋은 것입니다.
-
레거시 코드에 대한 테스트 범위는 시간이 지남에 따라 증가하고 있습니다. 새 코드를 추가하고 테스트 사례로 처리 할 수없는 경우 LWM 규칙을 피하기 위해 일부 기존 코드를 다루려고 시도 할 수 있습니다. 때때로 필요한 부정 행위는 레거시 코드의 적용 범위가 시간이 지남에 따라 증가 할 것이라는 긍정적 인 부작용을 제공하여 실제로 이러한 규칙을 엄격하게 시행하는 것처럼 보입니다.
그리고 피드백 루프가 너무 길면 통합 프로세스에서 이와 같은 것을 설정하는 것이 실용적이지 않을 수 있습니다.
코드 커버리지 메트릭의 두 가지 일반적인 이점에 대해서도 언급하고 싶습니다.
-
코드 적용 범위 분석은 정적 코드 (예 : Lint)와 달리 동적 코드 분석의 일부입니다. 동적 코드 분석 중에 발견 된 문제점 (purify 제품군, http://www-03.ibm.com/software/products/en/rational-purify-family 와 같은 도구 )은 초기화되지 않은 메모리 읽기 (UMR)와 같은 문제입니다. 메모리 누수 등. 이러한 문제는 코드가 실행 된 테스트 케이스에 의해 커버되는 경우에만 발견 될 수 있습니다 . 테스트 사례에서 다루기가 가장 어려운 코드는 일반적으로 시스템의 비정상 사례이지만 시스템이 정상적으로 실패하기를 원하면 (예 : 충돌 대신 오류 추적) 비정상 사례를 다루는 데 약간의 노력을 기울일 수 있습니다. 동적 코드 분석에서도 마찬가지입니다. 약간의 불운으로 UMR은 segfault 또는 더 나쁜 결과를 초래할 수 있습니다.
-
사람들은 새로운 코드를 100 % 유지하는 데 자부심을 갖고 다른 구현 문제와 비슷한 열정으로 테스트 문제에 대해 토론합니다. 이 기능을보다 테스트 가능한 방식으로 작성하려면 어떻게해야합니까? 이 비정상적인 사건 등을 다루려고 어떻게 할 것입니까?
그리고 완전성에 대한 부정적인.
- 관련 개발자가 많은 대규모 프로젝트에서 모든 사람이 테스트 천재가 될 수는 없습니다. 어떤 사람들은 코드 커버리지 메트릭을 코드가 테스트되었다는 증거로 사용하는 경향 이 있으며이 질문에 대한 다른 많은 답변에서 언급했듯이 이것은 사실 과 거리가 멀습니다 . 제대로 사용하면 좋은 이점을 줄 수있는 하나의 메트릭이지만 잘못 사용하면 실제로 테스트가 잘못 될 수 있습니다. 위에서 언급 한 매우 유용한 부작용 외에도 테스트 대상 시스템은 일부 입력 데이터에 대해 해당 라인에 도달 할 수 있으며 중단 또는 중단없이 실행할 수 있음을 보여줍니다.