sliver__

[Mastering C++ Programming] - TDD (Test-driven development) 본문

CS/C++

[Mastering C++ Programming] - TDD (Test-driven development)

sliver__ 2022. 12. 11. 11:08
728x90
  • 테스트 주도 개발(TDD)은 extreme 프로그래밍 방식입니다.
  • TDD에서는 테스트 사례로 시작하여 테스트 사례를 성공시키는 데 필요한 프로덕션 코드를 작성합니다.
  • 아이디어는 한 번에 하나의 테스트 케이스 또는 시나리오에 집중하고 테스트 케이스가 통과하면 다음 시나리오로 넘어갈 수 있다는 것입니다.
  • 이 과정에서 새로운 테스트 케이스가 통과되면 프로덕션 코드를 수정해서는 안됩니다.
  • 즉, 새로운 기능을 개발하거나 버그를 수정하는 과정에서 우리는 두 가지 이유로만 프로덕션 코드를 수정할 수 있습니다.
  • 테스트 케이스가 통과하는지 확인하거나 코드를 리팩터링하기 위해서입니다.
  • TDD의 주요 초점은 단위 테스트입니다.
  • 그러나 어느 정도 통합 및 상호 작용 테스트로 확장될 수 있습니다.

  • TDD를 따를 때 코드의 기능적 및 구조적 품질을 모두 달성할 수 있습니다. 
  • 개발 단계가 끝날 때 테스트 케이스를 작성하는 것과 달리 프로덕션 코드를 작성하기 전에 먼저 테스트 케이스를 작성하는 것이 매우 중요합니다. 
  • 이것은 꽤 많은 차이를 만듭니다. 
  • 예를 들어, 개발자가 개발 종료 시 단위 테스트 사례를 작성할 때 테스트 사례에서 코드의 결함을 발견할 가능성은 거의 없습니다. 
  • 그 이유는 개발이 끝날 때 테스트 사례가 작성될 때 개발자가 무의식적으로 코드가 올바른 일을 하고 있음을 증명하려는 경향이 있기 때문입니다. 
  • 반면에 개발자가 테스트 사례를 미리 작성하는 경우 아직 코드가 작성되지 않았기 때문에 최종 사용자의 관점에서 생각하기 시작하여 요구 사항 사양 관점에서 수많은 시나리오를 생각해 내도록 권장합니다.

  • 즉, 이미 작성된 코드에 대해 작성된 테스트 사례는 요구 사항에 대해 테스트하는 대신 작성된 코드가 정확함을 증명하는 경향이 있으므로 일반적으로 버그를 찾기 쉽지 않습니다.
  • 개발자가 코드를 작성하기 전에 다양한 시나리오를 생각하면 점진적으로 더 나은 코드를 작성하여 코드가 이러한 시나리오를 처리하도록 합니다.
  • 그러나 코드에 허점이 있는 경우 요구 사항을 충족하지 않으면 테스트 사례가 실패하므로 문제를 찾는 데 도움이 되는 것은 테스트 사례입니다.

  • TDD는 일부 단위 테스트 프레임워크를 사용하는 것이 아닙니다. 
  • 코드의 결함을 개발하거나 수정하는 동안 문화 및 사고 방식의 변화가 필요합니다. 
  • 개발자의 초점은 코드를 기능적으로 올바르게 만드는 것입니다
  • 이러한 방식으로 코드가 개발되면 개발자는 코드를 리팩토링하여 코드 smell을 제거하는 데에도 집중해야 합니다.
  • 이렇게 하면 코드의 구조적 품질도 양호해질 것입니다.
  • 장기적으로 팀이 기능을 더 빠르게 제공하게 만드는 것은 코드의 구조적 품질입니다.

 

 

 

[개발자가 단위 테스트를 작성하려면 더 많은 노력이 할까?]

  • 대부분의 개발자들이 생각하는 일반적인 의문 중 하나는 "TDD에 적응할 때 내 노력을 어떻게 추정해야 합니까?"입니다.
  • 개발자는 TDD의 일부로 단위 및 통합 테스트 사례를 작성해야 하므로 코드 작성 외에 테스트 사례를 작성하는 데 필요한 추가 노력에 대해 고객 또는 경영진과 협상하는 방법에 대해 걱정하는 것은 놀라운 일이 아닙니다.

  • 개발자는 코드를 수동으로 테스트합니다. 
  • 대신 지금 자동화된 테스트 사례를 작성하십시오. 
  • 좋은 소식은 장기적으로 도움이 되는 일회성 노력이라는 것입니다. 
  • 개발자는 코드를 테스트하기 위해 반복적인 수작업이 필요하지만, 코드를 변경할 때마다 기존의 자동화된 테스트 사례는 개발자가 새로운 코드를 통합할 때 즉각적인 피드백을 제공하여 개발자에게 도움이 됩니다.

  • 결론은 약간의 추가 노력이 필요하지만 장기적으로는 필요한 노력을 줄이는 데 도움이 된다는 것입니다.

 

 

 

