레거시 코드에 단위 테스트 추가 [닫힌]


79

레거시 코드에 단위 테스트를 추가 한 적이 있습니까? 코드가 얼마나 복잡하고 모든 것을 스텁하고 조롱하는 것이 얼마나 어려웠습니까? 최종 결과가 가치가 있었습니까?


4
"레거시 코드로 효과적으로 작업하기"를 살펴 보겠습니다. 이 모든 정적 종속성에 대한 래퍼를 작성하는 방법에 대한 좋은 포인터를 제공하기를 바랍니다.
BuckeyeSoftwareGuy

답변:


57

내가 찾은 가장 좋은 방법은 단지 뛰어 들어서 이제 애플리케이션을 단위 테스트하겠다고 말하는 것이 아니라 단위 테스트를 점진적으로 추가하는 것입니다.

따라서 버그 수정 또는 리팩토링을 위해 코드를 만질 경우 먼저 단위 테스트를 작성하십시오. 버그의 경우 단위 테스트는 복제 할 수 있으므로 문제의 위치를 ​​증명하는 데 도움이됩니다.

리팩토링하는 경우 단위 테스트를 작성하고 싶지만 테스트를 작성하는 것이 불가능하다는 것을 알 수 있으므로 리팩토링 할 함수를 호출하는 상위 레벨을 찾고 해당 부분을 단위 테스트해야 할 수 있습니다. 그런 다음 공격적인 함수를 리팩터링 할 때 제대로 작동하는지 확인할 수 있도록 테스트를 작성합니다.

이렇게하는 쉬운 방법은 없습니다.

이 질문은 더 많은 제안에 도움이 될 수 있습니다. 대규모 레거시 (C / C ++) 코드베이스에 단위 테스트를 어떻게 도입합니까?


8
테스트를 점진적으로 추가하려면 +1합니다.
TrueWill

42

Michael Feathers의 책 "레거시 코드로 효과적으로 작업하기"는이 주제를 다루는 전체 책입니다. Michael은 레거시 코드가 테스트 가능하도록 구성되지 않았기 때문에 테스트를 도입하기가 너무 어렵다고 말합니다. 제가 책에서 가장 많이 얻은 것은 "Sprout functions"와 "Sprout classes"라는 이름의 두 가지 패턴이었습니다. 새싹 함수는 코드에서 변경해야하는 변경 사항을 캡슐화하는 함수입니다. 그런 다음 이러한 함수 만 단위 테스트합니다. 새싹 클래스는 새로운 기능이 클래스에 포함된다는 점을 제외하면 동일한 아이디어입니다.


10

예, 일반적으로 고통 스럽습니다. 나는 종종 대신 통합 테스트를 작성해야했습니다.

The Art of Unit Testing 책 에는 이에 대한 좋은 조언이 있습니다. 또한 Working Effectively with Legacy Code 책을 권장합니다 . 나는 아직 후자를 읽지 않았지만 그것은 내 스택에 있습니다.

편집 :하지만 예, 최소한의 코드 커버리지조차도 가치가있었습니다. 코드 리팩토링에 대한 자신감과 안전망을 제공했습니다.

편집 : 나는 레거시 코드로 효과적으로 작업을 읽었으며 훌륭합니다.


4
"레거시 코드로 효과적으로 작업하기"에 대한 +1 : 훌륭한 조언으로 가득합니다. 실제로 테스트 가능성을위한 코드 구성에 대한 훌륭한 리소스와 마찬가지로 그린 필드 환경에서도 읽을 가치가 있습니다.
itowlson

1
통합 테스트로 단위 테스트를 대체하는 아이디어는 +1입니다. 적절한 조롱을 사용하면 전자는 충분히 양호합니다
DVK

7

또한 레거시 코드 단위 테스트 영역의 새로운 접근 방식을 살펴보십시오. Asis 프로젝트ApprovalTests 프로젝트에서 영감을 받아 핵심 개념을 공유합니다.

이 기사 에서 ApprovalTests 접근 방식에 대해 언급했듯이 :

종종 테스트가 전혀없는 거대한 레거시 코드 프로젝트가 있지만 새로운 기능을 구현하거나 리팩터링하려면 코드를 변경해야합니다. 레거시 코드의 흥미로운 점은-작동합니다! 작성 방법에 관계없이 수년 동안 작동합니다. 그리고 이것은 그 코드의 매우 큰 장점입니다. 승인을 받으면 단 하나의 테스트로 모든 가능한 출력 (HTML, XML, JSON, SQL 또는 출력이 될 수있는 모든 출력)을 얻고 승인 할 수 있습니다. 이러한 테스트를 완료하고 결과를 승인 한 후에는 기존의 모든 동작을 "잠그기"때문에 리팩토링으로 훨씬 더 안전합니다.

