배송 테스트 코드. 왜 안 그래?


17

테스트 코드를 제품과 함께 제공하고 싶습니다. 특히, 프로그램 사본을 보유한 모든 사람이 "자체 테스트"버튼을 누르거나 명령 행에서 --self-test를 통과하여 완전한 단위 제품군을 실행할 수 있도록 옵션을 제공하십시오. 통합 테스트.

필자는 현장에서 발견 된 문제를 디버그하기 위해 대부분이 작업을 수행하려고하므로 최종 사용자로부터 버그 보고서가 수신 될 때 "또한이 세 가지 테스트가 내 컴퓨터에서 실패했습니다"로 지원 될 가능성이 있습니다. 수동 테스터가 장치를 실행할 수 있기를 원합니다 | 통합 테스트도 가능합니다.

그러나 팀의 테스트는 테스트 코드가 프로덕션 코드가 아니므로 배송되지 않아야한다고 생각합니다. 대부분의 오픈 소스 프로젝트가 테스트 스위트를 제공하기 때문에 나는 실제로이 주장을 얻지 못한다. 닫힌 소프트웨어에서는 드문 것 같습니다.

나는 논쟁의 양쪽에 대한 증거 나 일화를지지하고 싶다. 어떤 스택 교환 사이트가 가장 적합한 지 가장 잘 추측했지만 이것이 잘못된 경우 알려 주시기 바랍니다.


8
비공개 소스 프로그램 (또는 수정되지 않은 공개 소스 프로그램)에서 단위 테스트가 실패한 이유는 무엇입니까? 제품에 상당한 양의 설정이 필요하고 설정 문제가 종종 버그의 원인 인 경우 데이터베이스 연결 확인, 다른 외부 서비스에 대한 연결 확인과 같은 작업을 수행하는 일종의 "내 구성 확인"앱을 제공하는 것이 좋습니다. 코드에 따라 다릅니다. 이미 코드가 작동하는지 확인 했으므로 단위 테스트가 실패하는 것은 이치에 맞지 않습니다.
저스틴 동굴


15
현장에서 단위 테스트가 실패하는 이유는 무엇입니까? 내 머리 꼭대기에서 : 손상된 프로그램. 닷지 하드웨어. 우리는 지역에서 보지 못한 경쟁 조건. 다른 동적 라이브러리에 연결되었습니다. 바이러스 백신 또는 OS와 충돌합니다. 불완전한 업데이트로 인해 관련 소프트웨어의 놀라운 버전과 함께 사용됩니다. 예상대로 작동하지 않는 다른 프로세스와의 상호 작용 필드에서 버그가 발생하는 데는 여러 가지 이유가 있으며, 주어진 단위 정의에 대해 단위 테스트에서 많은 버그가 발생할 수 있습니다.
Jon Chesterfield

7
@JonChesterfield : 프로그램에서 자체 테스트 기능을 만드는 것이 좋습니다. 자체 테스트 기능이 단위 테스트의 코드를 부분적으로 재사용 할 수 있다면 어떻습니까? 그러나 재사용 가능한 부품뿐만 아니라 이러한 기능은 "생산 코드"라는 관점에서 개발되어야합니다.
Doc Brown

2
@ JonChesterfield 나는 그 원인의 대부분에서 실패한 단위 테스트를 찍는 데 어려움을 겪고 있습니다. 통합 테스트는 또 다른 문제입니다. 너무 많은 추가 작업없이 수행 할 수 있다면 배송에 대한 장점을 볼 수 있습니다.
Loren Pechtel

답변:


19

때로는 테스트 코드에 외부 및 회사 내부의 타사 코드 스 니펫이 포함되기도합니다. 이것은 사용자가 버그를 신고 할 때 발생합니다. 테스트 (회귀 테스트 등)에서 제공 한 코드를 통합하여 재생산합니다. 버그를 재현하기 위해 이러한 코드 스 니펫의 라이센스가 명확하지 않은 경우가 종종 있습니다. 따라서 지적 재산권 문제를 알고 있어야합니다. 실수로 회사의 다른 부서 나 외부 파트너의 영업 비밀이나 지적 재산을 공개하는 테스트 코드를 발송하고 싶지 않습니다.

또 다른 참고로, 테스트 코드는 프로덕션 코드 표준에 거의 적용되지 않습니다. 코드 검토가 반드시 수행되는 것은 아닙니다. 코딩 표준 등이 적용되지 않습니다. 이것은 불행한 일이지만 흔한 일이며, 테스트가 진행될 당시 그 목표를 가지고 있지 않은 경우 테스트 팀에 제대로 반영되지 않아야합니다.

반면에, 많은 테스트는 당혹스럽고 나쁘고 일부 테스트는 테스트 대상이라고 생각하지도 않습니다. 그것은 다른 문제입니다 ...

궁극적으로 이러한 모든 요인으로 인해 테스트 를 오픈 소스 로 제공 할 수있는 테스트와 단순히 할 수없는 테스트로 분류 할 수 있습니다 . 배송을 염두에두고 일부 사용자 지정 테스트를 작성하여 다른 테스트를 천천히 해당 세트로 마이그레이션하려고 할 수 있습니다.


