수많은 실패한 테스트를 처리하는 방법은 무엇입니까? [닫은]


22

Java로 작성된 오래된 프로젝트를 개발 중입니다. LOC는 천만 개가 넘고 4000 개가 넘는 기능 테스트가 있습니다.

Hudson에 의해 예정된 테스트는 더 큰 코드 변경으로 인해 미친 듯이 실패합니다. 테스트 실패 확인-제품 또는 테스트에 문제가있는 경우 몇 개월이 걸립니다. 테스트 대상을 모르기 때문에 이전 테스트를 제거 할 수 없습니다!

우리는 무엇을 할 수 있습니까? 그러한 양의 레거시 테스트를 진행하는 방법은 무엇입니까?


6
실제 질문에는 답이 있습니다. 자신의 상황이 왜 끔찍한 지 또는 상사 / 동료가 왜 당신을 불행하게 만드는지 설명하기보다는 상황을 개선하기 위해 무엇을하고 싶은지 설명하십시오. 자세한 내용을 보려면 여기를 클릭 하십시오 .
gnat

13
왜 테스트가 처음부터 실패하도록 허용 했습니까? BTW 4000은 10 MLOC에 대한 많은 테스트가 아닙니다
BЈовић

6
멈추고 떨어 뜨리고 굴립니다.
Navin

13
테스트중인 테스트를 찾으십시오. 그런 다음 지구상 테스트에서 문제를 발견하는 데 몇 개월이 걸리는 방법을 다시 검토하고 궁금해 하며 요구 사항이 어떻게 바뀌 었는지 확인하십시오. 테스트는 응용 프로그램에서 요구 사항을 캡슐화하기위한 것입니다. 테스트가 실패하면 요구 사항에 따라 코드가 작동하지 않습니다. 잘못 작성했거나 요구 사항을 준수하는 코드가 없습니다.
Dan Pantry

6
우리는 모두 하나의 누락 된 '}'때문에 컴파일러가 심각한 오류를 발생시키는 것을 보았습니다. 이것들이 과도한 의존성을 가진 기능 테스트 라면 , 아마도 같은 종류의 문제가 작동하고 있습니까?
Dan Pichelman

답변:


37

그들을 버린다.

나는 분명히 많은 노력을 기울인 무언가를 버리는 것이 어렵다는 것을 알고 있지만 테스트는 당신을 위해 작동하지 않고 당신을 상대로 작동하고 있습니다. 테스트 스위트는 시스템이해야 할 일을 수행한다는 확신을 주어야합니다. 그렇게하지 않으면 자산이 아니라 책임입니다. 시스템 또는 테스트에 오류가 있는지 여부는 중요하지 않습니다. 테스트 스위트를 실행하면 막대한 양의 오류가 발생하면 목적을 달성 할 수 없습니다.

지금 필요한 것은 오류 없이 실행되는 새로운 테스트 모음입니다 . 즉, 처음에는 커버리지가 거의 없으며 실제로는 커버리지가 거의 없습니다. 시스템에 대한 내용을 고치거나 철저히 이해하기 위해 테스트 할 때마다 해당 지식을 평가해야합니다. 시간이 지남에 따라 향후 구축 할 수있는 새로운 안전망이 만들어 질 것입니다. 오래되고 이해하기 어려운 안전망을 패치하는 것은 거의 가치가없는 시간의 흐름입니다.

나는 심지어 이전 스위트에서 새로운 스위트로 테스트를 전송하는 것을 반대합니다. 물론, 그들 중 일부는 지금 성공할 수 있지만, 그들이 테스트해야하는 것을 정확하게 테스트하고 있기 때문에, 또는 임의의 샷이 항상 목표물에 부딪 혔기 때문입니까? 분명히 지출하려는 노력으로 할 수있는 것과 할 수없는 것에 대해 실용적이어야하지만 , 테스트 스위트가 작업을 수행하기 위해 깨끗하게 실행해야 한다는 원칙에 위배 될 수는 없습니다 .


