기존 생산 프로젝트에 단위 테스트를 성공적으로 추가 할 수 있습니까? 그렇다면 어떻게 그리고 가치가 있습니까?


140

프로덕션중인 기존 프로젝트에 단위 테스트를 추가 할 것을 강력히 고려하고 있습니다. TDD (face palm)의 이점을 실제로보기 전에 18 개월 전에 시작 되었으므로 이제는 많은 프로젝트가있는 다소 큰 솔루션이며 단위 테스트를 추가하기 위해 어디에서 시작 해야할지 가장 어리석은 아이디어가 아닙니다. 내가 이것을 고려하게하는 것은 때때로 오래된 버그가 다시 나타나는 것처럼 보이거나 버그가 실제로 수정되지 않고 수정 된 것으로 체크인 된다는 것입니다. 단위 테스트는 이러한 문제 발생을 줄이거 나 방지합니다.

SO에 대한 비슷한 질문을 읽음으로써 버그 추적기에서 시작하고 회귀를 막기 위해 각 버그에 대한 테스트 사례를 작성하는 것과 같은 권장 사항을 보았습니다. 그러나 나는 큰 그림을 잃어 버리고 결국 TDD를 사용하면 포함 된 기본 테스트가 누락 될까 걱정하고 있습니다.

기존 솔루션이 제대로 단위 테스트를 거치지 않고 제대로 테스트 되도록하기 위해 준수해야하는 프로세스 / 단계가 있습니까? 테스트의 품질 이 우수하고 테스트 의 사례가 아니라는 것이 테스트가없는 것보다 낫다 는 것을 어떻게 보장 할 수 있습니까 ?

그래서 나는 또한 요구하는 것이 같아요.

  • 프로덕션 환경에있는 기존 솔루션에 대한 노력의 가치가 있습니까?
  • 이 프로젝트의 테스트를 무시하고 나중에 다시 작성할 수 있도록 추가하는 것이 더 좋습니까?
  • 더 유익한 것은 무엇입니까? 몇 주 동안 테스트를 추가하거나 몇 주 동안 기능을 추가합니까?

(분명히 세 번째 요점에 대한 답변은 전적으로 관리자 또는 개발자와 대화하고 있는지 여부에 달려 있습니다)


현상금에 대한 이유

현상금을 추가하여 기존의 의심을 확인하는 것뿐만 아니라 수행해야 할 좋은 이유를 확인하는 더 넓은 범위의 답변을 시도하고 유치하려고합니다.

이 장을 나중에 장단점으로 작성하여 경영진에게 제품의 미래 개발을 TDD로 옮기는 데 시간을 투자 할 가치가 있음을 보여 주려고 노력하고 있습니다. 나는이 도전에 접근하고 편견없이 자신의 추론을 발전 시키려고합니다.


11
주제에 관한 Michael Feathers의 책에 대한 의무적 인 링크 : amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/…
Mark Rushakoff

1
@Mark-감사합니다. 제공 한 링크에 있습니다. 나는 다른 책을 사지 않고 괜찮은 답변을 얻기를 바랐습니다.하지만 책을 너무 많이 가질 수는 없지만 (일을 끝내고 싶지 않다면).
djdd87

1
이 책을 읽어야합니다. :) 그것은 내가 가장 좋아하는 것 중 하나이며 리팩토링과 자동 테스트 사이의 긴장을 이해하는 데 정말로 도움이됩니다.
마누엘 알다 나

답변:


177

이전에는 없었던 코드 기반에 단위 테스트를 도입했습니다. 내가이 작업을 수행 한 마지막 큰 프로젝트는 팀에 도착했을 때 제품 테스트가없는 상태에서 이미 생산되었습니다. 내가 2 년 후에 떠났을 때, 우리는 4500+ 정도의 테스트를 거쳐 230 000 + 프로덕션 LOC (실시간 금융 Win-Forms 응용 프로그램)가 포함 된 코드베이스에서 약 33 %의 코드 커버리지를 산출했습니다. 저음으로 들릴지 모르지만 결과적으로 코드 품질과 결함률이 크게 개선되어 사기와 수익성이 향상되었습니다.

관련 당사자의 정확한 이해와 약속이 모두있을 때 수행 할 수 있습니다.

우선, 단위 테스트는 그 자체가 기술이라는 것을 이해하는 것이 중요합니다. "기존의"표준으로 생산성이 높은 프로그래머가 되더라도 더 큰 프로젝트에서 확장되는 방식으로 단위 테스트를 작성하는 데 어려움을 겪을 수 있습니다.

또한 특히 상황에 따라 테스트가없는 기존 코드베이스에 단위 테스트를 추가하는 것도 전문 기술입니다. 귀하 또는 귀하의 팀원이 기존 코드 기반에 단위 테스트를 도입 한 경험이 없다면, Feather 's book을 읽는 것이 필수입니다 (선택적이거나 강력하게 권장되지 않음).

코드 단위 테스트로 전환하는 것은 코드베이스의 품질만큼이나 사람과 기술에 대한 투자입니다. 이를 이해하는 것은 사고 방식과 기대 관리 측면에서 매우 중요합니다.

귀하의 의견과 질문에 대해 :

그러나 나는 큰 그림을 잃어 버리고 결국 TDD를 사용하면 포함 된 기본 테스트가 누락 될까 걱정하고 있습니다.

짧은 대답 : 그렇습니다. 테스트를 놓치면 처음에는 그린 필드 상황에서와 똑같이 보이지 않을 수 있습니다.

더 깊은 수준의 대답은 이것입니다 : 그것은 중요하지 않습니다. 테스트없이 시작하십시오. 테스트 추가를 시작하고 진행하면서 리팩터링하십시오. 기술 수준이 향상되면 프로젝트에 추가 된 모든 새로 작성된 코드에 대한 기준을 높이십시오. 계속 개선하십시오 ...