타사 문제는 정말 좋은 지적입니다. 테스트 코드를 "외부 적으로 볼 수있는"것과 "기밀이있을 수있는"것으로 그룹화하면 오류가 발생하기 쉬우 며 상당한 오버 헤드가 발생합니다. 그것은 그 자체로 많은 거래 차단기입니다. 감사합니다.
Jon Chesterfield

그렇습니다, 사실 후에하기가 어렵습니다. 배송 테스트를 개발하기 위해 최선을 다하면 더 운이 좋을 것 같습니다.
Erik Eidt

@ErikEidt : OP가 생각한 것이 아니기 때문에 "오픈 소스로"를 제거 할 것을 제안 할 자유를 얻었습니다. 테스트를 비공개 소스로 제공하려고합니다.
Doc Brown

@DocBrown, 나는 당신의 요점을 취합니다. 아마도 OP가 포스트의 어딘가에 "오픈 소스"를 언급했을 때 해석상의 문제 일 것입니다. 어쨌든 편집은 포인트를 멋지게 일반화합니다.
Erik Eidt 2016 년

18

배송 테스트? 예. 배송 단위 테스트? 아니.

의견에서 말했듯이 클라이언트 컴퓨터에서 제품을 실행할 때 발생할 수있는 문제에는 잘못된 dll과의 연결과 같은 문제가 포함됩니다. 일반적으로 이것은 단위 테스트에서 포착 할 수있는 것이 아닙니다 (의심 할 여지없이 dll을 조롱했을 것입니다) 코드를 테스트하기 위해).