9
나는 당신의 요점에서 논리를 볼 수 없다 : "테스트 스위트는 시스템이해야 할 일을 수행한다는 확신을 주어야한다. [...] 지금 당신이 필요로하는 것은 오류. " 테스트에 실패한 코드가 있다고해서 결함이있는 코드가 통과하도록 테스트를 다시 작성해야한다는 의미는 아닙니다.
DBedrenko

13
헥터의 상황은 코드 나 테스트가 잘못되었는지 알지 못하는 것 입니다. 그가 그렇게했다면 코드베이스로 작업하고 때로는 테스트, 때로는 비즈니스 코드를 변경할 수 있습니다. 그렇기 때문에 이런 종류의 준설 작업조차도 비용을 지불하지 않을 것입니다.
Kilian Foth

5
"테스트 스위트는 시스템이해야 할 일을 수행 할 것이라는 확신을 주어야합니다." 아니요, 시스템이해야 할 일을하는지 알려줍니다. 거짓 확신은 누구보다 나쁘다. "필요한 것은 오류없이 실행되는 테스트 스위트입니다." 아니오, 그가 요구하는 것은 코드의 안정성에 대한 유용한 정보를 제공하는 테스트 스위트입니다. 그가 지금 가지고있는 것은 많은 비밀 경고등이며, 아무것도 테스트하지 않는 반짝이는 새로운 테스트 스위트의 녹색 빛보다 낫습니다. 그는 이전 테스트를 일시적으로 비활성화해야 하지만 허위로 확인되지 않은 테스트 는 포기하지 않아야합니다.
Beta

4
이 답변은 매우 나쁜 조언입니다! 작은 코드 변경으로 인해 많은 실패한 테스트가 발생하면 코드 품질 문제 일 수 있습니다. 테스트는 적어도 당신이 무언가를 깨뜨렸다는 것을 알려줄 것입니다. 테스트를 통해 신중하게 리팩토링하여 코드를 개선해야합니다. 테스트를 제거하면 무언가 깨 졌는지 알 방법이 없습니다.
JacquesB

4
이것은 끔찍한 조언입니다. OP와 그의 팀이 이미 코드베이스와 테스트를 이해하지 못하면 테스트를 포기하고 다시 시작해도 OP의 핵심 문제를 해결할 가능성이 없습니다. 코드베이스를 이해하십시오. 필자는 테스트를 수행 할 때 테스트가 제대로 수행되었다고 가정 할 수 있다고 생각합니다. 따라서 그의 팀은 각 테스트에서 테스트중인 내용을 추적하고 소스를 읽어 코드베이스인지 오늘 잘못된 테스트인지 확인해야합니다. 잘못 안내되고 정보가 없거나 순진한 테스트로 시작하는 것보다 훨씬 간단합니다.
SnakeDoc

29

가서 테스트를 수정하십시오.

가장 큰 실수는 테스트 실패를 허용 한 것이며 당분간 테스트를 무시한 것입니다. 당신이 가진 것은 "레거시 테스트"가 아닙니다-당신은 레거시 코드를 작업하고 있습니다. 그리고 테스트없이 작성된 모든 코드는 레거시라고 생각합니다.


테스트 실패 확인-제품 또는 테스트에 문제가있는 경우 몇 개월이 걸립니다. 테스트 대상을 몰랐기 때문에 이전 테스트를 제거 할 수 없습니다!

명확한 요구 사항으로 작업하지 않기 때문에 조직에 더 큰 문제가있는 것 같습니다. 본인 (또는 다른 사람)이 올바른 행동을 확인할 수 없음을 이해할 수 없습니다.


4
그것이 이상적으로 수행되어야하는 것이지만, 여기서 테스트는 너무 나빠서 프로그래머가 테스트중인 것을 알지 못하는 것 같습니다. 이 경우 WTF 테스트를 없애고 새롭고 의미있는 테스트를 바로 작성하는 것이 가장 좋습니다. 최근 프로젝트에서 나는 항상 좋은 이유없이 테스트에 실패한 동료와 비슷한 문제를 겪었습니다. . 나는 며칠 동안 내가 할 수있는 것을 다시 쓰고 나머지는 버렸다!
Shautieh