자, 여기서 줄 사이를 읽으면서 이것이 "행동을 취하지 않는 변명"으로서의 생각에서 온다는 인상을받습니다. 더 나은 사고 방식은 자기 신뢰에 집중하는 것입니다. 어떻게해야할지 아직 모를 수도 있지만, 빈칸을 채우는 방법을 알아낼 것입니다. 따라서 걱정할 이유가 없습니다.

다시, 그 기술. 선형 방식으로 하나의 "프로세스"또는 "단계별"쿡 북 접근 방식으로 제로 테스트에서 TDD- 완벽으로 이동할 수 없습니다. 과정이 될 것입니다. 점진적이고 점진적인 진전과 개선을 기대해야합니다. 마법의 약은 없습니다.

좋은 소식은 몇 개월 (그리고 몇 년)이지나면서 코드가 점차 "적절하게"잘 인수되고 테스트 된 코드가되기 시작한다는 것입니다.

부수적으로. 오래된 코드 기반에서 단위 테스트를 도입하는 데있어 주요 장애물은 응집력과 과도한 종속성이 없다는 것입니다. 따라서 가장 중요한 기술은 실제 단위 테스트 자체를 작성하지 않고 기존 종속성을 분리하고 코드를 분리하는 방법이 될 것입니다.

기존 솔루션이 제대로 단위 테스트를 거치지 않고 제대로 테스트되도록하기 위해 준수해야하는 프로세스 / 단계가 있습니까?

아직 설치하지 않은 경우 빌드 서버를 설정하고 코드 적용 범위가있는 모든 단위 테스트를 포함하여 모든 체크인에서 실행되는 연속 통합 빌드를 설정하십시오.

사람들을 훈련 시키십시오.

고객의 관점에서 진행하면서 어딘가에서 테스트를 시작하십시오 (아래 참조).

테스트중인 프로덕션 코드베이스의 양에 대한 지침으로 코드 적용 범위를 사용하십시오.

빌드 시간은 항상 빠릅니다. 빌드 시간이 느리면 단위 테스트 기술이 지연됩니다. 느린 테스트를 찾아서 개선하십시오 (제작 코드 분리 및 격리 테스트). 잘 작성하면 쉽게 수천 단위의 단위 테스트를 수행하고 10 분 이내에 빌드를 완료 할 수 있어야합니다 (~ 1 ms / 테스트는 좋지만 매우 거친 지침입니다. 반복을 사용하는 코드와 같은 예외는 거의 없습니다. ).

검사하고 적응하십시오.

테스트 품질이 좋고 테스트가 아닌 테스트가 테스트가 아닌 것보다 낫다는 것을 어떻게 확인할 수 있습니까?

당신 자신의 판단은 당신의 주요 현실의 근원이어야합니다. 스킬을 대체 할 수있는 메트릭이 없습니다.

그 경험이나 판단력이 없다면, 계약을 맺은 사람과 계약을 고려하십시오.

2 개의 대략적인 2 차 지표는 총 코드 적용 범위와 빌드 속도입니다.

프로덕션 환경에있는 기존 솔루션에 대한 노력의 가치가 있습니까?

예. 맞춤형 시스템 또는 솔루션에 소비되는 대부분의 돈은 생산 후 투입됩니다. 그리고 품질, 사람 및 기술에 대한 투자는 스타일을 벗어나서는 안됩니다.

이 프로젝트의 테스트를 무시하고 나중에 다시 작성할 수 있도록 추가하는 것이 더 좋습니까?

사람과 기술에 대한 투자뿐만 아니라 총 소유 비용과 시스템의 예상 수명 시간을 고려해야합니다.

제 개인의 대답은 대부분의 경우 "물론 예"가 될 것입니다. 왜냐하면 나는 그 점을 훨씬 더 잘 알고 있기 때문에 예외가 있다는 것을 알고 있습니다.

더 유익한 것은 무엇입니까? 몇 주 동안 테스트를 추가하거나 몇 주 동안 기능을 추가합니까?

둘 다. 기능 측면에서 발전하고있는 동안 코드베이스에 테스트를 추가해야합니다.

다시 말하지만 사람, 기술 및 코드 기반의 품질에 대한 투자이므로 시간이 필요합니다. 팀 구성원은 종속성을 깨고, 단위 테스트를 작성하고, 새로운 습관을 배우고, 훈련 및 품질 인식을 개선하고, 소프트웨어를 더 잘 디자인하는 방법 등을 배워야합니다. 테스트를 추가 할 때 팀원이 이러한 접근 방식이 성공하기 위해서는 이러한 수준의 기술을 갖추어야하므로 많은 테스트를 추가하기 위해 모든 시간을 소비하기 위해 진행을 중단하는 것만으로는 효과가 없습니다.

또한 모든 규모의 프로젝트 크기의 기존 코드베이스에 단위 테스트를 추가하는 것은 약속과 지속성이 필요한 대규모 사업입니다. 근본적인 것을 바꿀 수 없으며, 많은 학습을 기대하며 스폰서에게 비즈니스 가치 흐름을 중단하여 ROI를 기대하지 않도록 요청할 수 없습니다. 그것은 날지 않을 것이고, 솔직히 말하면 안됩니다.

셋째, 팀에 건전한 비즈니스 중심 가치를 심어 주려고합니다. 품질은 고객을 희생시키지 않으며 품질 없이는 빨리 갈 수 없습니다. 또한 고객은 변화하는 세상에 살고 있으며, 귀하의 업무는 고객이보다 쉽게 ​​적응할 수 있도록하는 것입니다. 고객 맞춤에는 품질과 비즈니스 가치 흐름이 모두 필요합니다.

당신이하고있는 일은 기술 부채를 지불하는 것입니다. 그리고 계속해서 변화하는 요구에 고객에게 서비스를 제공하면서 그렇게하고 있습니다. 점차 부채가 상환되면서 상황이 개선되며 고객에게 더 나은 서비스를 제공하고 더 많은 가치를 제공하는 것이 더 쉽습니다. 기타이 긍정적 인 추진력은 지속 가능한 페이스의 원칙에 밑줄을 긋고 개발팀, 고객 및 이해 관계자 모두에게 도덕을 유지하고 향상시킬 것이기 때문에 목표로 삼아야합니다.

