알려진 버그가 해결 될 때 다른 곳에 새로운 버그가 나타나는 원인은 무엇입니까?


14

토론 중 동료 중 한 명이 버그를 해결하려고 시도하는 동안 현재 프로젝트에 어려움이 있다고 말했습니다. "내가 하나의 버그를 해결하면 다른 곳에서는 작동하지 않는다"고 말했다.

나는 이것이 어떻게 일어날 수 있는지에 대해 생각하기 시작했지만 그것을 이해할 수는 없습니다.

  • 너무 피곤하거나 졸려서 작업을 올바르게 하고 작업중 인 코드 부분을 전체적으로 볼 수 없는 경우가 종종 있습니다. 여기서 문제는 며칠 또는 몇 주 동안 발생한 것으로 보이며 동료의 초점과 관련이 없습니다.
  • 또한 팀원들이 누가 무엇을하는지, 다른 사람의 업무에 어떤 영향을 미치는지에 대한 아이디어가없는 매우 큰 프로젝트, 매우 잘못 관리 된 프로젝트에서 발생하는이 문제를 상상할 수 있습니다. 이 경우도 마찬가지입니다. 개발자가 한 명인 작은 프로젝트입니다.
  • 또한 변화의 결과를 실제로 상상할 수있는 유일한 개발자가 몇 년 전에 회사를 떠났던 오래되고 잘못 관리되고 문서화되지 않은 코드베이스 의 문제 일 수도 있습니다 . 여기서 프로젝트가 시작되었고 개발자는 다른 사람의 코드베이스를 사용하지 않습니다.

그렇다면 자신의 작업에 계속 집중하고있는 한 명의 개발자가 작성한 새로운 소형 코드베이스에서 이러한 문제의 원인은 무엇입니까?

무엇이 도움이 될까요?

  • 단위 테스트 (없음)?
  • 적절한 아키텍처 (코드베이스에 아키텍처가 전혀 없으며 예비 사고로 작성되지 않았다고 확신), 전체 리팩토링이 필요합니까?
  • 페어 프로그래밍?
  • 다른 것?

14
아, "올바른"파괴의 파동 "디자인 패턴. :-)
Brian Knoblauch

1
나는 그것을 한 장의 접촉으로 거품에 비유합니다. 아래로 밀면 다른 곳에 나타납니다. 코딩이 향상 될수록 더 잘 보이지 않습니다.
johnc

2
참고로, 나는 임베디드 시스템에서 정확히 그것을 가지고있었습니다. 문제를 해결하기 위해 함수 호출을 추가했습니다. 이 함수 호출은 스택에 비해 너무 많았으며 (마이크로 컨트롤러에는 스택 오버플로 감지 기능이 없음) 메모리에 다른 임의의 내용을 썼습니다. 물론 완전히 다른 곳에서 문제가 발생했습니다. 따라서이 문제는 개발자가 하나만 있고 아키텍처가 좋은 작은 코드베이스에서 발생할 수 있습니다.
어둡게 상승

... 그리고 디버깅하기에는 악몽이었습니다.
risingDarkness

답변:


38

포커스, 프로젝트 크기, 문서 또는 기타 프로세스 문제와 관련이 없습니다. 이와 같은 문제는 일반적으로 설계에서 과도한 결합 으로 인해 발생하므로 변경을 분리하기가 매우 어렵습니다.


15
이것은 불량 또는 비 회귀 테스트와 결합
Ryathal

3
사실 @Ryathal은 회귀 테스트로 이러한 종류의 버그를 예방할 수는 없지만 더 빨리 알려주십시오.
Karl Bielefeldt

버그에 대해 빨리 알면 (예 : 버그 생성 후 몇 분 내에) 변경 사항을 취소하고 실제로 발생한 적이없는 것처럼 가장 할 수 있습니다.
bdsl

14