이제 dll을 호출하는 로직을 호출하는 UI를 호출하는 통합 테스트 스위트를 제공하는 것이 훨씬 효과적입니다. 통합 테스트는 단위 테스트가 표시되지 않는 실패한 설치의 다른 측면을 보여줄 수 있습니다. (예 : 현재 제품에는 라이센스로 인해 번들로 제공 될 수없는 k-lite 코덱 설치가 필요합니다. 단위 테스트는 코드가 제대로 작동하지만 고객 만족을 위해 작동하지 않을 수 있음을 보여줍니다. 마찬가지로, 코덱 구성 제대로 작동하지 않았을 수도 있습니다 (단위 테스트에서도 표시되지 않음).

따라서 설치, 통합 제품에 원하는 통합 테스트를 대신 제공하십시오.


2

크로스 플랫폼을 제공하면서 모든 단일 CPU 코어, SIMD 내장 함수, GPU, GPGPU 등을 사용하는 멀티 스레드 차세대 AAA 게임 엔진과 같이 하드웨어의 모든 1 인치를 커버하는 영역에서이 문제를 강력하게 이해할 수있었습니다. 생성물.

이 경우 최악의 악몽은 종종 테스트 (단위 및 통합)가 테스트 된 첫 번째 5,000 개의 이기종 기계 / 플랫폼에 대해 통과하지만 모호한 GPU 모델의 드라이버 버그로 인해 5,001 번째에는 실패하는 경우입니다. 이것에 대해 나에게 떨림을 줄 수 있습니다. 미리 미리 테스트하거나 예측할 수는 없습니다.

특히 GPU 셰이더를 작성하는 경우 관련된 모든 GPU 모델 / 드라이버에 의해 시행되는 이식 가능한 표준 보증이 거의 없기 때문에 작성하는 코드의 절반이 정의되지 않은 동작을 호출하는 역 복권을 재생할 수 있습니다. 요즘에는 지뢰 찾기와 같이 점점 더 작아지고 있지만 사람들에게 몇 가지 아이디어를 제공해야합니다 : http://theorangeduck.com/page/writing-portable-opengl . 90 년대 후반과 2000 년대 초반에 이것을 시도하는 것은 정말로 끔찍했고, 그것은 지뢰 찾기였습니다.

이러한 종류의 경우 제품을 안정적으로 출시하고 안정적인 출시 전에 확신을 갖기 위해 광범위한 하드웨어 및 운영 체제를 갖춘 10,000 명 이상의 테스터 팀이 종종 필요합니다 . 모든 기업들은 다양한 테스트 기반을 가지고 여유가 있고, 모든 것이 잘 (모든 널리 눈에 띄는 문제가 해결되어야 할 분야가 이전에 그렇지 않으면 일부 내부 전 알파 / 알파 단계 또는에서 많은 테스터 데 중복 보고서가 넘치면 개발자가 패치 및기도 패닉에 빠질 수 있습니다).

이 경우에 권장하는 것은 다른 사람들이 제안한 것입니다. 분산 통합 테스트 세트에 중점을 둡니다. 설치 프로그램과 함께 번들로 제공 할 수 있으므로, 사용자가 설치에 실패한 이유를 개발자에게 전달하는 데 대한 세부 정보를 제공하는 데주의를 기울여 기본 진단 검사를 통과해야합니다.

또 다른 것은 (보스를 설득 할 수있는 경우) 연속 통합을 수행 할 수있는 광범위한 하드웨어를 보유하는 것입니다. 더 다양한 하드웨어 / OS 콤보, 장점. CI 서버의 최소 하드웨어 요구 사항을 모델링하는 다양한 불량 하드웨어도 원합니다.

그러나 내가 제안 할 것이 하나 더 있습니다.

벌채 반출

위에서 설명한 시나리오와 같은 것을 다루는 경우 가장 문제가 많은 경향이있는 것들을 테스트 할 수없는 경우가 종종 있습니다 (가장 최악의 시간에 나타나고 심지어는 특정 하드웨어 / OS 콤보로 제한되는 문제이므로 가장 철저한 테스트 스위트).

그러나 불명확 한 하드웨어 비 호환성 또는 명백한 드라이버 결함 또는 잘못된 dylib에 대한 링크 (실제로는 이러한 문제에 직면 한 적이 없음)와 같은 대부분의 문제는 소프트웨어를 시작하는 데 크게 도움이되지 않습니다. 일반적으로 조만간 충돌하고 타 버릴 것입니다.

나는 건강을 위해 피할 수없는 것을 포용하는 것이 좋습니다. 종합적으로 테스트 할 수없는 이러한 작업에 대해서는 아무것도 할 수 없습니다. 허리케인을 막으려 고 노력하지 말고 (불가능) 그 창문을 세우십시오.

일반적으로 여기서 할 수있는 최선의 방법은 가능한 한 빨리 문제를 찾아 내서 가능한 한 상세하게 (의심 목록을 좁히기 위해)보고하고 문제가보고 된 후 최대한 빨리 수정하는 것입니다.

이 경우 로깅은 생명의 은인이 될 수 있습니다. 이러한 종류의 필드에 대해서는 아무도 읽지 못한 스팸 기술 로그를 만들 수 있습니다. 드라이버 결함으로 인해 충돌이 발생하기 전에 로그에 기록 된 마지막 행과 관련이있는 경우가 종종 있습니다. 예를 들어 충돌을 모니터링 한 다음 사용자가 복사 할 수있는 로그의 마지막 행을 표시하는 외부 프로세스 또는 후크를 작성할 수 있습니다. 예를 들어 크래시 덤프 외에 붙여 넣습니다.

여기에는 종종 세분화 된 정보가 필요하고 이러한 하드웨어 / 플랫폼 / 드라이버 문제와 관련하여 코드에서 가장 민감한 영역이 많으므로 성능이 매우 중요하므로 로깅이 빈번한 속도로 발생하여 실제로 느려질 수있는 어색한 문제가 있습니다 소프트웨어 다운.

이 경우 유용한 트릭은 한 번 실행 된 항목이 두 번째, 세 번째 등 성공적으로 실행된다는 가정에 의존하는 것입니다. 이는 가장 건전한 가정은 아니지만 종종 "충분히 좋은"것입니다. . 이를 통해 약간의 외부 상태를 사용하여 무언가가 이미 기록 된 시점을 추적하고 루프에서 반복적으로 코드가 호출되는 매우 세부적인 경우에 대한 후속 시도를 건너 뛸 수 있습니다.

어쨌든, 이것이 도움이되기를 바랍니다. 나는 과거에 이런 종류의 유혹을 겪었고 나와 자신과 팀 간의 과거 경험의 결과로 GPU 코딩 (GPGPU와 쉐이더)을 둘러싼 약간의 편집증이 있습니다 (때로는 다른 팀 구성원이 실제로 이러한 문제를 처리하는 것을 보았습니다) 늦게 출시 된 후 릴리스는 앤티 앨리어싱 된 라인을 렌더링 할 때 충돌이 발생하는 특정 Radeon 모델의 일부 ATI 결함과 같은 크립을 제공했으며 나중에 사용 가능한 해결 방법 솔루션으로 알려진 문제로보고되었습니다.

로깅은 우리의 꽁초를 저장 한 것인데, 우리가 들어 본 적이없는 온보드 GPU가있는 10,001 번째 모호한 프로토 타입 머신의 문제를 자주 볼 수있게했으며, 마지막 코드 줄을 통해 오류가 발생한 위치를 정확히 2 개 확인할 수있었습니다. 또는 세 줄의 코드가 의심되는 경우, 예를 들어 정교한 쉐이더 안에있는 경우 GPU 쉐이더 내부에서 로깅을 수행 할 수 없기 때문에 일종의 SOL입니다. 그러나 최소한 로깅을 사용하여 어떤 쉐이더에 문제가 있는지 즉시 확인할 수 있습니다 조사를 시작합니다.


2
로깅 코드를 메모하는 것은 영리합니다. 현재 성능 문제로 인해 로그를 생성하지 않으므로 디버깅에는 코어 덤프가 포함됩니다. 설치 프로그램에 진단 테스트를 포함시키는 것도 좋습니다. 자세한 답변 감사합니다.
존 체스터 필드
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.