@Shautieh WTF 테스트는 WTF 코드없이 진행되지 않으므로 테스트 수정은 일반적으로 코드 리팩토링을 의미합니다. 그리고 무작위로 실패한 테스트는 무능의 징후입니다. 그리고 당신의 동료의 감독자는 그들의 일을하지 않은 것에 대한 책임이 있습니다.
BЈовић

2
WTF 테스트 (및 코드)를 담당하는 사람이 팀에서 최고 급여를 받았으며 (나보다 20 % 더 높음) 프로젝트 중간에 그만두었을 때 ) 나는 그의 개발자 중 일부를 맡아야했습니다 : / 그러나 당신은 절대적으로 우리 감독자가 책임을 져야한다고 말할 수 있습니다 ^^
Shautieh

@Shautieh : 내 동료는 코드의 버그가 코드의 버그와 테스트의 사각 지대라는 두 가지 버그라고 말했습니다. 테스트 실패를 용인하는 개발자를 세면 실제로 3 명, 그런 무능한 사람을 홍보하는 관리자를 세면 4 명이라고 생각합니다.
Beta

@Beta TDD에서 때때로 사용되는 정의와 매우 유사한 소리 : "버그는 아직 작성하지 않은 테스트입니다."
Monica Monica

22

시험은 소중합니다. 최소한 그들은 누군가가 글을 쓰는 데 시간을 투자해야한다고 생각했기 때문에 아마도 누군가에게 한 번 가치가 있다고 생각합니다. 운 좋게도 팀이 작업 한 모든 기능과 버그에 대한 완전한 기록을 포함 할 것입니다. 그러나 신중하게 생각하지 않고 임의의 테스트 적용 범위 번호에 도달했을 수도 있습니다. 당신이 그들을 볼 때까지, 당신은 여기에 어떤 경우인지 알 수 없습니다.

대부분의 테스트가 대부분의 시간을 통과하는 경우 총알을 물고 실패한 몇 가지 테스트를 수행하고 다음에 작업이 더 쉬워 지도록 수정 또는 개선하는 데 시간을 투자하십시오. 이 경우 몇 가지 실패한 테스트로 수행 할 작업에 대한 조언이 필요하면 각 테스트 의도 결정 섹션으로 건너 뛰십시오 .

다른 한편으로, 당신은 지금 빨간 빌드와 한동안 지나지 않은 수백 또는 수천 개의 테스트에 직면 할 수 있으며 Jenkins는 오랫동안 녹색이 아닙니다. 이 시점에서 Jenkins 빌드 상태가 쓸모 없어졌으며 체크인 문제의 주요 지표가 더 이상 작동하지 않습니다. 이 문제를 해결해야하지만 거실의 혼란을 정리하는 동안 모든 진행 상황을 막을 여유가 없습니다.

실패한 테스트에서 어떤 값을 복구 할 수 있는지 결정하기 위해 필요한 고고학을 수행하면서 건강을 유지하려면 다음 단계를 따르는 것이 좋습니다.

실패한 테스트를 일시적으로 비활성화합니다.

환경에 따라 여러 가지 방법이 있습니다. 명확하게 설명하지 않으므로 특정 방법을 권장하지 않습니다.

일부 프레임 워크는 예상되는 실패 개념을 지원합니다. 당신이 그렇다면,이 범주에 남은 테스트 수에 대한 카운트 다운을 볼 수 있으며, 일부 테스트가 예기치 않게 통과되기 시작하면 알려줍니다.

일부 프레임 워크는 테스트 그룹을 지원하며 Hudson에게 일부 테스트 만 실행하거나 테스트 그룹을 건너 뛰도록 지시 할 수 있습니다. 즉, 때때로 테스트 그룹을 수동으로 실행하여 현재 통과 중인지 확인할 수 있습니다.

일부 프레임 워크에서는 단일 테스트에 주석을 달거나 다르게 표시하여 무시할 수 있습니다. 이 경우 그룹으로 실행하기가 더 어렵지만주의가 산만 해지지 않습니다.

일반적으로 빌드에 포함되지 않은 소스 트리로 테스트를 이동할 수 있습니다.

극단에서는 버전 제어 시스템의 HEAD에서 코드를 삭제할 수 있지만, 이로 인해 세 번째 단계가 완료되면 인식하기가 더 어려워집니다.

