TDD를 수행 할 때 로깅이 필요합니까?


40

Red, Green & Refactor주기를 수행 할 때는 항상 테스트를 통과하기위한 최소 코드를 작성해야합니다. 이것이 제가 TDD에 관해 배운 방식이며 거의 모든 책이 그 과정을 설명하는 방식입니다.

그러나 벌목은 어떻습니까?

솔직히 나는 실제로 복잡한 일이 발생하지 않는 한 응용 프로그램에서 로깅을 거의 사용하지 않았지만 적절한 로깅의 중요성에 대해 이야기하는 많은 게시물을 보았습니다.
따라서 예외를 기록하는 것 외에도 적절한 테스트 응용 프로그램 (단위 / 통합 / 수락 테스트)에서 로깅의 중요성을 정당화 할 수 없었습니다.

그래서 내 질문은 :

  1. TDD를 수행하는 경우 로그해야합니까? 테스트에 실패하면 응용 프로그램에 어떤 문제가 없는지 알 수 있습니까?
  2. 각 클래스의 각 메소드에서 로깅 프로세스에 대한 테스트를 추가해야합니까?
  3. 예를 들어 프로덕션 환경에서 일부 로그 수준이 비활성화 된 경우 테스트와 환경간에 종속성이 발생하지 않습니까?
  4. 사람들은 로그를 쉽게 디버깅하는 방법에 대해 이야기하지만 TDD의 주요 장점 중 하나는 테스트 실패로 인해 무엇이 잘못되었는지 항상 알고 있다는 것입니다.

내가 빠뜨린 것이 있습니까?


5
로깅은 많은 규칙에서 특별한 경우라고 생각합니다. 클래스 / 함수는 로깅을 제외하고 한 가지 일만해야합니다. 로깅을 제외하고 함수는 순수해야합니다. 등등. 로깅은 규칙을 위반합니다.
Phoshi

1
사용 된 SW 개발 방법론과 거의 직교하는 로깅을 사용하지 않습니까? 그래서 아마 당신은 단지 그것을 좁혀 물어해야 합니까 우리는 로깅을위한 테스트 케이스를 필요 TDD를 할 때?
hyde

답변:


50

1) TDD를 수행하는 경우 로그해야합니까? 테스트에 실패하면 응용 프로그램에 어떤 문제가 없는지 알 수 있습니까?

그것은 당신이 당신의 어플리케이션에 필요한 모든 가능한 테스트를 가지고 있다고 가정합니다. 로그는 아직 테스트를 작성하지 않은 버그를 추적하는 데 도움이됩니다.

2) 각 클래스의 각 메소드에서 로깅 프로세스에 대한 테스트를 추가해야합니까?

로거 자체가 테스트되면 다른 종속성과 마찬가지로 각 클래스에서 다시 테스트 할 필요가 없습니다.

3) 예를 들어 프로덕션 환경에서 일부 로그 수준이 비활성화 된 경우 테스트와 환경간에 종속성이 발생하지 않습니까?

사람 (및 로그 집계 자)은 로그에 의존하며 테스트는 로그에 의존해서는 안됩니다. 일반적으로 몇 가지 로그 수준이 있으며 일부는 프로덕션에 사용되며 일부 추가 수준은 다음과 같이 개발에 사용됩니다.

"레일 로그 레벨은 프로덕션 모드에서 정보이며 개발 및 테스트에서 디버그" -http : //guides.rubyonrails.org/debugging_rails_applications.html

다른 응용 프로그램도 비슷한 방식을 사용합니다.

4) 사람들은 로그를 쉽게 디버깅하는 방법에 대해 이야기하지만 TDD의 주요 장점 중 하나는 테스트 실패로 인해 무엇이 잘못되었는지 항상 알고 있다는 것입니다.

프로덕션 버그는 모든 테스트를 통과 했으므로 해당 문제를 조사하기 위해 다른 참조가 필요할 수 있습니다.


26
완벽하게 엄격하게 실행 된 TDD조차도 성능, 시스템 상호 작용, 타사 상호 작용과 관련된 생산 문제를 방지하지는 않습니다. 동시성 문제는 테스트로 완전히 다루기가 매우 어렵습니다. 100 % 테스트 범위 "만"은 코드의 100 %가 실행되었으며 모든 주나 환경에서 올바른 것은 아닙니다.
Holstebroe

34

