내가 이해하지 못하는 코드에 대한 테스트 작성


59

최근에 블랙 박스 리팩토링을 완료했습니다. 테스트 방법을 알아볼 수 없으므로 체크인 할 수 없습니다.

높은 수준에서 초기화에 클래스 B의 값을 가져 오는 클래스가 있습니다. 클래스 B가 "빈"인 경우 합리적인 기본값을 생성합니다. 이 부분을 클래스 B를 동일한 기본값으로 초기화하는 메소드로 추출했습니다.

나는 어느 수업의 목적이나 맥락이나 그것들의 사용법을 아직 해결하지 못했다. 그래서 빈 클래스 B에서 객체를 초기화 할 수 없으며 올바른 값을 가지고 있는지 확인하십시오.

최선의 아이디어는 원래 코드를 실행하고 초기화 된 멤버에 따라 공개 메소드의 결과로 하드 코드하고 새 코드를 테스트하는 것입니다. 나는 왜이 생각이 모호하게 불편하다고 느끼는지 분명히 말할 수 없다.

더 나은 공격이 있습니까?


28
당신이 잘못 시작한 것 같아요 먼저 코드를 이해하고 테스트 한 다음 리팩터링해야합니다. 코드가 무엇인지 모른 채 왜 리팩토링합니까?
— Jacob Raihle

11
@JacobRaihle 제가 만지지 않은 것들에 학위를 가진 사람들을위한 다소 전문화 된 프로그램입니다. 나는 갈 때 상황을 포착하고 있지만 시작하기 전에 확실하게 이해하기를 기다리는 것은 실용적이지 않습니다.
— JETM

4
실용적이지 않은 것은 내용을 다시 작성하고 변경 사항이 프로덕션 환경에있을 때 왜 없어야 하는지를 발견하는 것입니다. 그 전에 철저히 테스트 할 수 있다면 코드베이스를 알 수있는 좋은 방법이 될 수 있습니다. 그렇지 않은 경우 변경하기 전에 반드시 이해해야합니다.
— Jacob Raihle

37
시스템의 실제 동작을 테스트하려는 경우 특성화 테스트라고하는 특정 종류의 테스트가 있습니다. 당신은 당신의 원래 시스템을 취한 다음, 실제로 무엇을하는지 (그리고 반드시 의도 한 것이 아닌) 주장하는 테스트를 추가하십시오. 그것들은 시스템 주변의 발판 역할을하며, 시스템의 동작을 유지하기 때문에 안전하게 수정할 수 있습니다.
— Vincent Savard

3
이해 하지 못하는 사람에게 요청 / 검토를받을 수 없습니까?
— pjc50

답변:


122

잘하고 있어요!

자동 회귀 테스트 작성은 구성 요소를 리팩토링 할 수있는 최선의 방법입니다. 놀랍지 만, 입력 및 출력 "인터페이스"(해당 단어의 일반적인 의미)를 이해하는 한 구성 요소가 내부적으로 수행하는 작업을 완전히 이해하지 않고도 이러한 테스트를 작성할 수 있습니다. 우리는 과거에 클래스뿐만 아니라 본격적인 레거시 애플리케이션을 위해 여러 번이 작업을 수행했으며, 우리가 완전히 이해하지 못한 것을 깨뜨리는 것을 피하는 데 도움이되었습니다.

그러나 테스트 데이터가 충분해야하며 해당 구성 요소 사용자 관점에서 소프트웨어의 기능을 제대로 이해해야합니다. 그렇지 않으면 중요한 테스트 사례를 생략 할 위험이 있습니다.

나중에 리팩토링을 시작 하기 전에 자동화 된 테스트를 구현하여 작은 단계로 리팩토링을 수행하고 각 단계를 확인할 수있는 것이 좋습니다. 리팩토링 자체는 코드를 더 읽기 쉽게 만들어야하므로 내부에 대한 이해를 조금씩 향상시키는 데 도움이됩니다. 이 과정에서 주문 단계는

  1. "외부에서"코드를 이해하고
  2. 회귀 테스트 작성
  3. 코드의 내부를 더 잘 이해하게하는 리팩터링