목표는 가능한 한 빨리 Jenkins가 Green으로 이동하도록하는 것이므로 가능한 빨리 올바른 방향으로 이동할 수 있습니다.

테스트를 적절하게 유지하십시오.

코드를 추가하거나 수정할 때 새로운 테스트를 추가하고 모든 통과 테스트를 계속 통과하도록 결심하십시오.

테스트는 잘 작성된 테스트가 아니기 때문에 여러 가지 이유로 실패 할 수 있습니다. 하지만 일단 젠킨스를 녹색으로 만들면 그렇게 유지하는 것이 정말 중요합니다.

좋은 테스트를 작성하는 데 익숙해지고 테스트가 실패하면 큰 문제가됩니다.

각 테스트의 의도를 결정하십시오.

비활성화 된 테스트를 하나씩 진행하십시오. 가장 자주 변경하는 모듈에 영향을주는 것으로 시작하십시오. 테스트의 의도와 실패 이유를 결정하십시오.

  • 의도적으로 코드베이스에서 제거 된 기능을 테스트합니까? 그런 다음 아마 삭제할 수 있습니다.

  • 아직 아무도 눈치 채지 못한 버그를 발견하고 있습니까? 테스트를 복원하고 버그를 수정하십시오.

  • 버튼 텍스트가 항상 영어라고 가정하지만 여러 언어에 대한 응용 프로그램을 현지화했다고 가정하면 부주의 한 가정을했기 때문에 실패합니까? 그런 다음 테스트를 단일 항목에 집중시키는 방법을 알아 내고 가능한 한 관련없는 변경과 분리하십시오.

  • 테스트가 전체 응용 프로그램을 통해 확산되고 시스템 테스트를 나타 냅니까? 그런 다음 기본 Jenkins 테스트 스위트에서이를 제거하고 덜 자주 실행되는 회귀 스위트에 추가하십시오.

  • 앱의 아키텍처가 인식 범위를 넘어서 변경되었으므로 테스트에서 더 이상 유용한 기능이 없습니까? 삭제하십시오.

  • 코드 커버리지 통계를 인위적으로 높이기 위해 테스트를 추가했지만 실제로 코드가 올바르게 컴파일되고 무한 루프로 들어 가지 않는다는 것을 확인하는 것 이상은 무엇입니까? 아니면 테스트는 단순히 선택한 조롱 프레임 워크가 방금 말한 결과를 반환하는지 확인합니까? 삭제하십시오.

결과적으로 일부 테스트는 그대로 유지되고 일부는 수정되며 일부는 여러 개의 독립적 인 한입 크기의 덩어리로 분할되고 일부는 제거됩니다. 새로운 요구 사항을 계속 진행하는 한, 기술 부채를 처리 할 시간을 조금 남겨 두어야 할 책임이 있습니다.


1
테스트가 실패했기 때문에 테스트를 비활성화하는 것은 정말 나쁜 생각입니다! 나머지 조언은 좋지만 이것은 아닙니다. 이해하지 못하는 테스트는 절대 비활성화하지 않아야합니다. 테스트 포인트는 녹색 막대를 얻는 것이 아니라 작동하는 소프트웨어를 얻는 것입니다!
JacquesB

문제의 규모에 따라 다릅니다. 그러나 나는 실제로 그것을 명확히하지 않았다는 것에 동의합니다.
Bill Michell

단락을 구분하는 추가 "우린 녹색 그러나 모든 변화는 물건의 이동이 빨간색하게"와 "우리는 우리가 녹색 어떤 모습처럼 잊어 버린, 너무 오래 빨간색했습니다"
빌 미첼

테스트를 비활성화하거나 삭제하는 대신 일부 프레임 워크는 예상되는 실패에 대한 개념을 제공합니다 . 새로운 장애 에 대해보다 직접적으로 경고 하지만 (실제로 많은 수의 장애가있는 경우에는 발생하지 않을 것임) 알려진 장애에 대한 알림을받을 수 있기 때문에 SNR을 높이는 데 도움이 될 수 있습니다. 이전에 실패한 테스트가 갑자기 다시 통과합니다. 예상치 못한 오류를 읽고 예상 오류가 주황색이면 빨간색 테스트를 먼저 녹색으로 설정하고 주황색 오류를 녹색으로 두 번째 우선 순위로 설정하십시오.
5gon12eder