원인 중 하나는 소프트웨어 구성 요소 사이의 긴밀한 연결 일 수 있습니다 . 구성 요소 사이에 간단하고 정의 된 인터페이스가 없으면 코드의 한 부분 만 약간만 변경해도 다른 부분에서는 예기치 않은 부작용이 발생할 수 있습니다. 암호.

예를 들어, 최근에 내 응용 프로그램에서 GUI 구성 요소를 구현하는 클래스를 작업하고있었습니다. 몇 주 동안 새로운 버그가보고되었으며 문제를 해결했으며 다른 곳에서 새로운 버그가 나타났습니다. 나는 그 클래스가 너무 커져서 너무 많은 일을하고 있었고 많은 메소드가 올바르게 작동하기 위해 올바른 순서로 호출되는 다른 메소드에 의존한다는 것을 깨달았습니다.

최신 세 가지 버그를 수정하는 대신 몇 가지 강력한 리팩토링을 수행했습니다. 구성 요소를 기본 클래스와 MVC 클래스 (3 개의 추가 클래스)로 나누었습니다. 이런 식으로 코드를 더 작고 간단한 조각으로 나누고 더 명확한 인터페이스를 정의해야했습니다. 리팩토링 후 모든 버그가 해결되었으며 새로운 버그는보고되지 않았습니다.


7

하나의 버그가 다른 버그를 감추기 쉽습니다. 버그 "A"로 인해 입력을 처리하기 위해 잘못된 함수가 호출되었다고 가정하십시오. 버그 "A"가 수정되면 갑자기 테스트 된 적이없는 올바른 기능이 갑자기 호출됩니다.


5

글쎄, 즉각적인 원인은 두 가지 잘못이 옳은 일을하거나 최소한 분명하지 않은 일을하는 것입니다. 코드의 한 부분이 다른 부분의 잘못된 동작을 보상합니다. 또는 첫 번째 부분이 "잘못"되지 않은 경우 코드가 변경 될 때 위반되는 두 부분 사이에 서면 동의가없는 것입니다.

예를 들어, 함수 A와 B가 수량에 대해 0부터 시작하는 규칙을 사용하여 올바르게 작동하지만 C가 하나를 사용한다고 가정하면 C를 사용하기 위해 A를 "수정"한 다음 B의 문제를 발견 할 수 있습니다.

더 깊은 문제는 개별 부품의 정확성에 대한 독립적 인 검증이 부족하다는 것입니다. 단위 테스트는이를 해결하기 위해 고안되었습니다. 또한 올바른 입력 사양으로 작동합니다. 예를 들어, 일련의 테스트를 통해 기능 A와 B는 0 기반 입력과 C 1 기반을 기대할 수 있습니다.

프로젝트의 요구에 따라 공식 문서에서 코드의 좋은 주석에 이르기까지 다른 방법으로 사양을 얻는 것도 가능합니다. 핵심은 각 구성 요소가 기대하는 것과 약속하는 것을 이해하는 것이므로 불일치를 찾을 수 있습니다.

좋은 아키텍처는 코드 이해 문제를 해결하는 데 도움이됩니다. 페어 프로그래밍은 처음에 버그를 피하거나 더 빨리 찾는 데 도움이됩니다.

도움이 되었기를 바랍니다.


5

긴밀한 커플 링, 테스트 부족, 아마도 가장 일반적인 범인 일 것입니다. 기본적으로 일반적인 문제는 단지 표준과 절차입니다. 다른 하나는 올바른 행동으로 잠시 운이 좋게 관리하는 잘못된 코드입니다. memcpyLinus Torvalds의 구현을 변경하면 소스 및 대상이 겹치는 memcpy위치에서 사용해야 하는 클라이언트에서 버그가 발생 (발생하지 않음) 된 버그를 고려하십시오 memmove.


4

이 "새로운"버그는 실제로 "새로운"버그가 아닌 것 같습니다. 깨진 다른 코드가 실제로 수정 될 때까지 문제가되지 않았습니다. 다시 말해, 동료는 실제로 전체 시간에 두 개의 버그가 있음을 인식하지 못합니다. 끊어지지 않았 음을 증명하는 코드가 끊어지지 않았다면 다른 코드 조각이 실제로 수정 된 후에는 실패하지 않았을 것입니다.