희망이 도움이


내가 가진 것과 같은 사고 방식을 반영합니다. 현재이 정확한 프로세스 / 방법을 보여주고 큰 JAVA 응용 프로그램에서 테스트 사례를 소개하는 중입니다. :)
Darshan Joshi

3
이것은 내가 Stackoverflow에서 읽은 주제에 대해 가장 잘 표현 된 답변입니다. 잘 했어! 아직 그렇게하지 않았다면 마지막 질문에 대한 답변을 담은 책을 쓰는 것이 좋습니다.
Yermo Lamers

Yermo 감사합니다. 책을 쓸 시간이 있는지 잘 모르겠습니다. 그러나 아마도 블로그 기사를 작성할 수있을 것입니다. 새 블로그를 방금 시작 했으므로 시간이 다소 걸릴 수 있습니다.
Mahol25

2
이 친구 단위 테스트 조언은 일반적인 생활 조언입니다. 진심으로.
Wjdavis5

24
  • 프로덕션 환경에있는 기존 솔루션에 대한 노력의 가치가 있습니까?

예!

  • 이 프로젝트의 테스트를 무시하고 나중에 다시 작성할 수 있도록 추가하는 것이 더 좋습니까?

아니!

  • 더 유익한 것은 무엇입니까? 몇 주 동안 테스트를 추가하거나 몇 주 동안 기능을 추가합니까?

테스트 (특히 자동 테스트)를 추가 하면 향후 프로젝트를 훨씬 쉽게 유지할 수 있으며 사용자에게 어리석은 문제가 발생할 가능성이 크게 줄어 듭니다.

우선 순위 에 넣는 테스트 는 코드에 대한 공용 인터페이스 (및 각 모듈)가 생각하는 방식으로 작동하는지 여부를 확인 하는 테스트 입니다. 가능하면 코드 모듈에 포함 된 각각의 분리 된 실패 모드를 유도하십시오 (이것은 사소하지 않을 수 있으므로 실제로 실패하지 않는 방식을주의 깊게 확인하지 않도록주의해야합니다) 로그 기록이 충분한 지 확인하기 때문에 실패시 생성되는 로그 메시지 수 계산과 같은 작업을 수행합니다.

그런 다음 버그 데이터베이스에있는 현재 버그 각각을 테스트하여 정확하게 버그를 유발하고 버그가 수정되면 통과합니다. 그런 다음 그 버그를 수정하십시오! :-)

테스트를 추가하는 데 시간이 오래 걸리지 만 코드 품질이 훨씬 높아짐에 따라 백엔드에서 여러 번 상환됩니다. 새 버전을 배송하거나 유지 보수를 수행 할 때 매우 중요합니다.


정교한 응답에 감사드립니다. 내가 느끼는 것을 확인했다. 투표를하기 전에 다른 답변이 게시 된 내용을 확인하고 수락합니다.
djdd87

15

개량 단위 테스트의 문제점은 여기서 의존성을 주입하거나 인터페이스를 사용하지 않았다는 사실을 깨닫게되며 얼마 지나지 않아 전체 구성 요소를 다시 작성하게됩니다. 이 작업을 수행 할 시간이 있다면 멋진 안전망을 구축 할 수 있지만 그 과정에서 미묘한 버그가 발생할 수 있습니다.

나는 처음부터 단위 테스트가 실제로 필요한 많은 프로젝트에 참여했으며, 코드가 작동하고 이미 돈을 벌고있을 때 일반적으로 정당화 할 수없는 완전한 재 작성이 부족한 쉬운 방법이 없습니다. 최근에는 결함이 발생하자마자 재생산하는 방식으로 코드를 실행하는 powershell 스크립트를 작성하고 이러한 스크립트를 추가 변경을위한 회귀 테스트 모음으로 유지했습니다. 이렇게하면 응용 프로그램에 대한 테스트를 너무 많이 변경하지 않고도 최소한 일부 테스트를 작성할 수 있지만 적절한 단위 테스트보다 종단 간 회귀 테스트와 비슷합니다.


코드가 처음부터 합리적으로 잘 분리되어 있으면 테스트하기가 매우 쉽습니다. 문제는 모든 코드가 엉성하게 묶여 있고 노출 된 유일한 테스트 포인트가 완전한 통합 테스트를위한 코드 인 경우에 발생합니다. (테스트 용이성이 모의에 쉽지 않은 다른 구성 요소에 의존 거의 0 때문에 양이며, 배포 서버를 재부팅해야 어디 어디서 그런 코드를 시험 가능한이 ...하지만 열심히 잘 할 수 있습니다..)
DONAL 휄로우

13

나는 대부분의 다른 사람들이 말한 것에 동의합니다. 기존 코드에 테스트를 추가하는 것이 중요합니다. 나는 그 점에 동의하지 않을 것이지만 하나의 경고를 추가하고 싶습니다.

기존 코드에 테스트를 추가하는 것은 가치가 있지만 비용이 많이 듭니다. 새로운 기능을 구축 하지 않으면 비용이 발생 합니다. 이 두 가지의 균형을 맞추는 방법은 전적으로 프로젝트에 달려 있으며 여러 변수가 있습니다.

  • 모든 코드를 테스트하는 데 얼마나 걸립니까? 일? 몇 주? 몇 달? 연령?
  • 이 코드를 누가 작성하고 있습니까? 고객 지불? 교수? 오픈 소스 프로젝트?
  • 일정은 어떻습니까? 충족해야 할 마감일이 있습니까? 마감일이 있습니까?