11

4000 테스트는 다루기 힘든 문제입니다. 40 가지 테스트가 더 다루기 쉽다. 실행 및 분석 할 관리 가능한 테스트 수를 임의로 선택하십시오. 결과를 다음과 같이 분류하십시오.

  1. 쓸모없는 테스트
  2. 깨끗하게 작동하는 유용한 테스트
  3. 실패한 유용한 테스트

많은 테스트가 첫 번째 범주에 속하는 경우 현재 테스트 스위트를 버리고 현재 코드에 유용한 테스트를 작성해야합니다.

코드의 문제에 대해 알려주는 방식으로 많은 테스트가 실패하면 실패한 테스트를 통해 문제를 해결해야합니다. 하나 또는 두 개의 버그를 수정하면 많은 수의 테스트가 실행됩니다.


2
테스트 스위트 를 테스트 하는 실제 적이고 간단한 방법을 제공하기위한 + (int) (PI / 3) -경험적으로, OP에 의해 기술 된 것과 같은 테스트는 잘못된 디자인의 징조이지만 테스트는 하지 않음에 동의합니다 무엇이 잘못되었는지, 테스트 스위트 자체에 대한 조언 ( "그것을 버린다", "테스트 수정", "새 테스트 작성")은 쓸모가 없다. 정확히 당신이 말한대로 : 4k 테스트를하고 40에 대해 그 3/4 중 무작위 가 엉뚱하고 쓸모가 없다면 전체 스위트를 덤프하는 것을 망설이지 않을 것입니다. 그중 3/4이 실제로 유용했을 경우 코드를 개선하는 데 중점을 둡니다.
vaxquis

7

이 진술이 사실이라면

테스트는 ... 큰 코드 변경마다 미친 듯이 실패합니다.

"더 큰 코드 변경"직전에 코드로 롤백하면 많은 테스트가 다시 통과한다는 것을 의미합니다. 그런 다음 작은 변경 사항을 잡고 어떤 테스트가 새로 실패했는지 확인하십시오. 이렇게하면 어떤 코드 변경으로 인해 어떤 테스트가 실패했는지 더 잘 격리 할 수 ​​있습니다. 각 테스트에 대해 일단 문제점을 분리 한 후에는 새 코드에 결함이 있는지 또는 테스트에 있는지 판별 할 수 있어야합니다. 새 코드에 문제가있는 경우 특정 버그가 이미 수정 된 경우를 대비하여 최신 버전과 비교하십시오.

최신 코드베이스가 될 때까지 반복하십시오.

이것은 압도적 인 작업처럼 보일 수 있지만 일단이 길을 걷고 문제를 격리하기 시작하면 패턴이 나타나기 시작하여 프로세스 속도가 크게 빨라질 수 있습니다. 예를 들면 다음과 같습니다.

  • 많은 테스트가 결함이있는 다른 것에 의존한다는 것을 알 수 있습니다. 한 조각을 수정하면 많은 테스트가 수정 될 수 있습니다.
  • 많은 테스트에 결함이 있으므로 수정하거나 제거해야합니다.
  • 특정 개발자가 테스트를 중단시키는 빈도가 훨씬 높다는 것을 알 수 있습니다. 개발자에게는 더 많은 교육이나 감독이 필요할 수 있습니다.

3

테스트 대상을 모르는 경우 알 때까지 제거하십시오. 테스트는 유동적 인 것이므로 더 이상 필요하지 않은 기능을 제거하면 해당 기능을 테스트하는 테스트를 변경해야합니다! 테스트가 무엇인지 알지 못한다면 코드베이스를 변경하기를 희망하지 않습니다.

개발자 시스템에 테스트 시스템을 설치하고 실행할 수 있으므로 개발자는 테스트와 상호 작용하는 부분을 확인하고 누락 된 설명서를 제공하며 올바르게 변경되지 않는 코드베이스에 익숙해 질 수 있습니다. 더 이상 올바르게 테스트하십시오.