[코드 커버리지 메트릭이 좋은가요 나쁜가요?]

  • Code coverage tool은 개발자가 자동화된 테스트 사례의 차이를 식별하는 데 도움이 됩니다.
  • 의심할 여지없이 여러 번 누락된 테스트 시나리오에 대한 단서를 제공하여 결국 자동화된 테스트 사례를 더욱 강화할 것입니다.
  • 그러나 조직이 테스트 커버리지의 효과를 확인하기 위한 수단으로 코드 커버리지를 적용하기 시작하면 때때로 개발자를 잘못된 방향으로 인도합니다.
  • 실제 컨설팅 경험을 통해 배운 것은 많은 개발자가 더 높은 코드 커버리지를 보여주기 위해 construtor 및 private, protected에 대한 테스트 사례를 작성하기 시작한다는 것입니다.
  • 이 과정에서 개발자는 숫자를 쫓기 시작하고 TDD의 궁극적인 목표를 잃습니다.

  • 20개의 메서드가 있는 클래스가 있는 특정 소스에서 10개의 메서드만 단위 테스트에 적합하고 다른 메서드는 복잡한 기능일 수 있습니다. 
  • 이 경우 code coverage 는 50%의 코드 적용 범위만 표시하며 이는 TDD 철학에 따라 절대적으로 좋습니다.
  • 그러나 조직 정책이 최소 75%의 코드 적용 범위를 적용하는 경우 개발자는 우수한 코드 적용 범위를 표시하기 위해 생성자, 소멸자, 개인, 보호 및 복합 함수를 테스트하는 것 외에 다른 선택의 여지가 없습니다.

  • 비공개 및 보호된 메서드를 테스트할 때의 문제는 구현 세부 정보로 표시될 때 더 자주 변경되는 경향이 있다는 것입니다. 
  • 비공개 및 보호된 메서드가 잘못 변경되면 테스트 사례를 수정해야 하므로 테스트 사례를 유지 관리하는 측면에서 개발자의 삶이 더 어려워집니다.

  • 따라서 코드 커버리지 도구는 테스트 시나리오 갭을 찾는 데 매우 좋은 개발자 도구이지만, 테스트 케이스를 작성할지 또는 특정 메소드에 대한 테스트 케이스 작성을 무시할지에 대한 현명한 선택은 개발자에게 맡겨야 합니다. 
  • 그러나 코드 커버리지가 프로젝트 메트릭으로 사용되는 경우 개발자가 더 나은 커버리지를 표시하는 잘못된 방법을 찾는 경향이 있어 잘못된 테스트 케이스 관행으로 이어집니다.

 

 

 

[TDD가 복잡한 레거시 프로젝트에서 작동합니까?]

  • 틀림없이 TDD는 모든 유형의 소프트웨어 프로젝트 또는 제품에서 작동합니다.
  • TDD는 새 제품이나 프로젝트만을 위한 것이 아닙니다.
  • 또한 복잡한 레거시 프로젝트 또는 제품에서 더 효과적인 것으로 입증되었습니다.
  • 유지 관리 프로젝트에서 대부분의 시간은 결함을 수정해야 하며 새 기능을 지원해야 하는 경우는 거의 없습니다.
  • 이러한 레거시 코드에서도 결함을 수정하면서 TDD를 따를 수 있습니다.

  • 개발자로서 문제를 재현할 수 있게 되면 개발자의 관점에서 문제의 거의 절반이 해결된 것으로 간주될 수 있다는 데 기꺼이 동의할 것입니다. 
  • 따라서 문제를 재현하는 테스트 사례로 시작한 다음 문제를 디버그하고 수정할 수 있습니다. 
  • 문제를 해결하면 테스트 케이스가 통과하기 시작합니다. 
  • 이제 동일한 결함을 재현하고 프로세스를 반복할 수 있는 다른 가능한 테스트 사례를 생각할 때입니다.

 

 

[임베디드 또는 하드웨어와 관련된 제품에도 TDD를 적용할 수 있습니까?]

  • 응용 프로그램 소프트웨어가 TDD의 이점을 얻을 수 있는 것처럼 임베디드 프로젝트 또는 하드웨어 상호 작용이 포함된 프로젝트도 TDD 접근 방식의 이점을 얻을 수 있습니다. 
  • 하드웨어가 포함된 임베디드 프로젝트나 제품은 하드웨어 종속성을 격리하여 하드웨어 없이 코드의 대부분을 테스트할 수 있으므로 TDD에서 더 많은 이점을 얻을 수 있습니다.
  • TDD는 팀에서 하드웨어를 기다리지 않고 대부분의 소프트웨어를 테스트할 수 있으므로 시장 출시 시간을 줄이는 데 도움이 됩니다.
  • 대부분의 코드는 이미 하드웨어 없이 철저하게 테스트되었으므로 보드를 불러올 때 마지막 순간에 예상치 못한 싸움을 피하는 데 도움이 됩니다.
  • 대부분의 시나리오가 철저하게 테스트되었기 때문입니다.

  • 소프트웨어 엔지니어링 모범 사례에 따르면 좋은 디자인은 느슨하게 결합되어 있고 본질적으로 강하게 결합되어 있습니다. 
  • 우리 모두는 느슨하게 결합된 코드를 작성하려고 노력하지만 항상 완전히 독립적인 코드를 작성하는 것은 불가능합니다. 
  • 대부분의 경우 코드에는 어떤 유형의 종속성이 있습니다. 
  • 애플리케이션 소프트웨어의 경우 종속성은 데이터베이스 또는 웹 서버일 수 있습니다. 임
  • 베디드 제품의 경우 의존성은 하드웨어의 일부일 수 있습니다. 
  • 그러나 종속성 inversion을 사용하면 CUT(테스트 중인 코드)를 종속성에서 격리할 수 있으므로 종속성 없이 코드를 테스트할 수 있습니다.
  • 이는 강력한 기술입니다.
  • 따라서 우리가 코드를 리팩토링하여 보다 모듈화되고 원자적으로 만드는 한 모든 유형의 코드와 프로젝트 또는 제품이 TDD 접근 방식의 이점을 누릴 수 있습니다.
728x90
Comments