다시 강조하겠습니다. 테스트는 가치가 있으며 이전 코드를 테스트하기 위해 노력해야합니다. 이것은 실제로 어떻게 접근하는지에 대한 문제입니다. 모든 것을 버리고 이전 코드를 모두 테스트 할 여유가 있다면 그렇게하십시오. 그것이 현실적이지 않다면, 최소한 여기에해야 할 일이 있습니다.

  • 작성하는 모든 새 코드는 완전히 단위 테스트를 받아야합니다
  • 만지는 오래된 코드 (버그 수정, 확장 등)는 단위 테스트를 받아야합니다.

또한 이것은 전부가 아닌 제안이 아닙니다. 예를 들어 4 명으로 구성된 팀이 있고 1 ~ 2 명을 레거시 테스트 의무에 맡겨 마감일을 맞출 수 있다면 반드시 그렇게하십시오.

편집하다:

이 장을 나중에 장단점으로 작성하여 경영진에게 제품의 미래 개발을 TDD로 옮기는 데 시간을 투자 할 가치가 있음을 보여 주려고 노력하고 있습니다.

"소스 제어 사용의 장단점은 무엇입니까?" 또는 "채용하기 전에 사람들을 인터뷰 할 때의 장단점은 무엇입니까?" 또는 "호흡의 장단점은 무엇입니까?"

때로는 논쟁의 한 면만 있습니다. 복잡한 프로젝트에 대해 어떤 형태의 자동화 된 테스트가 필요합니다. 아니요, 테스트는 스스로 작성하지 않으며, 문제를 해결하는 데 약간의 시간이 더 걸립니다. 그러나 장기적으로는 테스트를 미리 작성하는 것보다 버그를 수정하는 데 더 많은 시간과 비용이 소요됩니다. 기간. 그것이 전부입니다.


9

테스트를 추가하기 시작했을 때, UI와보고 코드에 너무 많은 로직을 가진 10 년 된 약 백만 라인 코드베이스였습니다.

우리가 한 첫 번째 작업 (연속 빌드 서버를 설정 한 후) 중 하나는 회귀 테스트를 추가하는 것이 었습니다. 이것들은 엔드-투-엔드 테스트였습니다.

  • 각 테스트 스위트는 데이터베이스를 알려진 상태로 초기화하여 시작합니다. 실제로 Subversion에 보관하는 수십 개의 회귀 데이터 세트가 있습니다 (순서 크기 때문에 코드와 별도의 저장소에 있음). 각 테스트의 FixtureSetUp은 이러한 회귀 데이터 세트 중 하나를 임시 데이터베이스에 복사 한 다음 거기에서 실행됩니다.
  • 그런 다음 테스트 픽스처 설정은 결과에 관심이있는 일부 프로세스를 실행합니다.이 단계는 선택 사항입니다. 일부 회귀 테스트는 보고서를 테스트하기 위해서만 존재합니다.
  • 그런 다음 각 테스트는 보고서를 실행하고 보고서를 .csv 파일로 출력 한 다음 해당 .csv의 내용을 저장된 스냅 샷과 비교합니다. 이 스냅 샷 .csvs는 각 회귀 데이터 세트 옆의 Subversion에 저장됩니다. 보고서 출력이 저장된 스냅 샷과 일치하지 않으면 테스트가 실패합니다.

회귀 테스트의 목적은 변경 사항이 있는지 알려주는 것입니다. 즉, 무언가를 파기하면 실패하지만 의도적으로 무언가를 변경하면 실패합니다 (이 경우 수정은 스냅 샷 파일을 업데이트하는 것임). 스냅 샷 파일이 올바른지조차 모릅니다. 시스템에 버그가있을 수 있습니다 (그런 다음 버그를 수정하면 회귀 테스트가 실패합니다).

그럼에도 불구하고 회귀 테스트는 우리에게 큰 승리였습니다. 우리 시스템의 거의 모든 것이 보고서를 가지고 있으므로 보고서 주위에 테스트 하네스를 얻는 데 몇 주를 소비함으로써 우리는 코드 기반의 상당 부분을 어느 정도 커버 할 수있었습니다. 동등한 단위 테스트를 작성하는 데 몇 개월 또는 몇 년이 걸렸습니다. (단위 테스트는 우리에게 훨씬 더 나은 적용 범위를 제공했을 것이고 훨씬 덜 취약했을 것입니다. 그러나 나는 완벽을 위해 몇 년을 기다리는 대신 지금 무언가를 갖고 싶습니다.)

그런 다음 버그를 수정하거나 개선 사항을 추가하거나 일부 코드를 이해해야 할 때 단위 테스트를 추가하기 시작했습니다. 회귀 테스트는 결코 단위 테스트의 필요성을 제거하지 않습니다. 그것들은 단지 첫 번째 수준의 안전망이므로 어느 정도의 테스트 범위를 빠르게 얻을 수 있습니다. 그런 다음 리팩토링을 시작하여 종속성을 깨뜨릴 수 있으므로 단위 테스트를 추가 할 수 있습니다. 회귀 테스트를 통해 리팩토링으로 인해 아무런 문제가 발생하지 않는다는 확신을 얻을 수 있습니다.

회귀 테스트에는 문제가 있습니다. 속도가 느리고 깨질 수있는 이유가 너무 많습니다. 그러나 우리를 위해 적어도 그들은했다 그래서 가치. 지난 5 년 동안 수많은 버그를 발견했으며 QA주기를 기다리는 대신 몇 시간 내에 버그를 발견했습니다. 우리는 여전히 원래 회귀 테스트를 가지고 있으며, 7 개의 서로 다른 연속 빌드 머신 (고속 유닛 테스트를 실행하는 머신과는 별개)에 퍼져 있으며, 우리는 여전히 6,000 개의 코드를 가지고 있기 때문에 때때로 그것들을 추가합니다. + 단위 테스트는 다루지 않습니다.


8