간단히 말해, 변경을 할 때 이전 테스트가 실패하면 코드 변경이 좋지 않습니다. 이러한 테스트를 시스템 작동 방식에 대한 교육 수단으로 사용하십시오.


1
이것이 제가 JUnit의 @Ignore주석을 좋아하는 이유 입니다. 테스트는 유지할 수는 있지만 실행할 수는 없습니다. 그런 다음 단순히 다시 활성화하고 한 번에 하나씩 수정하는 것입니다. 수천 번의 실패로 압도되는 대신 한 번에 소수의 테스트로 초점을 좁힐 수 있습니다.
TMN

1
이것은 나쁜 조언입니다. 이해하지 못하는 테스트를 제거하거나 비활성화해서는 안됩니다. 당신이 경우에만 테스트를 이해하고, 당신이 사용되지 않는 기능을 테스트 확신, 그것은 비활성화 또는 제거해야합니다.
JacquesB

2

내가해야 할 가장 중요한 일은 테스트가 수행해야하는 기본 사항과 비즈니스가 계속 이동해야하는 기본 사항으로 돌아가는 것입니다. 테스팅의 임무는 나중에 고치기 전에 문제가 발생하기 전에 식별하는 것입니다. 그 문장의 핵심어는 "비싸다"고 생각합니다. 이러한 문제에는 비즈니스 솔루션이 필요합니다. 비싼 문제가 현장에 표시됩니까? 그렇다면 테스트에 실패한 것입니다.

경영진과 현실 점검이 필요합니다. 레거시 테스트 세트로 인해 개발 비용이 급격히 증가하고 있습니다. 이러한 비용은 테스트를 비활성화했기 때문에 결함있는 제품을 제공하는 비용과 어떻게 비교됩니까? 실제로 사용자가 필요로하는 행동 (테스트해야하는 것)을 파악하는 번거로운 작업과 어떻게 비교됩니까?

업무의 비즈니스 측면에 영향을 미치기 때문에 비즈니스 솔루션이 필요한 문제입니다. 고객에게 제품을 제공하고 있으며 이는 비즈니스에 매우 관심이있는 경계입니다. 개발자는 개발자가 할 수없는 솔루션을 식별 할 수 있습니다. 예를 들어, 두 가지 제품을 제공하는 것이 합리적 일 수 있습니다. 신뢰성이 필요하고 새로운 기능을 기꺼이 포기하려는 사용자를위한 "레거시"제품 하나, 더 많은 결함이있을 수 있지만 앞서 나가는 "비주얼"제품 하나. 이를 통해 두 개의 독립적 인 테스트 세트를 개발할 수 있습니다. 하나는 4000 개의 테스트가있는 레거시 하나와 수행해야 할 것으로 생각되는 더 많은 테스트가있는 것입니다 (이 과정이 반복되지 않도록 문서화하십시오).

그런 다음 예술이 시작됩니다.이 두 짐승을 어떻게 관리하여 한 지부의 진보가 다른 지부의 도움을 줄 수 있습니까? 엄격한 테스트 요구 사항에도 불구하고 "가상"브랜치에 대한 업데이트가 "레거시"브랜치로 어떻게 되돌아 갈 수 있습니까? "레거시"브랜치에 대한 지속적인 고객 요청은 제품을 다시 병합 할 때 레거시 고객이 필요로하는 요구 사항을보다 잘 이해하도록 어떻게 도울 수 있습니까?


-3

테스트 대상을 몰랐기 때문에 이전 테스트를 제거 할 수 없습니다!

이것이 바로 이전 테스트를 제거 해야하는 이유입니다! 그들이 무엇을하고 있는지 모른다면 실패는 무의미하며 실패하는 것은 시간 낭비입니다. 그들을 버리고 다시 시작하십시오.


2
이것은 단지 이미 정답으로
gnat

4
실패는 "의미없는"것이 아니며, 생각했던 것뿐만 아니라 시스템을 이해하지 못한다는 것을 의미합니다.
Ben Voigt

OP는 시스템을 이해하지 못한다고 분명히 말했기 때문에 실패는 의미가 없습니다.
모헤어
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.