코드 범위를 크게 향상시키는 방법은 무엇입니까?


21

단위 테스트에서 레거시 응용 프로그램을 얻는 작업을 맡았습니다. 응용 프로그램에 대한 첫 번째 배경 : 600k LOC Java RCP 코드 기반으로 이러한 주요 문제가 있습니다.

  • 대규모 코드 복제
  • 캡슐화가없고 대부분의 개인 데이터는 외부에서 액세스 할 수 있으며 일부 비즈니스 데이터도 싱글 톤으로 만들어 외부에서뿐만 아니라 어디에서나 변경할 수 있습니다.
  • 추상화 (예 : 비즈니스 모델 없음, 비즈니스 데이터는 Object [] 및 double [] []에 저장 됨)가 없으므로 OO가 없습니다.

좋은 회귀 테스트 스위트가 있으며 효율적인 QA 팀이 버그를 테스트하고 찾는 중입니다. Michael Feathers와 같은 고전 서적에서 테스트를받는 방법을 알고 있지만 너무 느립니다. 회귀 테스트 시스템이 작동하기 때문에 단위 테스트를 작성할 수 있도록 시스템을 적극적으로 리팩터링하는 것을 두려워하지 않습니다.

어떻게 커버리지를 빨리 얻기 위해 문제를 공격하기 시작해야합니까? 관리자에게 진척 상황을 보여줄 수 있습니까? AgitarOne과 같은 회귀 테스트 스위트를 생성하는 도구를 사용하고 싶지 않습니다.이 테스트는 무언가가 올바른지 테스트하지 않기 때문입니다.


회귀 테스트를 자동으로 작성하고 각각 개별적으로 검증하지 않는 이유는 무엇입니까? 손으로 직접 쓰는 것보다 더 빠릅니다.
Robert Harvey

Java 레거시로 작성된 것을 호출하는 것은 약간 유쾌하게 들리지만 동의하지만 확실히 레거시입니다. 단위 테스트를 작성하기 위해 시스템을 리팩토링하는 것을 두려워하지 않지만 리팩토링을 시도하기 전에 시스템에 단위 테스트를 작성해서는 안됩니까? 그런 다음 리팩터링을 동일한 단위 테스트를 통해 실행하여 아무것도 끊어지지 않았습니까?
dodgy_coder

1
@dodgy_coder 일반적으로 동의하지만 효율적으로 작동하는 기존 QA가 언젠가는 안전하길 바랍니다.
피터 코 플러

1
@dodgy_coder Michael C. Feathers, 레거시 코드를 효과적으로 사용하는 저자는 레거시 코드를 "테스트없는 코드"로 정의합니다. 유용한 정의로 사용됩니다.
StuperUser

답변:


10

단위 테스트를 도입 할 때 코드를 배치 할 수있는 두 가지 주요 축이 있다고 생각합니다 .A) 코드는 얼마나 테스트 가능합니까? B) 얼마나 안정적입니까 (즉, 테스트가 얼마나 시급한가)? 극단만을 살펴보면 4 가지 범주가 생성됩니다.

  1. 테스트하고 취하기 쉬운 코드
  2. 테스트하기 쉽고 안정적인 코드
  3. 테스트 및 취하기 어려운 코드
  4. 테스트하기 어렵고 안정적인 코드

카테고리 1은 비교적 적은 작업으로 많은 혜택을 얻을 수있는 확실한 출발점입니다. 카테고리 2를 사용하면 커버리지 통계를 신속하게 개선하고 (도덕에 유리함) 코드베이스에 대해 더 많은 경험을 얻을 수 있으며 카테고리 3은 더 많은 (종종 실망스러운) 작업이지만 더 많은 혜택을 제공합니다. 먼저해야 할 것은 사기와 범위 통계가 얼마나 중요한지에 달려 있습니다. 카테고리 4는 아마도 귀찮게 할 가치가 없습니다.


우수한. 종속성 수 / 테스트 가능성 탐색기와 같은 정적 분석으로 쉽게 확인할 수 있는지 확인하는 방법을 알고 있습니다. 그러나 코드가 부서지기 쉬운 지 어떻게 알 수 있습니까? 특정 단위 (예 : 클래스)와 결함을 일치시킬 수 없으며 물론 3 위 (신 클래스 / 단일) 인 경우에는 일치하지 않습니다. 체크인 횟수 (핫스팟)가 몇 개인가?
Peter Kofler

