저는 최근에 신뢰성이 낮아 사용하기가 정말 실망스러운 테스트 스위트를 작업했습니다.
테스트 스위트가 대상으로 하는 애플리케이션은 Rails API 전용 애플리케이션이었습니다. 테스트는 "JSON REST 엔드포인트에서 엔드 투 엔드 테스트를 수행하도록 설계된 API 테스트 프레임워크"인 Chakram이라는 프레임워크를 사용하여 JavaScript로 작성되었습니다.
테스트 스위트의 문제는 그것이 결정적이지 않다는 것이었습니다. 동일한 입력이 주어지면 항상 동일한 출력을 제공하는 함수 또는 프로그램은 결정적입니다.
이 특정 테스트 스위트는 애플리케이션 코드나 테스트 코드를 변경하지 않고 첫 번째 실행에서 통과하고 두 번째 실행에서 통과한 다음 세 번째 실행에서 실패합니다.
rake db:reset
을 수행하여 테스트 스위트를 다시 통과 상태로 되돌릴 수 있음을 발견했습니다. . 테스트 환경이 아닌 Rails 애플리케이션의 개발 환경에서 작동하는 테스트는 테스트 스위트가 실행되기 시작했을 때 특정 상태에 있었던 Rails 애플리케이션의 데이터베이스에 의존했습니다.
때로는 새로 시드된 데이터베이스로 시작하여 테스트 스위트를 실행한 다음 두 번째로 테스트 스위트를 성공적으로 실행할 수 있습니다. 테스트 스위트를 세 번 이상 실행할 수도 있습니다. 하지만 꽤 자주, 테스트 스위트는 어떻게든 데이터를 엉망으로 만들고 나는 또 다른 rake db:reset
을 해야 했습니다. 테스트 스위트가 성공적으로 사용할 수 있는 상태로 데이터를 되돌리기 위해.
이것은 당연히 일이 되어야 하는 방식이 아닙니다. 테스트 스위트는 단 한 가지 이유로 실패해야 합니다. 테스트 중인 코드가 제대로 작동하지 않는다는 것입니다.
대신 해야 할 일
따라서 이 테스트 스위트가 문제가 있는 방식으로 설정되었다면 올바른 방법이었을까?
문제의 근본 원인은 테스트 스위트가 사람이 수동으로 수행하는 데이터베이스 재설정에 의존한다는 것입니다. 대신, 테스트 스위트의 각 개별 테스트는 실행 전에 데이터베이스를 자동으로 깨끗하고 준비된 상태로 전환해야 합니다. (또한 테스트가 실행 후 데이터베이스를 지우는 것이 일반적이므로 데이터가 다른 테스트로 "누출"되지 않습니다. 모든 단일 테스트가 실행하기 전에 데이터베이스를 지우는 경우에는 반드시 필요한 것은 아니지만 좋은 보호 조치입니다. )
또한 테스트 스위트는 개발 환경이 아닌 Rails 애플리케이션의 테스트 환경을 대상으로 해야 합니다. 개발 환경에서 개발자의 작업은 테스트 제품군의 작업을 방해해서는 안 되며 그 반대의 경우도 마찬가지입니다.
다른 유형의 문제가 있는 종속성
제 이야기에 따르면 문제가 되는 종속성은 제대로 정리되지 않는 데이터베이스였습니다.
문제가 되는 종속성의 또 다른 유형은 네트워크 요청입니다. Twilio API에 도달하는 테스트 제품군이 있다고 상상해 보십시오. 화요일에 테스트 스위트를 실행하고 통과합니다. 그런 다음 수요일에 동일한 테스트 제품군을 실행하고 실패합니다. 당신도 모르는 사이에 Twilio가 중단되고 있으며 이것이 테스트 제품군이 실패한 이유입니다. 몇 분 후 중단이 해결되고 테스트 제품군이 다시 통과합니다.
이것은 테스트가 한 가지 이유로만 실패해야 한다는 생각으로 돌아갑니다. 이는 애플리케이션 코드가 작동을 멈춘 경우입니다.
네트워크와 상호 작용하는 코드에 대한 테스트를 작성해야 하는 경우 더 나은 방법(Ruby/Rails를 사용하는 경우)은 VCR과 같은 도구를 사용하여 네트워크 요청을 기록한 다음 실제로 인터넷을 사용합니다.
외부 종속성이 괜찮은 경우
애플리케이션이 Twilio API에 의존하고 Twilio API가 다운된 경우 애플리케이션이 실제로 중단되었으므로 테스트가 실제로 실패해야 한다고 주장할 수 있습니다. 테스트가 외부 조건에 의존해서는 안 된다는 아이디어와 이 아이디어를 어떻게 조화시킬 수 있습니까?
이 두 가지를 조화시키는 방법은 통합 테스트를 구별하는 것입니다. , 여러 레이어 또는 시스템을 함께 테스트하고 단위 테스트 , 단일 기능을 개별적으로 테스트합니다.
팀이 여러 시스템을 함께 테스트할 수 있도록 특정 테스트 세트가 네트워크를 통해 외부 서비스에 영향을 미칠 것이라는 의식적인 결정을 내린다면, 그것에 대해 "잘못"된 것은 없습니다. (대안은 해당 시스템을 함께 테스트하지 않기로 결정하는 것입니다.) 이 시나리오에서 팀은 네트워크 종속 통합 테스트 제품군이 결정적이라고 보장되지 않으며 때때로 조각날 가능성이 있음을 인식해야 합니다. . 이와 같은 테스트 스위트는 개발자가 회귀를 확인하기 위해 매일 자신의 컴퓨터에서 실행하는 테스트 세트와 별도로 존재해야 합니다.
테스트가 외부 조건에 의존하지 않아야 한다는 규칙에 대한 예외가 있지만 대부분의 경우 규칙을 준수해야 테스트 스위트에 결정적이고 신뢰할 수 있다는 이점이 있습니다.