21
"레거시 코드로 작업하기"
— Altoyr의

나는 이런 일을 한 번해야했다. 수정하기 전에 애플리케이션에서 일반적인 출력 데이터를 수집 한 다음 동일한 테스트 데이터를 통해 새 버전의 애플리케이션을 확인하십시오. 30 년 전 ... 포트란 ... 일종의 이미지 처리 / 매핑 작업 이었기 때문에 테스트 케이스를 보거나 출력하여 출력이 무엇인지 정확히 알 수 없었습니다. 그리고 저는 Tektronix 벡터 (영구적) 디스플레이에서이 작업을 수행했습니다. 정부 사업 ... 2 개의 텔레타이프가 내 뒤를 쾅쾅 두드렸다.

4
또한, 사실 후에도 이전 코드에 대한 테스트를 작성할 수 있습니다. 그런 다음 리팩토링 된 버전에서 시도해 볼 수 있으며, 중단 된 경우 커밋 기록을 통해 이분법 검색을 수행하여 중단되기 시작하는 지점을 찾으십시오.
— CodeMonkey

2
한 가지 더 할 것을 제안합니다. 테스트 데이터를 수집하는 동안 가능하면 코드 범위 통계를 수집하십시오. 테스트 데이터가 해당 코드를 얼마나 잘 설명하는지 알 수 있습니다.
— liori

2
@nocomprende, 지난주에 기존의 과학 포트란 77 코드를 사용하여 정확히 한 일이 재미있었습니다. 파일에 ascii 데이터 인쇄를 추가하고 입력 및 예상 출력으로 테스트 디렉토리를 설정하십시오. 내 테스트 사례는 두 출력 세트의 차이점이었습니다. 그들이 캐릭터의 캐릭터와 일치하지 않으면, 나는 무언가를 깨뜨렸다. 코드가 각각 2-3k LoC 인 2 개의 서브 루틴 인 경우 어딘가에서 시작해야합니다.
— Godric Seer

1

단위 테스트를 작성하는 중요한 이유는 구성 요소 API를 어떻게 든 문서화하기 때문입니다. 테스트중인 코드의 목적을 이해하지 못하는 것은 실제로 문제입니다. 코드 적용 범위는 또 다른 중요한 목표로, 어떤 실행 분기가 존재하고 어떻게 트리거되는지 알지 못하면 달성하기 어렵습니다.

그러나 상태를 깨끗하게 재설정 할 수있는 경우 (또는 매번 새로운 테스트 개체를 구성 할 수있는 경우) 대부분 무작위 입력을 시스템에 공급하고 출력을 관찰하는 "휴지통 휴지통"유형 테스트를 작성할 수 있습니다.

이러한 테스트는 실패 할 경우 유지 관리가 어려우며 그 이유와 심각성을 말하기가 어려울 수 있습니다. 적용 범위에 문제가있을 수 있습니다. 그러나 그들은 여전히 ​​아무것도 아닌 것보다 훨씬 낫습니다. 이러한 테스트가 실패하면 개발자는 더 많은주의를 기울여 최신 변경 사항을 수정하고 버그를 발견 할 수 있습니다.


1
모든 종류의 정보는 맹인 비행보다 낫습니다. 크래시 덤프 파일 (Unix)에서 디버거를 호출하고 스택 추적을 요청하여 프로덕션 환경에 있던 서버 프로그램에서 버그를 찾는 데 사용했습니다. 오류가 발생한 기능의 이름을 알려줍니다. 다른 지식이 없어도 (이 디버거를 사용하는 방법을 몰랐습니다) 신비스럽고 재현 할 수없는 상황에 도움이되었습니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.