로깅 은 응용 프로그램의 예외가 아닌 동작 을 설명하는 데 유용 합니다.

이벤트 로그 는 시스템 의 활동을 이해하고 문제를 진단하는 데 사용할 수 있는 감사 추적 을 제공하기 위해 시스템 실행시 발생하는 이벤트를 기록합니다 . 복잡한 시스템의 활동을 이해하는 데 필수적입니다. 특히 사용자 상호 작용이 적은 응용 프로그램 (예 : 서버 응용 프로그램)의 경우 ...

응용 프로그램을 테스트 한 방법과 예외가 얼마나 잘 기록되는지에 관계없이 사용자가 요청할 수 있습니다.

프로그램의 출력은 0이지만 예상되는 결과는 1입니다. 왜 그렇습니까?

예외가 아닌 동작을 설명하기 위해 애플리케이션 구성, 매개 변수 및 기타 런타임 세부 사항을 확인하려면 로깅이 필요합니다.

위의 관점에서 로깅은 개발보다 지원에 더 중점을 둡니다 . 응용 프로그램이 게시 된 후 다른 사용자가 사용자의 질문을 처리하도록하여 프로그래머가 추가 개발에 집중할 수 있도록하는 것이 바람직합니다.

어떤 응용 프로그램을 로깅하면 다른 사람 이 코드를 파지 않고 진행 상황을 설명하는 요청으로 개발자를 방해하지 않고 프로그램 동작을 이해할 수 있습니다 .


5
"로깅은 지원에 더 중점을 둡니다"+1 정말 머리에 못을 쳤다.
Tibos

1
"예외가 아닌 행동"및 "로그 기록은 지원에 더 중점을 둡니다"+1 그러나 인용문의 출처를 나열하기 위해 답을 편집 해 주시겠습니까?
logc

인용문의 @logc 소스는 여기 첫 번째 단어 인 "Logging"의 링크로 참조됩니다. 클릭하면 Wikipedia 기사로 이동합니다 : en.wikipedia.org/wiki/Logfile
gnat

16

여기에있는 대부분의 답변은 정확성 측면에 중점을 둡니다. 그러나 로깅도 다른 용도로 사용됩니다. 로깅은 성능 관련 데이터를 수집하는 방법 일 수 있습니다. 따라서 시스템이 오류없이 작동하더라도 로그가 왜 느린 지 알 수 있습니다. 모든 측면을 완벽하게 테스트하더라도 테스트 스위트는 알 수 없습니다.

물론 성능이 중요한 시스템은 일부 운영 대시 보드에 핵심 성능 메트릭을 제공 할 수 / 제공해야하지만 "클래식"로깅은 다른 수준의 세부 정보를 제공 할 수 있습니다.


2
또한 감사 추적 목적으로 로깅하는 것을 잊지 마십시오. 또는 청구. 또는 다양한 종류의 통계. 또는 다른 시스템의 다른 종류의 통계와 일치시키기위한 이벤트 로깅.
PlasmaHH

로깅하지 않고 수행 할 작업을 프로파일 링하지 않습니까? 아니면 프로파일 링 결과를 지속적으로 기록 할 수 있다는 의미입니까?
Bergi

@ Bergi : 전적으로 응용 프로그램의 작동 방식에 달려 있습니다. 예를 들어 웹 응용 프로그램 인 경우 각 요청의 서비스 시간을 기록한 다음 나중에 "나쁜 수행자"에 대한 해당 이벤트를 클러스터하려고하면 작동 할 수 있습니다.
PlasmaHH

@Bergi 프로파일 개발에서 발생하지만, 느려질 수, CPU는 더로드 할 수있는 서비스가되지 응답 시간에, 병렬 스레드가 잠금 문제로 실행 않을 수 있습니다 디스크를 사용 명심 전자 라이브 시스템에 대한 영향이있다 ...
johannes

@PlasmaHH 감사는 핵심 요구 사항의 일부이며 테스트를 거쳐야합니다. 대부분의 경우 "일반"로깅 경로를 통해 실행하지 않습니다. 감사가 아닌 일반 로깅이 실패 할 수 있습니다. "다양한 통계"내가 성능 아래 수집;)
johannes

8

주요 질문에 대한 짧은 대답은 다음과 같습니다. 일반적으로 코드의 버그는 TDD에 노출되지 않습니다. 일부 는 이상적으로는 많지만 테스트 실패가 버그가 없음을 의미하지는 않습니다. 이것은 소프트웨어 테스트에서 매우 중요한 요소입니다.

