Java로 작성된 오래된 프로젝트를 개발 중입니다. LOC는 천만 개가 넘고 4000 개가 넘는 기능 테스트가 있습니다.
Hudson에 의해 예정된 테스트는 더 큰 코드 변경으로 인해 미친 듯이 실패합니다. 테스트 실패 확인-제품 또는 테스트에 문제가있는 경우 몇 개월이 걸립니다. 테스트 대상을 모르기 때문에 이전 테스트를 제거 할 수 없습니다!
우리는 무엇을 할 수 있습니까? 그러한 양의 레거시 테스트를 진행하는 방법은 무엇입니까?
답변
그들을 버린다.
나는 분명히 많은 노력을 기울인 무언가를 버리는 것이 어렵다는 것을 알고 있지만 테스트는 당신을 위해 작동하지 않고 당신을 상대로 작동하고 있습니다. 테스트 스위트는 시스템이해야 할 일을 수행한다는 확신을 주어야합니다. 그렇게하지 않으면 자산이 아니라 책임입니다. 시스템 또는 테스트에 오류가 있는지 여부는 중요하지 않습니다. 테스트 스위트를 실행하면 막대한 양의 오류가 발생하면 목적을 달성 할 수 없습니다.
지금 필요한 것은 오류 없이 실행되는 새로운 테스트 모음입니다 . 즉, 처음에는 커버리지가 거의 없으며 실제로는 커버리지가 거의 없습니다. 시스템에 대한 내용을 고치거나 철저히 이해하기 위해 테스트 할 때마다 해당 지식을 평가해야합니다. 시간이 지남에 따라 향후 구축 할 수있는 새로운 안전망이 만들어 질 것입니다. 오래되고 이해하기 어려운 안전망을 패치하는 것은 거의 가치가없는 시간의 흐름입니다.
나는 심지어 이전 스위트에서 새로운 스위트로 테스트를 전송하는 것을 반대합니다. 물론, 그들 중 일부는 지금 성공할 수 있지만, 그들이 테스트해야하는 것을 정확하게 테스트하고 있기 때문에, 또는 임의의 샷이 항상 목표물에 부딪 혔기 때문입니까? 분명히 지출하려는 노력으로 할 수있는 것과 할 수없는 것에 대해 실용적이어야하지만 , 테스트 스위트가 작업을 수행하기 위해 깨끗하게 실행해야 한다는 원칙에 위배 될 수는 없습니다 .
답변
가서 테스트를 수정하십시오.
가장 큰 실수는 테스트 실패를 허용 한 것이며 당분간 테스트를 무시한 것입니다. 당신이 가진 것은 “레거시 테스트”가 아닙니다-당신은 레거시 코드를 작업하고 있습니다. 그리고 테스트없이 작성된 모든 코드는 레거시라고 생각합니다.
테스트 실패 확인-제품 또는 테스트에 문제가있는 경우 몇 개월이 걸립니다. 테스트 대상을 몰랐기 때문에 이전 테스트를 제거 할 수 없습니다!
명확한 요구 사항으로 작업하지 않기 때문에 조직에 더 큰 문제가있는 것 같습니다. 본인 (또는 다른 사람)이 올바른 행동을 확인할 수 없음을 이해할 수 없습니다.
답변
시험은 소중합니다. 최소한 그들은 누군가가 글을 쓰는 데 시간을 투자해야한다고 생각했기 때문에 아마도 누군가에게 한 번 가치가 있다고 생각합니다. 운 좋게도 팀이 작업 한 모든 기능과 버그에 대한 완전한 기록을 포함 할 것입니다. 그러나 신중하게 생각하지 않고 임의의 테스트 적용 범위 번호에 도달했을 수도 있습니다. 당신이 그들을 볼 때까지, 당신은 여기에 어떤 경우인지 알 수 없습니다.
대부분의 테스트가 대부분의 시간을 통과하는 경우 총알을 물고 실패한 몇 가지 테스트를 수행하고 다음에 작업이 더 쉬워 지도록 수정 또는 개선하는 데 시간을 투자하십시오. 이 경우 몇 가지 실패한 테스트로 수행 할 작업에 대한 조언이 필요하면 각 테스트 의도 결정 섹션으로 건너 뛰십시오 .
다른 한편으로, 당신은 지금 빨간 빌드와 한동안 지나지 않은 수백 또는 수천 개의 테스트에 직면 할 수 있으며 Jenkins는 오랫동안 녹색이 아닙니다. 이 시점에서 Jenkins 빌드 상태가 쓸모 없어졌으며 체크인 문제의 주요 지표가 더 이상 작동하지 않습니다. 이 문제를 해결해야하지만 거실의 혼란을 정리하는 동안 모든 진행 상황을 막을 여유가 없습니다.
실패한 테스트에서 어떤 값을 복구 할 수 있는지 결정하기 위해 필요한 고고학을 수행하면서 건강을 유지하려면 다음 단계를 따르는 것이 좋습니다.
실패한 테스트를 일시적으로 비활성화합니다.
환경에 따라 여러 가지 방법이 있습니다. 명확하게 설명하지 않으므로 특정 방법을 권장하지 않습니다.
일부 프레임 워크는 예상되는 실패 개념을 지원합니다. 당신이 그렇다면,이 범주에 남은 테스트 수에 대한 카운트 다운을 볼 수 있으며, 일부 테스트가 예기치 않게 통과되기 시작하면 알려줍니다.
일부 프레임 워크는 테스트 그룹을 지원하며 Hudson에게 일부 테스트 만 실행하거나 테스트 그룹을 건너 뛰도록 지시 할 수 있습니다. 즉, 때때로 테스트 그룹을 수동으로 실행하여 현재 통과 중인지 확인할 수 있습니다.
일부 프레임 워크에서는 단일 테스트에 주석을 달거나 다르게 표시하여 무시할 수 있습니다. 이 경우 그룹으로 실행하기가 더 어렵지만주의가 산만 해지지 않습니다.
일반적으로 빌드에 포함되지 않은 소스 트리로 테스트를 이동할 수 있습니다.
극단에서는 버전 제어 시스템의 HEAD에서 코드를 삭제할 수 있지만, 이로 인해 세 번째 단계가 완료되면 인식하기가 더 어려워집니다.
목표는 가능한 한 빨리 Jenkins가 Green으로 이동하도록하는 것이므로 가능한 빨리 올바른 방향으로 이동할 수 있습니다.
테스트를 적절하게 유지하십시오.
코드를 추가하거나 수정할 때 새로운 테스트를 추가하고 모든 통과 테스트를 계속 통과하도록 결심하십시오.
테스트는 잘 작성된 테스트가 아니기 때문에 여러 가지 이유로 실패 할 수 있습니다. 하지만 일단 젠킨스를 녹색으로 만들면 그렇게 유지하는 것이 정말 중요합니다.
좋은 테스트를 작성하는 데 익숙해지고 테스트가 실패하면 큰 문제가됩니다.
각 테스트의 의도를 결정하십시오.
비활성화 된 테스트를 하나씩 진행하십시오. 가장 자주 변경하는 모듈에 영향을주는 것으로 시작하십시오. 테스트의 의도와 실패 이유를 결정하십시오.
-
의도적으로 코드베이스에서 제거 된 기능을 테스트합니까? 그런 다음 아마 삭제할 수 있습니다.
-
아직 아무도 눈치 채지 못한 버그를 발견하고 있습니까? 테스트를 복원하고 버그를 수정하십시오.
-
버튼 텍스트가 항상 영어라고 가정하지만 여러 언어에 대한 응용 프로그램을 현지화했다고 가정하면 부주의 한 가정을했기 때문에 실패합니까? 그런 다음 테스트를 단일 항목에 집중시키는 방법을 알아 내고 가능한 한 관련없는 변경과 분리하십시오.
-
테스트가 전체 응용 프로그램을 통해 확산되고 시스템 테스트를 나타 냅니까? 그런 다음 기본 Jenkins 테스트 스위트에서이를 제거하고 덜 자주 실행되는 회귀 스위트에 추가하십시오.
-
앱의 아키텍처가 인식 범위를 넘어서 변경되었으므로 테스트에서 더 이상 유용한 기능이 없습니까? 삭제하십시오.
-
코드 커버리지 통계를 인위적으로 높이기 위해 테스트를 추가했지만 실제로 코드가 올바르게 컴파일되고 무한 루프로 들어 가지 않는다는 것을 확인하는 것 이상은 무엇입니까? 아니면 테스트는 단순히 선택한 조롱 프레임 워크가 방금 말한 결과를 반환하는지 확인합니까? 삭제하십시오.
결과적으로 일부 테스트는 그대로 유지되고 일부는 수정되며 일부는 여러 개의 독립적 인 한입 크기의 덩어리로 분할되고 일부는 제거됩니다. 새로운 요구 사항을 계속 진행하는 한, 기술 부채를 처리 할 시간을 조금 남겨 두어야 할 책임이 있습니다.
답변
4000 테스트는 다루기 힘든 문제입니다. 40 가지 테스트가 더 다루기 쉽다. 실행 및 분석 할 관리 가능한 테스트 수를 임의로 선택하십시오. 결과를 다음과 같이 분류하십시오.
- 쓸모없는 테스트
- 깨끗하게 작동하는 유용한 테스트
- 실패한 유용한 테스트
많은 테스트가 첫 번째 범주에 속하는 경우 현재 테스트 스위트를 버리고 현재 코드에 유용한 테스트를 작성해야합니다.
코드의 문제에 대해 알려주는 방식으로 많은 테스트가 실패하면 실패한 테스트를 통해 문제를 해결해야합니다. 하나 또는 두 개의 버그를 수정하면 많은 수의 테스트가 실행됩니다.
답변
이 진술이 사실이라면
테스트는 … 큰 코드 변경마다 미친 듯이 실패합니다.
“더 큰 코드 변경”직전에 코드로 롤백하면 많은 테스트가 다시 통과한다는 것을 의미합니다. 그런 다음 작은 변경 사항을 잡고 어떤 테스트가 새로 실패했는지 확인하십시오. 이렇게하면 어떤 코드 변경으로 인해 어떤 테스트가 실패했는지 더 잘 격리 할 수 있습니다. 각 테스트에 대해 일단 문제점을 분리 한 후에는 새 코드에 결함이 있는지 또는 테스트에 있는지 판별 할 수 있어야합니다. 새 코드에 문제가있는 경우 특정 버그가 이미 수정 된 경우를 대비하여 최신 버전과 비교하십시오.
최신 코드베이스가 될 때까지 반복하십시오.
이것은 압도적 인 작업처럼 보일 수 있지만 일단이 길을 걷고 문제를 격리하기 시작하면 패턴이 나타나기 시작하여 프로세스 속도가 크게 빨라질 수 있습니다. 예를 들면 다음과 같습니다.
- 많은 테스트가 결함이있는 다른 것에 의존한다는 것을 알 수 있습니다. 한 조각을 수정하면 많은 테스트가 수정 될 수 있습니다.
- 많은 테스트에 결함이 있으므로 수정하거나 제거해야합니다.
- 특정 개발자가 테스트를 중단시키는 빈도가 훨씬 높다는 것을 알 수 있습니다. 개발자에게는 더 많은 교육이나 감독이 필요할 수 있습니다.
답변
테스트 대상을 모르는 경우 알 때까지 제거하십시오. 테스트는 유동적 인 것이므로 더 이상 필요하지 않은 기능을 제거하면 해당 기능을 테스트하는 테스트를 변경해야합니다! 테스트가 무엇인지 알지 못한다면 코드베이스를 변경하기를 희망하지 않습니다.
개발자 시스템에 테스트 시스템을 설치하고 실행할 수 있으므로 개발자는 테스트와 상호 작용하는 부분을 확인하고 누락 된 설명서를 제공하며 올바르게 변경되지 않는 코드베이스에 익숙해 질 수 있습니다. 더 이상 올바르게 테스트하십시오.
간단히 말해, 변경을 할 때 이전 테스트가 실패하면 코드 변경이 좋지 않습니다. 이러한 테스트를 시스템 작동 방식에 대한 교육 수단으로 사용하십시오.
답변
내가해야 할 가장 중요한 일은 테스트가 수행해야하는 기본 사항과 비즈니스가 계속 이동해야하는 기본 사항으로 돌아가는 것입니다. 테스팅의 임무는 나중에 고치기 전에 문제가 발생하기 전에 식별하는 것입니다. 그 문장의 핵심어는 “비싸다”고 생각합니다. 이러한 문제에는 비즈니스 솔루션이 필요합니다. 비싼 문제가 현장에 표시됩니까? 그렇다면 테스트에 실패한 것입니다.
경영진과 현실 점검이 필요합니다. 레거시 테스트 세트로 인해 개발 비용이 급격히 증가하고 있습니다. 이러한 비용은 테스트를 비활성화했기 때문에 결함있는 제품을 제공하는 비용과 어떻게 비교됩니까? 실제로 사용자가 필요로하는 행동 (테스트해야하는 것)을 파악하는 번거로운 작업과 어떻게 비교됩니까?
업무의 비즈니스 측면에 영향을 미치기 때문에 비즈니스 솔루션이 필요한 문제입니다. 고객에게 제품을 제공하고 있으며 이는 비즈니스에 매우 관심이있는 경계입니다. 개발자는 개발자가 할 수없는 솔루션을 식별 할 수 있습니다. 예를 들어, 두 가지 제품을 제공하는 것이 합리적 일 수 있습니다. 신뢰성이 필요하고 새로운 기능을 기꺼이 포기하려는 사용자를위한 “레거시”제품 하나, 더 많은 결함이있을 수 있지만 앞서 나가는 “비주얼”제품 하나. 이를 통해 두 개의 독립적 인 테스트 세트를 개발할 수 있습니다. 하나는 4000 개의 테스트가있는 레거시 하나와 수행해야 할 것으로 생각되는 더 많은 테스트가있는 것입니다 (이 과정이 반복되지 않도록 문서화하십시오).
그런 다음 예술이 시작됩니다.이 두 짐승을 어떻게 관리하여 한 지부의 진보가 다른 지부의 도움을 줄 수 있습니까? 엄격한 테스트 요구 사항에도 불구하고 “가상”브랜치에 대한 업데이트가 “레거시”브랜치로 어떻게 되돌아 갈 수 있습니까? “레거시”브랜치에 대한 지속적인 고객 요청은 제품을 다시 병합 할 때 레거시 고객이 필요로하는 요구 사항을보다 잘 이해하도록 어떻게 도울 수 있습니까?