그만한 가치가 있습니다. 앱에 복잡한 교차 유효성 검사 규칙이 있으며 최근 비즈니스 규칙을 크게 변경해야했습니다. 결국 사용자가 저장하지 못하게하는 충돌이 발생했습니다. 나는 applcation에서 그것을 분류하는 데 영원히 걸릴 것이라고 깨달았습니다 (문제가 발생한 지점까지 도달하는 데 몇 분이 걸립니다). 자동화 된 단위 테스트를 도입하고 프레임 워크를 설치하고 싶었지만, 몇 가지 더미 테스트 외에는 아무런 작업도 수행하지 않았습니다. 새로운 비즈니스 규칙에 따라 테스트를 시작했습니다. 테스트를 통해 충돌을 일으킨 조건을 신속하게 파악하고 규칙을 명확하게 파악할 수있었습니다.

추가하거나 수정하는 기능을 다루는 테스트를 작성하면 즉각적인 이점이 있습니다. 다시 쓰기를 기다리는 경우 자동 테스트가 없을 수 있습니다.

이미 작동하는 기존 항목에 대한 테스트를 작성하는 데 많은 시간을 소비해서는 안됩니다. 대부분의 경우 기존 코드에 대한 사양이 없으므로 테스트하려는 주요 사항은 리버스 엔지니어링 기능입니다. 반면에 무언가를 수정하려는 경우 해당 기능을 테스트로 다루어야 변경 사항이 올바르게 적용되었음을 알 수 있습니다. 물론 새로운 기능의 경우 실패한 테스트를 작성한 다음 누락 된 기능을 구현하십시오.


6

음성을 추가하고 예라고 말하겠습니다. 항상 유용합니다!

그러나 블랙 박스와 화이트 박스, 그리고 유닛과 기능의 차이점을 명심해야합니다. 정의가 다양하기 때문에 다음과 같은 의미를 갖습니다.

  • 블랙 박스 = 구현에 대한 특별한 지식없이 작성된 테스트로, 일반적으로 순진한 사용자가 예상 한대로 일이 발생하는지 확인하기 위해 엣지 케이스를 탐색합니다.
  • 화이트 박스는 기록 된 테스트 = 종종 잘 알려진 장애 지점을 행사하려고 구현, 지식.
  • 단위 테스트 = 개별 단위 (기능, 분리 가능한 모듈 등)의 테스트. 예를 들어, 배열 클래스가 예상대로 작동하고 문자열 비교 함수가 광범위한 입력에 대해 예상 된 결과를 리턴하는지 확인하십시오.
  • 기능 테스트 = 한 번에 전체 시스템을 테스트합니다. 이 테스트는 한 번에 시스템의 큰 덩어리를 시험합니다. 예를 들어 : 초기화, 연결 열기, 실제 작업 수행, 종료, 종료. 나는 이것들과 단위 테스트가 다른 목적을 제공하기 때문에 구별하기를 원합니다.

게임 후반에 배송 제품에 테스트를 추가했을 때 화이트 박스기능 테스트 에서 가장 많은 비용을 지불했습니다 . 특히 취약한 코드 부분이 있으면 문제를 해결하기 위해 화이트 박스 테스트를 작성하여 같은 방식으로 두 번 깨지지 않도록하십시오. 마찬가지로 전체 시스템 기능 테스트는 가장 일반적인 10 가지 사용 사례를 위반하지 않도록하는 유용한 온 전성 검사입니다.

작은 단위의 블랙 박스 및 단위 테스트도 유용하지만 시간이 제한되어 있으면 조기에 추가하는 것이 좋습니다. 배송 할 때 일반적으로 이러한 테스트에서 발견 된 대부분의 엣지 사례와 문제를 발견했습니다.

다른 사람들과 마찬가지로 TDD에 대해 가장 중요한 두 가지 사항을 상기시켜 드리겠습니다.

  1. 테스트 작성은 지속적인 작업입니다. 절대 멈추지 않습니다. 새 코드를 작성하거나 기존 코드를 수정할 때마다 새 테스트를 추가해야합니다.
  2. 테스트 스위트는 절대 완벽하지 않습니다! 테스트를 받았다는 사실로 인해 잘못된 보안 감각이 생길 수 있습니다. 테스트 스위트를 통과했다고해서 그것이 올바르게 작동하거나 미묘한 성능 회귀 등을 도입하지 않았다는 의미는 아닙니다.

4

프로덕션 환경에있는 앱에 단위 테스트를 추가 할 가치가 있는지 여부는 앱 유지 관리 비용에 따라 다릅니다. 앱에 버그와 개선 요청이 거의 없다면 노력할 가치가 없을 것입니다. OTOH, 앱이 버그가 있거나 자주 수정되면 단위 테스트가 큰 도움이 될 것입니다.

이 시점에서 단위 테스트를 선택적으로 추가하는 것에 대해 이야기하고 있음을 기억하십시오. 처음부터 TDD를 연습했을 때 존재할 테스트와 유사한 테스트 세트를 생성하려고 시도하지 마십시오. 따라서 두 번째 질문의 후반부에 대한 응답으로 다음 프로젝트에서 새 프로젝트인지 다시 쓰기인지에 관계없이 TDD를 사용하십시오. (사죄이지만 실제로 읽어야 할 다른 책에 대한 링크 가 있습니다. : 테스트를 통해 성장하는 객체 지향 소프트웨어 )

세 번째 질문에 대한 나의 대답은 첫 번째 질문과 동일합니다. 프로젝트의 상황에 따라 다릅니다.

게시물에 포함 된 내용은 개조 된 테스트가 올바르게 수행 되는지에 대한 추가 질문 입니다. 확인해야 할 중요한 점은 단위 테스트가 실제로 단위 테스트라는 것입니다. 이는 개량 테스트를 수행하려면 기존 코드를 리팩터링하여 레이어 / 컴포넌트의 분리를 허용해야합니다 (종속성 주입, 제어 역전, 스터 빙, 참조). 조롱). 이를 시행하지 않으면 테스트가 통합 테스트가되어 실제 단위 테스트보다 유용하지만 덜 대상이되고 취성이 적습니다.


4