시스템에서 잘못된 동작을하는지 여부를 알 수 없으므로 드문 경우이지만 로깅은 불가피하게 잘못 될 때 무엇이 ​​잘못되었는지 이해하는 데 유용한 도구입니다.

로깅과 TDD는 다른 문제를 해결합니다.


7
  1. 일반적으로 그렇지 않은 100 % 테스트 커버가 없다면 소프트웨어가 충돌하지 않는다는 것을 알 수 없습니다. 충돌); 절대 버그가없는 소프트웨어를 할 수 있다고 생각하는 것과 같습니다 (NASA조차도 할 수 없음). 따라서 최소한 프로그램이 충돌하는 경우 가능한 실패를 기록하여 이유를 알 수 있어야합니다.

  2. 로깅은 사용중인 기술에 따라 외부 라이브러리 또는 인턴 프레임 워크에서 수행해야합니다. 내가 의미하는 바는 이미 테스트를 거쳤으며 스스로 테스트 할 필요가 없다는 것입니다. 모든 방법이 예상 한 사항을 기록하는지 테스트하는 것은 과도합니다.

  3. 로그는 테스트 용이 아니며 종속성이 없어야합니다. 즉, 환경에 해당하는 파일에 로그를 보관해야하지만 테스트, 개발 및 프로덕션 환경에 다른 파일이 있어야하지만 테스트에 대한 로깅을 비활성화 할 필요는 없습니다. 아주 최소한).

  4. 오류가 명확하지 않을 수 있으며 하나의 TDD 테스트가 실패했을 때 무엇이 ​​잘못되었는지 항상 명확하지는 않습니다. 로그가 더 정확해야합니다. 예를 들어, 정렬 알고리즘을 수행하고 전체 테스트 사례가 실패하는 경우 문제의 실제 위치를 파악하는 데 도움이되는 알고리즘의 모든 단일 테스트에 대한 로그가 있어야합니다.


3
보장 범위가 100 %인데도 발생할 수있는 모든 일에 대해 적용됩니까? 데이터베이스에 대한 네트워크 연결이 끊어지면 어떻게됩니까? 당신의 테스트는 당신에게 말할 것입니까?
Zachary K

적용 범위가 100 % 인 경우에도 소프트웨어가 충돌하지 않을 것임을 절대 알 수 없습니다. 100 % 적용 범위는 바람직한 반면, 정확성에 대한 정보는 생각보다 훨씬 적습니다.
Andres F.

그렇습니다. 요점은 충돌 가능성이 없다는 것입니다. 편집하겠습니다.
Pierre Arlaud

1
편집 내용이 여전히 올바르지 않습니다. 테스트 범위가 100 %라도 코드에 버그가있을 수 있습니다 (외부 원인을 탓할 필요 없음). 테스트가 코드 작업을 의미하지는 않습니다. 그들이 확실하게 암시하는 것은 버그를 발견 한 테스트를 작성하지 못했다는 것입니다.
Andres F.

3
"! 100 % 테스트 적용 범위! 반례 : add(x, y) = 2(항상 2를 반환) 다음 테스트는 통과하고 전체 범위를 제공합니다 assert(2 == add(1,1)). 버그가있는 기능에 대한 100 % 테스트 범위 :)
Andres F.

5

예, 일반적으로 로깅이 필요합니다.

로깅은 디버깅에 관한 것이 아닙니다. 글쎄, 로깅의 일부는 때때로 디버깅에 관한 것이며, 개발 중에 필요하지 않으면 해당 부분을 건너 뛸 수 있습니다.

그러나 로깅의 가장 중요한 부분은 유지 관리 성입니다. 잘 설계된 로깅은 다음 질문에 대답 할 수 있습니다.

  • 응용 프로그램이 여전히 살아 있고 발로 있습니까? 1000 초마다 하트 비트를 기록합니다.
  • 지난 10 개월 동안 응용 프로그램의 성능이 변경 되었습니까? 사용 사례의 성능에 대한 통계를 로깅합니다.
  • 지난 10 개월 동안 어플 리케이션의로드가 변경 되었습니까? (요청 유형 당 요청 수를 로깅하여)
  • 인터페이스 중 성능 특성이 변경된 것이 있습니까?
  • 새 릴리스가 일부 서브 시스템에 대해 다른 사용 특성을 유발합니까?
  • 우리는 DoS 공격을 받고 있습니까?
  • 어떤 종류의 오류가 발생합니까?