Asis 도구는 특성화 테스트를 자동으로 생성하고 실행하여 레거시 코드를 관리하는 것입니다.

자세한 내용은


더 많은 찬성표가없는 이유는 무엇입니까? 리포지토리가 주장하는 작업을 수행하는 경우 이것이 선택된 답변이어야합니다.
lolololol 올

그것은 기능의 부작용을 다룹니까, btw? 이 문제를 해결할 수 있습니까?
lolololol 올

5

레거시 코드로 효과적으로 작업에 소개 된 단위 테스트에 대한 한 가지 대안은 특성화 테스트 입니다. 그런 테스트로 흥미로운 결과를 얻었습니다. 테스트 할 수있는 것보다 지점에서 테스트 할 때 단위 테스트보다 설정하기가 더 쉽습니다 (이음새라고 함). 단점은 테스트가 실패하면 테스트 영역이 단위 테스트보다 훨씬 클 수 있으므로 문제의 위치에 대한 힌트가 적다는 것입니다. 여기에서 로깅이 도움이됩니다.


xUnit 제품군과 같은 단위 테스트 프레임 워크를 사용하여 특성화 테스트를 작성할 수 있습니다.

사실 뒤에 작성된 이러한 테스트에서 어설 션은 코드의 현재 동작을 확인합니다. 단위 테스트와 달리 그들은 코드가 정확하다는 것을 증명하지 않으며 코드의 현재 동작을 고정 (특징 화)하고 있습니다.

프로세스는 TDD 프로세스와 유사합니다.

  • 코드 일부에 대한 테스트 작성
  • 실행-실패
  • 코드의 관찰 된 동작에서 테스트 수정
  • 실행-패스
  • 반복

코드의 외부 동작을 수정하면 테스트가 실패합니다. 코드의 외부 동작? 익숙한 소리? 예, 여기 있습니다. 이제 코드를 리팩터링 할 수 있습니다.

분명히 위험은 특성화 테스트의 범위에 따라 다릅니다.


5

무료 오픈 소스 단위 테스트 유틸리티 라이브러리 인 ApprovalTests를 살펴보십시오 . .NET 개발자라면 제작자 인 Llewellyn Falco 가 ApprovalTests를 사용하여 새 코드와 레거시 코드 모두에 대한 단위 테스트를 개선하는 방법을 보여주는 일련의 비디오 를 만들었습니다 .


4

레거시 코드를 리팩토링 할 계획이라면 이러한 단위 테스트를 만드는 것이 필수입니다. 조롱이나 스터 빙에 대해 걱정하지 마십시오. 변경 사항이나 리팩토링 노력이 현재 기능을 손상시키지 않도록 시스템의 입력 및 출력 테스트에 대해 걱정하십시오.

거짓말을하지 않겠습니다. 단위 테스트를 레거시 코드로 개조하는 것은 어렵지만 그만한 가치가 있습니다.


작업해온 레거시 코드에 대한 단위 테스트를 만들기 시작했습니다. 하지만 실제 데이터를 만들어 데이터베이스에 삽입하기 때문에 단위 테스트가 아닌 통합 테스트를 작성하고 있다는 것을 깨달았습니다. 이 레거시 코드는 테스트 용으로 구성되지 않았기 때문에 순수한 모의와 스텁을 만드는 방법이 없습니다.
Vin Shahrdar 2011

1

저는 XPDays http://xpdays.com.ua/archive/xp-days-ukraine-2012/materials/legacy-code/ 에서 레거시 코드의 Reversed Tests Pyramid에 대한 아이디어에 대해 얼마 전에 이야기했습니다 .

이 프레젠테이션은 레거시 코드로 작업 할 때 통합 / 기능 또는 높은 수준의 승인 테스트로 시작하는 것이 왜 그렇게 중요한지에 대한 질문에 답해야합니다. 그리고 천천히, 단계적으로 단위 테스트를 도입합니다. 코드 예제는 없습니다. 미안하지만 Michaels Feathers의 책 "레거시 코드로 효과적으로 작업하기"에서 많은 예제를 찾을 수 있습니다.

또한 Legacy Code Retreat http://www.jbrains.ca/legacy-code-retreat를 확인 하고 해당 지역에서 해당 회의를 찾을 수 있습니다.

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