구현 언어에 대해서는 언급하지 않지만 Java 인 경우 다음 방법을 시도 할 수 있습니다.

  1. 별도의 소스 트리 빌드 회귀 또는 '연기'테스트에서이를 생성하는 도구를 사용하면 80 %에 가까운 범위에 도달 할 수 있습니다. 이 테스트는 모든 코드 논리 경로를 실행하고 그 시점부터 코드가 여전히 현재 수행중인 작업을 정확히 수행하는지 확인합니다 (버그가있는 경우에도). 이를 통해 필요한 리팩토링을 수행 할 때 실수로 변경되는 동작에 대한 안전망을 제공하여 손으로 코드를 쉽게 테스트 할 수 있습니다.

  2. 수정 한 버그 또는 지금부터 추가 한 기능에 대해 TDD 접근 방식을 사용하여 새 코드를 테스트 할 수 있도록 설계하고 이러한 테스트를 일반 테스트 소스 트리에 배치하십시오.

  3. 기존 코드도 새로운 기능을 추가하는 과정에서 테스트 할 수 있도록 변경하거나 리팩토링해야합니다. 연기 테스트는 회귀 또는 의도하지 않은 미묘한 행동 변화에 대한 안전망을 제공합니다.

  4. TDD를 통해 변경 (버그 수정 또는 기능)을 수행 할 때 완료되면 동반 연기 테스트가 실패했을 수 있습니다. 손으로 쓴 단위 테스트에서 개선 된 구성 요소를 완벽하게 다루기 때문에 변경 사항으로 인해 실패가 예상 된 것인지 확인하고 읽기 어려운 연기 테스트를 제거하십시오. 테스트 범위가 줄어들지 않아야합니다.

  5. 버그를 수정하는 경우 먼저 버그를 노출시키는 실패한 단위 테스트를 작성하십시오.


3

단위 테스트는 버그가 생산에 들어가기 전에 체포하는 데 도움이되므로 단위 테스트가 정말 중요하다고 말하면서이 답변을 시작하고 싶습니다.

버그가 재 도입 된 프로젝트 / 모듈 영역을 식별하십시오. 프로젝트를 시작하여 테스트를 작성하십시오. 새로운 기능과 버그 수정에 대한 테스트를 작성하는 것이 완벽합니다.

프로덕션 환경에있는 기존 솔루션에 대한 노력의 가치가 있습니까?

예. 버그가 줄어들고 유지 관리가 쉬워지는 효과를 볼 수 있습니다

이 프로젝트의 테스트를 무시하고 나중에 다시 작성할 수 있도록 추가하는 것이 더 좋습니까?

지금부터 시작하는 것이 좋습니다.

더 유익한 것은 무엇입니까? 몇 주 동안 테스트를 추가하거나 몇 주 동안 기능을 추가합니까?

당신은 잘못된 질문을하고 있습니다. 확실히, 기능은 다른 무엇보다 중요합니다. 그러나 테스트를 추가하는 데 몇 주가 걸리면 내 시스템이 더 안정적 일지 묻습니다. 이것이 최종 사용자에게 도움이됩니까? 팀의 새로운 개발자가 프로젝트를 이해하고 변경의 전반적인 영향에 대한 이해 부족으로 인해 버그가 발생하지 않도록하는 데 도움이됩니까?


3

리팩토링을 시작할 위치에 대한 질문에 대한 응답으로 로우 행잉 과일 리팩터링을 매우 좋아 합니다. 씹을 수있는 것 이상으로 물지 않고 더 나은 디자인으로 편하게 할 수있는 방법입니다.

동일한 논리가 TDD 또는 단위 테스트에만 적용된다고 생각합니다. 필요한 테스트를 필요한대로 작성하십시오. 새로운 코드에 대한 테스트 작성; 버그가 나타날 때 테스트를 작성하십시오. 코드베이스의 접근하기 어려운 영역을 무시하는 것에 대해 걱정하고 있으며 위험이 있지만 시작하는 방법으로 시작하십시오! 코드 커버리지 도구를 사용하여 위험을 완화시킬 수 있으며, 어쨌든 그 위험은 크지 않습니다. 버그를 다루고 있다면 새 코드를 다루고 있으며 찾고있는 코드를 덮고 있습니다 테스트가 가장 필요한 코드를 다루고 있습니다.


2
  • 그렇습니다. 새로운 기능 추가를 시작하면 오래된 코드가 수정 될 수 있으며 결과적으로 잠재적 인 버그의 원인이됩니다.
  • 새로운 기능을 추가하기 전에 (첫 번째 코드 참조) 모든 (또는 거의) 코드를 (이상적으로는) 단위 테스트로 다루어야합니다.
  • (첫 번째와 두 번째 참조) :). 새로운 장대 한 기능은 이전에 작동했던 코드를 "파기"할 수 있습니다.

2

예, 가능합니다. 이제 작성한 모든 코드에 테스트가 있는지 확인하십시오.

이미 존재하는 코드를 수정해야하고 테스트 할 수 있다면 그렇게해야하지만, 안정적인 코드를 위해 테스트를 시도하는 데 너무 힘이없는 것이 좋습니다. 그런 종류의 물건은 노크 효과가 있고 통제 불능 상태가 될 수 있습니다.


2

프로덕션 환경에있는 기존 솔루션에 대한 노력의 가치가 있습니까?
예. 그러나 시작하기 위해 모든 단위 테스트를 작성할 필요는 없습니다. 하나씩 추가하십시오.

이 프로젝트의 테스트를 무시하고 나중에 다시 작성할 수 있도록 추가하는 것이 더 좋습니까?
아니요. 기능을 손상시키는 코드를 처음 추가하면 후회하게됩니다.

더 유익한 것은 무엇입니까? 몇 주 동안 테스트를 추가하거나 몇 주 동안 기능을 추가합니까?
새로운 기능 (코드)의 경우 간단합니다. 먼저 단위 테스트를 작성한 다음 기능을 작성하십시오. 오래된 코드의 경우 길을 결정합니다. 모든 단위 테스트를 시행 할 필요는 없습니다 ... 가장 많이 해치지 않은 테스트를 추가하십시오.