이 모든 것은 로깅으로 달성 할 수 있습니다. 그리고 그렇습니다. 자동으로 계획하고 설계하고 테스트해야합니다.

로깅은 다른 기능과 마찬가지로 처리를 서버에서 제거하는 기능입니다.


4

TL; DR : 로깅 및 TDD는 직교입니다. 하나를 갖는 것은 다른 것을 필요로하지 않는다

TDD를 수행하는 경우 로그해야합니까? 테스트에 실패하면 응용 프로그램에 어떤 문제가 없는지 알 수 있습니까?

내가 구현하고 보았던 대부분의 로깅은 개발 디버깅이 아닌 운영 문제 해결을위한 것입니다 (도움이 될 수는 있음). 이 로깅의 주요 대상은 서버를 실행하는 관리자 및 운영 담당자, 분석을 위해 로그를 보낸 사람 지원 및 로그를보고 진행중인 작업을 파악하려는 고객입니다.

이 로그는 통합 지점에 대한 문제를 해결하는 데 도움이됩니다. 네트워크 서비스 (데이터베이스, 비누 등), 로컬 리소스 (디스크, 메모리 등), 잘못된 데이터 (고객 입력, 잘못된 / 손상된 데이터 소스 등) 등 예외 캡처, 오류 기록 및 정보 로깅 (설정, 구성 등)은 모두 문제 해결에 도움이 될 수 있습니다.

각 클래스의 각 메소드에서 로깅 프로세스에 대한 테스트를 추가해야합니까?

로깅을 테스트하기 위해 필요한 곳에 테스트를 추가하십시오. 정보를 로그 아웃하기위한 임시 호출이있는 경우 해당 정보를 테스트해야합니다. Aspect 지향 프로그래밍 또는 메타 프로그래밍을 사용하여 로깅 및 로그 테스트를 구현하더라도 테스트 부담을 줄일 수 있습니다.

예를 들어 프로덕션 환경에서 일부 로그 수준이 비활성화 된 경우 테스트와 환경간에 종속성이 발생하지 않습니까?

IoC를 사용하여 코드를 작성하고 모의를 사용하는 경우 특정 환경 설정에 의존하지 않고 모든 로깅을 효과적으로 테스트 할 수 있어야합니다.


3

TDD는 일반적으로 코딩 버그를 줄이는 데 도움이됩니다. 사양의 버그 또는 작동 방식에 대한 오해로 훨씬 덜 도움이됩니다.

"아? 로그온이 성공했다는 확인을 받기 전에 데이터 메시지 를받을 수 있습니까? 잘 몰랐습니다. 잘 처리 할 수 ​​없습니다!"... 그런 것입니다. 로깅은 소프트웨어가 무엇을하려고했는지 알려주는 데 매우 유용하므로 잘못한 것을 발견 할 수 있습니다.


2

내 경험에 따르면 TDD를 수행하지 않으면 응용 프로그램에 큰 수준의 로깅이 추가됩니다. 그런 다음 불확실성의 수준이 높아 지므로 진행 상황을 확인하기 위해 로깅을 추가합니다.

반면 TDD (또는 테스트 할 때마다)를 할 때 나는 훨씬 적은 로그 문을 추가한다는 것을 알았습니다. 결과적으로 LOC가 줄어들고 성능에 영향을 줄 수 있습니다 (항상 그런 것은 아님).

그러나 대부분의 경우 개발 방법에 관계없이 대부분 회사에서 반자동 방식으로 함수에 대한 종료 로그를 추가합니다. 내가 아는 것처럼 이것은 생산 문제 분석에 필수적으로 고려되었습니다.

공개 인터페이스에 존재하는 EJB 서비스 Bean의 메소드를 예로들 수 있습니다. 함수가 복잡한 계산을 수행하는 경우도 있습니다. 메소드에 입력하는 숫자를 많이 얻는 데 도움이 될 수 있습니다 (예 : 일반 주제로 돌아 가기 위해 단위 테스트를 작성할 수 있음).


기능에 대한 종료 로그를 추가하는 이유를 확장 할 수 있습니까? 왜 이것이 회사에서 필요합니까?
gnat

네 그럼요. 나는 그것이 더 나아지기를 바랍니다.
dbalakirev
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.