1
@Peter Kofler : 커밋 핫스팟은 좋은 생각이지만 이런 종류의 지식의 가장 귀중한 소스는 코드를 다루는 개발자들입니다.
Michael Borgwardt

1
@Peter-Michael이 말했듯이 코드를 다루는 개발자는 말했다. 상당한 시간 동안 큰 코드베이스로 작업 한 사람은 냄새가 나는 부분을 알게 될 것입니다. 또는, 모든 것은 그것의 어떤 부분, 정말 냄새 경우 악취 .
Carson63000

15

나는 이것보다 훨씬 더 큰 레거시 시스템 (Java는 아니지만)에서 많은 경험을 가지고 있습니다. 나쁜 소식을 전하는 사람이 싫습니다. 문제는 문제의 크기입니다. 당신이 그것을 과소 평가했다고 생각합니다.

레거시 코드에 회귀 테스트를 추가하는 것은 느리고 비용이 많이 드는 프로세스입니다. 많은 요구 사항이 잘 문서화되어 있지 않습니다. 여기에 버그 수정, 여기에 패치가 있으며이를 알기 전에 소프트웨어는 자체 동작을 정의합니다. 테스트가 없다는 것은 구현이 모두 필요하다는 것을 의미하며, 코드에 구현 된 암시 적 요구 사항에 "도전"하는 테스트는 없습니다.

보험을 빨리 받으려고하면 일을 서두르고 반쯤 구워서 실패 할 가능성이 있습니다. 테스트는 명백한 내용을 부분적으로 다루고 실제 문제를 다루지 않습니다. 당신은 당신이 단위 테스팅에 가치가 없다는 것을 당신이 팔려고하는 바로 그 매니저들을 확신시킬 것입니다.

IMHO, 가장 좋은 방법은 테스트 대상입니다. 메트릭, 직감 및 결함 로그 보고서를 사용하여 가장 문제가 많은 코드의 1 % 또는 10 %를 식별하십시오. 이 모듈을 세게 치고 나머지는 무시하십시오. 너무 많은 것을 시도하지 마십시오.

실제 목표는 "UT를 구현 한 이후 테스트중인 모듈의 결함 삽입이 UT가 아닌 모듈의 x %로 떨어졌습니다"(이상적으로 x는 숫자 <100)입니다.


+1, 코드보다 더 강력한 표준이 없으면 효과적으로 무언가를 단위 테스트 할 수 없습니다.
dan_waterworth

알고 동의합니다. 차이점은 우리는 QA를 제 위치에서 테스트함으로써 전통적인 회귀 테스트를 테스트한다는 것입니다. 둘째, 단위 테스트에 깊이 찬성하므로 분명히 작동하지 않는 것은 아닙니다. 무엇을 먼저 목표로 삼을지에 대한 좋은 지적. 감사.
Peter Kofler

1
"커버리지"를 목표로한다고해서 결함이있는 사소한 테스트 (명시적인 테스트가 필요하지 않은 사소한 코드에 대한 테스트)에 갇히게 될 때 품질이 향상되는 것은 아니라는 점을 잊지 마십시오. 적용 범위를 늘리기 위해 추가되었습니다). 적용 범위 도구가 유용하지 않기 때문에 적용 범위 도구를 만족시키기 위해 테스트를 작성하고 테스트를 작성하지 않고 테스트 적용 범위를 늘리기 위해 코드 자체를 변경하게 될 것입니다 (일부 적용 범위 도구와 같은 주석 및 변수 정의를 잘라내는 것과 같이) 발견되지 않은 코드를 호출합니다).
jwenting December

2

나는 말이 이미 볼트로 고정되었을 때 헛간 문에 대해 걱정하지 않는다는 말을 상기합니다.

현실은 레거시 시스템에 대한 좋은 테스트 범위를 확보 할 수있는 비용 효율적인 방법이 실제로는 짧은 시간이 아니라는 것입니다. MattNz가 언급했듯이, 그것은 시간이 많이 걸리는 프로세스이며 궁극적으로 비용이 많이 듭니다. 내 직감은 경영진에게 감동을 줄 무언가를 시도하면 테스트하려는 요구 사항을 완전히 이해하지 않고 너무 빨리 표시하려고 시도하여 새로운 유지 보수 악몽을 만들 것입니다.