두 경우 모두 더 나은 자동 테스트 요법이 도움이 될 수 있습니다. 동료가 현재 코드베이스를 단위 테스트 해야하는 것처럼 들립니다. 향후 회귀 테스트에서는 기존 코드가 계속 작동하는지 확인합니다.


0

자동화 된 테스트 요법 의 을 향상 시키 십시오. 코드 변경을 커밋하기 전에 항상 전체 테스트를 실행하십시오. 이렇게하면 변경 사항의 악영향을 감지 할 수 있습니다.


0

테스트가 잘못되었을 때이 문제가 발생했습니다. 테스트에서 지정된 권한 상태가 올바른지 확인했습니다. 코드를 업데이트하고 권한 테스트를 실행했습니다. 효과가있었습니다. 그런 다음 모든 테스트를 실행했습니다. 점검 된 자원을 사용한 다른 모든 테스트가 실패했습니다. 테스트와 권한 확인을 수정했지만 처음에는 약간의 패닉이있었습니다.

일치하지 않는 사양도 발생합니다. 그런 다음 하나의 버그를 수정하면 다른 버그가 생성된다는 것이 거의 보장됩니다 (프로젝트의 후반까지 사양의 특정 부분이 실행되지 않을 때 흥미 로움).


0

완전한 제품을 가지고 있다고 상상해보십시오. 그런 다음 새로운 것을 추가하면 모든 것이 좋아 보이지만 다른 것을 깨뜨 렸습니다. 이는 새로운 기능이 작동하도록 변경하는 코드에 따라 다릅니다. 코드를 변경 하지 않고 기존 기능을 추가하기 만하면 다른 문제가 발생할 수 있습니다.

그래서 기본적으로 당신은 거의 자신에게 대답했습니다.

  • 느슨한 결합
  • 테스트 부족

TDD 원칙 (적어도 새로운 기능에 대한)을 적용하는 방법을 배우고 발생할 수있는 모든 가능한 상태를 테스트하십시오.

페어 프로그래밍은 훌륭하지만 항상 "사용 가능한"것은 아닙니다 (시간, 돈, 둘 다.). 그러나 코드 검토 (예 : 동료가 예를 들어 일주일에 한 번 커밋 세트)에 특히 검토에 테스트 스위트가 포함 된 경우 크게 도움이됩니다. (테스트 스위트에 버그를 쓰지 않는 것이 어렵다는 것을 알게되었습니다 ... 때로는 테스트를 내부적으로 테스트해야합니다 (신성 검사) :)).


0

개발자 A가 버그로 코드를 작성했다고 가정 해 봅시다. 코드는 정확히 수행 해야하는 것이 아니라 약간 다른 것입니다. 개발자 B는 A가 지정한 작업을 정확하게 수행하는 코드에 의존하는 코드를 작성했으며 B의 코드는 작동하지 않습니다. B는 A 코드에서 잘못된 동작을 찾아서 수정합니다.

한편 개발자 C의 코드는 A의 코드가 잘못된 동작에 의존하기 때문에 제대로 작동했습니다. A의 코드는 이제 정확합니다. 그리고 C의 코드는 작동을 멈 춥니 다. 즉, 코드를 수정하면이 코드를 사용하는 사람과 고정 된 코드로 동작이 어떻게 바뀌는 지 매우 신중하게 확인해야합니다.

다른 상황이 발생했습니다. 일부 코드가 잘못 작동하고 일부 상황 X에서 기능이 완전히 작동하지 않도록 중지했습니다. 따라서 오작동을 변경하고 기능을 작동 시켰습니다. 불행히도 부작용은 전체 기능이 상황 X에서 중대한 문제를 가지고 있었고 모든 곳에서 실패했다는 것입니다. 글쎄, 힘든 일이다.

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