2

최신 정보

원래 답변 6 년 후, 나는 조금 다른 테이크를 가지고있다.

여러분이 작성한 모든 새로운 코드에 단위 테스트를 추가 한 다음 테스트 할 수 있도록 변경 한 부분을 리팩터링하는 것이 합리적이라고 생각합니다.

기존의 모든 코드에 대해 테스트를 한 번에 작성해도 도움이되지는 않지만 작성하는 새 코드 (또는 수정 한 영역)에 대한 테스트를 작성하지 않는 것도 의미가 없습니다. 사물을 리팩터링 / 추가 할 때 테스트를 추가하는 것이 테스트를 추가하고 테스트없이 기존 프로젝트에서 코드를 유지 관리하기에 가장 좋은 방법 일 것입니다.

이전 답변

나는 여기에 약간의 눈썹을 올릴거야 :)

우선 프로젝트가 무엇입니까? 컴파일러, 언어 또는 프레임 워크 또는 오랫동안 기능적으로 변경되지 않는 다른 것이라면 단위 테스트를 추가하는 것이 절대적으로 환상적이라고 생각합니다.

그러나 요구 사항 변경으로 인해 기능 변경이 필요할 수있는 응용 프로그램에서 작업하는 경우 추가 노력을 기울일 필요가 없습니다.

왜?

  1. 단위 테스트는 코드 테스트에만 적용됩니다 (코드가 의도 한 기능을 수행하는지 여부). 기능 버그, 유용성 문제 및 기타 모든 종류의 문제를 발견하기 위해 수행해야하는 수동 테스트를 대체하는 것은 아닙니다.

  2. 단위 테스트는 시간이 걸립니다! 이제 내가 어디에서 왔는지, 그것은 귀중한 상품입니다. 비즈니스는 일반적으로 완전한 테스트 스위트보다 더 나은 기능을 선택합니다.

  3. 응용 프로그램이 사용자에게 원격으로 유용 할 경우 변경을 요청하게되므로 더 나은 작업, 더 빠른 작업 및 새로운 작업을 수행 할 수있는 버전이 제공됩니다. 코드가 커짐에 따라 리팩토링도 많이 발생할 수 있습니다. 역동적 인 환경에서 완전히 성장한 단위 테스트 스위트를 유지 관리하는 것은 골치 아픈 일입니다.

  4. 단위 테스트는 제품의인지 품질, 즉 사용자가 보는 품질에 영향을 미치지 않습니다. 물론, 방법은 1 일과 똑같이 작동 할 수 있습니다. 프리젠 테이션 레이어와 비즈니스 레이어 간의 인터페이스는 깨끗할 수 있습니다. 사용자는 신경 쓰지 않습니다! 실제 테스터에게 응용 프로그램을 테스트하십시오. 그리고 그 방법과 인터페이스는 어쨌든 조만간 변경되어야합니다.

더 유익한 것은 무엇입니까? 몇 주 동안 테스트를 추가하거나 몇 주 동안 기능을 추가합니까? -테스트를 ​​작성하는 것보다 더 좋은 일이 많이 있습니다.-새로운 기능 작성, 성능 개선, 유용성 개선, 더 나은 도움말 매뉴얼 작성, 보류중인 버그 해결 등

이제 내가 틀리지 마라-만약 당신이 앞으로 100 년 동안 변화가 없을 것이라고 긍정적으로 생각한다면, 계속 넘어 가서 테스트를 작성하십시오. 자동 테스트는 타사 코드를 절대로 중단하지 않으려는 API에도 좋습니다. 다른 곳에서는 나중에 배송 할 수있는 것입니다!


이 글을 읽어 보시기 바랍니다 -joelonsoftware.com/items/2009/01/31.html
Roopesh Shenoy

'대기중인 버그 수정'을 원하십니까? 아니면 버그가 발생하지 않도록 하시겠습니까? 적절한 단위 테스트는 버그 수정에 소요되는 시간을 최소화하여 시간을 절약합니다.
Ihor Kaharlichenko

신화입니다. 자동화 된 단위 테스트가 수동 테스트의 대체품이라고 말하면 심각하고 심각하게 실수 한 것입니다. 그리고 버그가 아닌 경우 수동 테스터는 무엇을 기록합니까?
Roopesh Shenoy

그리고 그래, 나도 틀리지 마-단위 테스트는 절대 낭비라고 말하지-요점은 작성하는 데 걸리는 시간과 제품을 변경할 때 변경 해야하는 이유를 고려하고 있습니다. 실제로 돈을 지불합니까? 나를 위해 나는 양쪽을 시도했지만 대답은 아니오, 그들은 충분히 빨리 갚지 않습니다.
Roopesh Shenoy

1

테스트 범위가 크지 않을 가능성이 높으므로 테스트를 추가 할 위치에 대해 전술적이어야합니다.

  • 앞에서 언급했듯이 버그를 발견하면 테스트를 작성하여 재현 한 다음 버그를 수정해야합니다. 테스트에서 버그가 재생되는 것을 확인하면 버그가 훌륭하고 확실하게 테스트되는지 확인할 수 있습니다. 버그의 상당 부분이 회귀 (50 %)라는 점을 감안할 때 거의 항상 회귀 테스트를 작성하는 것이 좋습니다.
  • 코드 영역으로 들어가서 코드를 수정 한 후에는 테스트를 작성하는 것이 좋습니다. 코드의 특성에 따라 다른 테스트가 적합합니다. 좋은 조언 이 여기에 있습니다 .

OTOH, 사람들이 만족하는 코드 주위에 테스트를 작성하는 것만으로는 가치가 없습니다. 특히 아무도 그것을 수정하지 않을 경우. 그것은 단지 가치를 추가하지 않습니다 (시스템의 행동을 이해하는 것을 제외하고).

행운을 빕니다!



1