실제로 코드를 작성한 후에는 중요한 것을 놓칠 위험없이 효과적으로 테스트를 작성하는 것이 늦습니다. 반면에 일부 테스트는 테스트가없는 것보다 낫다고 말할 수 있지만, 그러한 경우 테스트 자체는 시스템 전체에 가치를 더한다는 것을 보여 주어야합니다.

내 제안은 당신이 무언가 "부러진"느낌이있는 핵심 영역을 살펴 보는 것입니다. 즉, 코드가 매우 비효율적이거나 이전에 유지 관리하는 데 비용이 많이 든다는 것을 의미합니다. 문제를 문서화 한 다음이를 시작점으로 사용하여 대규모 리엔지니어링 노력없이 시스템을 개선하는 데 도움이되는 테스트 수준을 도입하십시오. 여기서 아이디어는 테스트를 따라 잡는 것을 피하고 대신 특정 문제를 해결하는 데 도움이되는 테스트를 도입하는 것입니다. 일정 시간이 지난 후에는 해당 코드 섹션을 유지하기위한 이전 비용과 지원 테스트로 적용한 수정 사항을 사용하여 현재의 노력을 측정하고 구별 할 수 있는지 확인하십시오.

기억해야 할 것은 경영진이 비용 / 혜택과 그것이 고객과 예산에 직접적인 영향을 미치는 방식에 더 관심이 있다는 것입니다. 그들은 당신이 그들에게 관심있는 혜택을 제공 할 것임을 증명할 수 없다면 최선의 일이기 때문에 단순히 무언가에 관심이 없습니다. 시스템을 개선하고 있고 현재 수행중인 작업에 대해 우수한 테스트 범위를 확보하고 있음을 보여줄 수 있다면 경영진은이를 효율적인 노력의 적용으로 간주 할 가능성이 높습니다. 이를 통해 제품 개발이 완전히 중단되거나 재 작성 주장이 거의 불가능한 상황에서 다른 주요 영역으로 노력을 확장 한 사례를 주장 할 수 있습니다!


1

적용 범위를 향상시키는 한 가지 방법은 더 많은 테스트를 작성하는 것입니다.

또 다른 방법은 기존 테스트에서 현재 중복 코드를 다루지 않는 방식으로 코드의 중복성을 줄이는 것입니다.

a, b, b '라는 3 개의 코드 블록이 있는데, 여기서 b'는 B의 복제본 (정확한 또는 미스 카피)이며 a와 b에 대해서는 적용되지만 테스트 T에서는 b '가 아닙니다.

b와 b '에서 공통성을 B로 추출하여 b'를 제거하기 위해 코드베이스를 리팩토링하는 경우, 코드베이스는 이제 a, b0, B, b'0처럼 보입니다. b0은 b'0과 함께 비공유 코드를 포함하고 있습니다. b0과 b'0은 B보다 훨씬 작으며 B를 호출 / 사용합니다.

이제 프로그램의 기능이 변경되지 않았으며 테스트 T도 없습니다. 따라서 T를 다시 실행하고 통과 할 것으로 기대할 수 있습니다. 현재 다루는 코드는 a, b0 및 B이지만 b'0은 아닙니다. 코드베이스가 작아졌고 (b'0이 b '보다 작습니다!) 우리는 여전히 원래의 내용을 다룹니다. 커버리지 비율이 높아졌습니다.

이렇게하려면 리팩토링을 활성화하기 위해 b, b '및 이상적으로 B를 찾아야합니다. 우리 CloneDR의 도구는 특히 자바를 포함, 많은 언어에 대한이 작업을 수행 할 수 있습니다. 코드베이스에 중복 된 코드가 많이 있다고합니다. 이것은 당신의 이익을 위해 그것을 다루는 좋은 방법 일 수 있습니다.

이상하게도, 찾기 b와 b '의 행동은 종종 프로그램이 구현하는 추상적 아이디어에 대한 어휘를 증가시킵니다. 이 툴은 b와 b '가 무엇을하는지 전혀 모르지만 b와 b'의 내용에 간단하게 초점을 맞출 수 있도록 코드에서 코드를 분리하는 행위는 프로그래머에게 종종 복제 된 코드가 구현하는 추상화 B_abstract에 대한 아주 좋은 아이디어를 제공합니다. . 따라서 코드에 대한 이해도도 향상됩니다. 당신이 그것을 생략 할 때 B에게 좋은 이름을 부여하십시오, 당신은 더 나은 시험 범위와보다 유지 보수가 쉬운 프로그램을 얻을 수 있습니다.

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