내가 당신의 자리에 있다면 아마도 전체 시스템을 시험하는 기능 테스트로 시작하여 아마도 외부 접근 방식을 취할 것입니다. RSpec과 같은 BDD 사양 언어를 사용하여 시스템 요구 사항을 다시 문서화 한 다음 사용자 인터페이스를 자동화하여 해당 요구 사항을 확인하는 테스트를 작성하려고합니다.

그런 다음 새로 발견 된 버그에 대한 결함 중심 개발을 수행하고, 문제를 재현하기 위해 단위 테스트를 작성하고 테스트가 통과 할 때까지 버그에 대해 작업합니다.

새로운 기능의 경우, 외부 접근 방식을 고수 할 것입니다. RSpec에 문서화되고 사용자 인터페이스를 자동화하여 검증 된 기능으로 시작한 다음 (물론 초기에는 실패 할 것임) 구현이 진행됨에 따라 더 세밀한 단위 테스트를 추가하십시오.

나는 프로세스에 대한 전문가는 아니지만 자동화 된 UI 테스트를 통한 BDD는 쉽지 않다는 것을 알 수 있지만 노력의 가치가 있다고 생각하며 아마도 귀하의 경우에 가장 큰 이익을 얻을 것이라고 생각합니다.


1

나는 노련한 TDD 전문가는 아니지만, 물론 단위 테스트를 할 수있는 한 엄청나게 중요하다고 말할 것입니다. 코드가 이미 준비되어 있으므로 우선 일종의 단위 테스트 자동화를 시작합니다. TeamCity를 사용하여 프로젝트의 모든 테스트를 수행하고 구성 요소의 수행 방식에 대한 요약을 제공합니다.

그 자리에서 필자는 실패 할 수없는 정말 중요한 비즈니스 로직과 같은 구성 요소로 넘어갑니다. 필자의 경우 다양한 입력에 대해 해결해야 할 몇 가지 기본 삼각법 문제가 있으므로 그 중 하나를 테스트합니다. 내가하는 이유는 자정 기름을 태울 때 실제로 입력 할 필요가없는 코드 깊이까지 파고 드는 시간을 매우 쉽게 낭비하기 때문 입니다. 가능한 모든 입력에 대해 테스트마쳤 기 때문에 (제 경우에는 유한 한 수의 입력이 있습니다).

이제 중요한 부분에 대해 더 나은 느낌을 가지십시오. 앉아서 모든 테스트를 수행하는 대신, 테스트가 시작될 때 공격합니다. 실제 PITA 인 버그를 발견하면 단위 테스트를 작성하여 방해하지 마십시오.

테스트에서 특정 클래스를 인스턴스화 할 수 없기 때문에 테스트가 어려운 경우가 있으므로이를 조롱해야합니다. 그러나 인터페이스에 쓰지 않았기 때문에 쉽게 조롱 할 수는 없습니다. 이러한 인터페이스를 구현할 수있는 기회로 이러한 "후드"시나리오를 사용합니다. 왜냐하면 좋은 일이기 때문입니다.

거기에서 코드 커버리지 도구로 구성된 빌드 서버 또는 자동화를 얻을 수 있습니다. 적용 범위가 열악한 빨간색 영역이 큰 불쾌한 막대 그래프를 만듭니다. 이제 100 % 적용 범위가 목표가 아니며 100 % 적용 범위가 코드가 방탄임을 의미하지는 않지만 자유 시간이있을 때 빨간색 막대가 확실히 동기를 부여합니다. :)


1

좋은 답변이 너무 많아서 내용을 반복하지 않겠습니다. 프로필을 확인한 결과 C # .NET 개발자 인 것 같습니다. 이 때문에 레거시 코드에 대한 단위 테스트를 자동 생성하는 데 도움이되는 Microsoft PEX 및 Moles 프로젝트에 대한 참조를 추가 하고 있습니다. 나는 자동 생성이 최선의 방법은 아니지만 최소한 시작하는 방법이라는 것을 알고 있습니다. 레거시 코드에 PEX를 사용하는 방법에 대한 MSDN Magazine의이 흥미로운 기사를 확인하십시오 .


1

TopTal Engineer 의 훌륭한 기사 를 읽고 테스트 추가를 시작할 위치 를 설명하는 것이 좋습니다 . 많은 수학이 포함되어 있지만 기본 아이디어는 다음과 같습니다.

1) 코드의 Afferent Coupling (CA )을 측정하십시오 ( 다른 클래스가 사용하는 클래스의 양,이를 위반하면 광범위한 손상을 초래할 수 있음)

2) 코드의 Cyclomatic Complexity (CC ) 측정 (더 높은 복잡성 = 더 높은 파괴 변화)

CA 및 CC가 높은 클래스를 식별해야합니다. 즉, 함수 f (CA, CC) 가 있어야하며 두 메트릭간에 가장 작은 차이 가있는 클래스 는 테스트 적용 범위에 가장 높은 우선 순위를 부여해야합니다.

왜? 높은 CA이지만 매우 낮은 CC 클래스는 매우 중요하지만 깨지지 않을 것입니다. 반면, 낮은 CA이지만 높은 CC는 깨질 가능성이 있지만 피해는 적습니다. 균형을 잡기를 원합니다.


0

그것은 다릅니다 ...
단위 테스트를하는 것이 좋지만 더 버그가없는 제품을 얻기 위해서는 사용자가 누구인지, 무엇을 허용 할 것인지 고려해야합니다. 필연적으로 현재 단위 테스트가없는 코드를 리팩토링하면 버그가 발생하고 많은 사용자가 장기적으로 결함을 줄이기 위해 제품을 일시적으로 더 결함이있는 것으로 이해하기 어렵습니다. 최종적으로 최종 사용자는 ...


-2

예. 아니오. 테스트 추가.

더 많은 TDD 접근 방식을 사용하면 실제로 새로운 기능을 추가하고 회귀 테스트를 훨씬 쉽게하려는 노력에 더 효과적으로 알릴 수 있습니다. 확인 해봐!

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