JavaRush /Java Blog /Random-KO /TDD와 단위 테스트란 무엇입니까?
Dr-John Zoidberg
레벨 41
Марс

TDD와 단위 테스트란 무엇입니까?

Random-KO 그룹에 게시되었습니다
이 기사는 The Complete Software Career Guide 책의 한 장을 각색한 것입니다. 저자인 John Sonmez가 이 책을 집필하고 그의 웹사이트에 일부 장을 게시합니다.
TDD와 단위 테스트란 무엇인가 [번역] - 1

초보자를 위한 짧은 용어집

단위 테스트 또는 단위 테스트는 프로그램 소스 코드의 개별 모듈이 올바른지 확인할 수 있는 프로그래밍 프로세스입니다. 아이디어는 모든 중요하지 않은 함수나 메서드에 대한 테스트를 작성하는 것입니다. 회귀 테스트는 소스 코드의 이미 테스트된 영역에서 오류를 탐지하는 것을 목표로 하는 모든 유형의 소프트웨어 테스트에 대한 일반적인 이름입니다. 이러한 오류(프로그램을 변경한 후 계속 작동해야 하는 작업이 작동을 멈추는 경우)를 회귀 오류라고 합니다. 빨간색 결과, 실패 - 테스트 실패입니다. 예상 결과와 실제 결과의 차이. 녹색 결과, 합격 - 양성 테스트 결과. 실제 결과는 얻은 것과 다르지 않습니다. ***
TDD와 단위 테스트란 무엇인가 [번역] - 2
저는 테스트 주도 개발(TDD) 및 단위 테스트와 매우 혼합된 관계를 갖고 있습니다. 사랑에서 증오로, 다시 증오로. 나는 열렬한 팬이면서 동시에 이것과 다른 "모범 사례"의 사용에 대해 의심스러운 회의론자였습니다. 내 태도의 이유는 소프트웨어 개발 프로세스에서 심각한 문제가 발생했다는 사실에 근거합니다. 개발자, 때로는 관리자가 특정 도구와 방법론이 "모범 사례"에 속한다는 이유만으로 사용합니다. 실제 사용 이유는 불분명합니다. 어느 날 특정 프로젝트 작업을 시작했는데 그 과정에서 엄청난 수의 단위 테스트가 포함된 코드를 수정하게 될 것이라는 소식을 들었습니다. 농담이 아니라 약 3000개가 있었습니다. 이는 일반적으로 개발자가 고급 방법론을 사용하고 있다는 좋은 신호입니다. 이 접근 방식을 사용하는 코드는 대부분 구조화되어 있으며 신중한 아키텍처를 기반으로 합니다. 한마디로, 테스트의 존재는 프로그래머의 멘토로서의 일을 더 쉽게 만들어준다는 의미이기 때문에 나를 행복하게 만들었습니다. 이미 단위 테스트가 있었기 때문에 내가 해야 할 일은 개발팀에 연결하여 이를 지원하고 자체 코드 작성을 시작하는 것뿐이었습니다. IDE(통합 개발 환경)를 열고 프로젝트를 로드했습니다.
TDD와 단위 테스트란 무엇인가 [번역] - 3
큰 프로젝트였어요! "단위 테스트"라는 폴더를 찾았습니다. “좋아요.” 나는 생각했다. - 실행해서 무슨 일이 일어나는지 살펴보겠습니다. 몇 분밖에 걸리지 않았고 놀랍게도 모든 테스트가 통과되었으며 모든 것이 녹색이었습니다( "녹색"은 테스트의 긍정적인 결과입니다. 코드가 예상대로 작동하고 있음을 나타냅니다. 빨간색은 "실패" 또는 실패를 나타냅니다. 그런 다음 코드가 제대로 작동하지 않는 경우가 있습니다 - 번역자 주 ). 그들은 모두 테스트를 통과했습니다. 그 순간 내 안의 회의론자가 깨어났습니다. 왜 3,000개의 단위 테스트를 한꺼번에 실시했고 긍정적인 결과를 얻었습니까? 오랫동안 연습하면서 코드에 단 하나의 네거티브 단위 테스트도 없이 프로젝트 작업을 시작한 때가 언제인지 기억나지 않습니다. 무엇을 해야 할까요? 수동으로 확인하세요! ChY는 가장 많이 드러나는 테스트는 아니지만 무작위 테스트를 하나 선택했지만 그가 확인하고 있는 내용은 즉시 분명해졌습니다. 그러나 테스트를 진행하는 동안 나는 뭔가 터무니없는 것을 발견했습니다. 테스트에는 예상 결과(어설션)와의 비교가 포함되어 있지 않았습니다! 즉, 실제로는 아무것도 확인되지 않았습니다 ! 테스트에는 특정 단계가 있었고 수행되었지만 실제 결과와 예상 결과를 비교해야 하는 테스트가 끝날 때 확인이 없었습니다. "테스트"는 아무것도 테스트하지 않았습니다. 또 다른 테스트를 열었습니다. 더 좋은 점은 결과가 포함된 비교 연산자가 주석 처리되었다는 점입니다. 훌륭하게! 이는 테스트 통과를 수행하는 좋은 방법입니다. 테스트 실패의 원인이 되는 코드를 주석 처리하면 됩니다. 나는 또 다른 테스트를 확인했고, 또 다른 테스트를 했습니다... 그들 중 누구도 아무것도 확인하지 않았습니다. 3,000번의 테스트를 거쳤지만 모두 완전히 쓸모가 없습니다. 단위 테스트 작성과 단위 테스트 및 TDD(테스트 기반 개발)를 이해하는 것에는 큰 차이가 있습니다.

단위 테스트란 무엇입니까?

TDD와 단위 테스트란 무엇인가 [번역] - 4
단위 테스트의 기본 아이디어는 코드의 가장 작은 "단위"를 테스트하는 테스트를 작성하는 것입니다. 단위 테스트는 일반적으로 애플리케이션의 소스 코드와 동일한 프로그래밍 언어로 작성됩니다. 이 코드를 테스트하기 위해 직접 생성되었습니다. 즉, 단위 테스트는 다른 코드의 정확성을 확인하는 코드입니다. 나는 이 맥락에서 "테스트"라는 단어를 상당히 자유롭게 사용합니다. 어떤 의미에서 단위 테스트는 테스트가 아니기 때문입니다. 그들은 아무것도 경험하지 않습니다. 내 말은 단위 테스트를 실행할 때 일반적으로 일부 코드가 작동하지 않는다는 사실을 발견하지 못한다는 것입니다. 테스트가 녹색으로 바뀔 때까지 코드를 변경하게 되므로 테스트를 작성하는 동안 이를 발견하게 됩니다. 예, 나중에 코드가 변경되어 테스트가 실패할 수 있습니다. 따라서 이런 의미에서 단위 테스트는 회귀 테스트입니다. 단위 테스트는 몇 가지 단계를 수행하고 소프트웨어가 올바르게 작동하는지 확인하는 일반적인 테스트와는 다릅니다. 단위 테스트를 작성하는 과정에서 코드가 예상한 대로 수행되는지 여부를 확인하고 테스트가 통과할 때까지 코드를 변경하게 됩니다.
TDD와 단위 테스트란 무엇인가 [번역] - 5
단위 테스트를 작성하고 통과하는지 확인하는 것은 어떨까요? 이런 식으로 생각하면 단위 테스트는 매우 낮은 수준의 특정 코드 모듈에 대한 일종의 절대 요구 사항으로 변합니다. 단위 테스트를 절대 사양으로 생각할 수 있습니다 . 단위 테스트는 이러한 특정 입력 집합을 사용하여 이러한 조건에서 이 코드 단위에서 얻어야 하는 출력이 있는지 확인합니다. 진정한 단위 테스트는 대부분의 프로그래밍 언어(적어도 객체 지향 언어)에서 클래스인 가장 일관성 있는 코드 단위를 식별합니다.

단위 테스트라고도 하는 것은 무엇입니까?

TDD와 단위 테스트란 무엇인가 [번역] - 6
단위 테스트는 종종 통합 테스트와 혼동됩니다. 일부 "단위 테스트"는 둘 이상의 클래스를 테스트하거나 대규모 코드 단위를 테스트합니다. 많은 개발자들은 실제로는 낮은 수준의 화이트박스 테스트를 작성하면서도 단위 테스트를 작성한다고 주장합니다. 이 사람들과 논쟁하지 마십시오. 실제로 통합 테스트를 작성하고 실제 단위 테스트는 다른 부분과 격리된 가장 작은 코드 단위를 테스트한다는 점만 알아두세요. 종종 단위 테스트라고 불리는 또 다른 것은 예상 값을 확인하지 않고 단위 테스트를 수행하는 것입니다. 즉, 실제로 아무것도 테스트하지 않는 단위 테스트입니다. 단위화 여부에 관계없이 모든 테스트에는 일종의 검증이 포함되어야 합니다. 이를 예상 결과와 비교하여 실제 결과를 확인한다고 합니다. 테스트의 통과 여부를 결정하는 것은 바로 이러한 조정입니다. 항상 통과하는 테스트는 쓸모가 없습니다. 항상 실패하는 테스트는 쓸모가 없습니다.

단위 테스트의 가치

나는 왜 단위 테스트에 열광하는가? 다른 코드에서 분리된 가장 작은 블록이 아닌 더 큰 코드 조각을 테스트하는 일반화된 테스트를 "단위 테스트"라고 부르는 것이 해로운 이유는 무엇입니까? 내 테스트 중 일부가 수신된 결과와 예상 결과를 비교하지 않는 경우 문제는 무엇입니까? 적어도 그들은 코드를 실행합니다. 나는 설명하려고 노력할 것이다.
TDD와 단위 테스트란 무엇인가 [번역] - 7
단위 테스트를 수행하는 데에는 두 가지 주요 이유가 있습니다. 첫 번째는 코드 디자인을 개선하는 것입니다. 단위 테스트는 실제로 테스트가 아니라고 말한 것을 기억하시나요? 적절한 단위 테스트를 작성하려면 가장 작은 코드 단위를 분리해야 합니다. 이러한 시도를 통해 코드 자체 구조의 문제를 발견하게 됩니다. 테스트 클래스를 분리하고 해당 종속성을 포함하지 않는 것이 매우 어려울 수 있으며 이로 인해 코드가 너무 밀접하게 결합되어 있음을 깨닫게 될 수 있습니다. 테스트하려는 핵심 기능이 여러 모듈에 걸쳐 있어 코드의 일관성이 충분하지 않다고 생각할 수도 있습니다. 단위 테스트를 작성하려고 자리에 앉았을 때 코드가 무엇을 해야 할지 전혀 모른다는 사실을 갑자기 발견할 수도 있습니다(저를 믿으세요, 그런 일이 일어납니다!). 따라서 이에 대한 단위 테스트를 작성할 수 없습니다. 물론 코드 구현에서 실제 버그를 발견할 수도 있습니다. 단위 테스트를 통해 상자 밖에서 생각하고 고려하지 않았을 수 있는 다양한 입력 세트를 테스트해야 하기 때문입니다.
TDD와 단위 테스트란 무엇인가 [번역] - 8
단위 테스트를 만들 때 "코드의 가장 작은 단위를 다른 코드와 분리하여 테스트"하는 규칙을 엄격히 준수한다면 해당 코드와 해당 모듈의 설계에서 온갖 종류의 문제를 발견하게 될 것입니다. 소프트웨어 개발 수명주기에서 단위 테스트는 테스트 활동이라기보다는 평가 활동에 가깝습니다. 단위 테스트의 두 번째 주요 목표는 소프트웨어 동작의 낮은 수준 사양 역할을 할 수 있는 자동화된 회귀 테스트 세트를 만드는 것입니다. 무슨 뜻이에요? 반죽을 치댈 때 부서지지 않아요. 이러한 관점에서 보면 단위 테스트는 테스트, 더 구체적으로는 회귀 테스트입니다. 그러나 단위 테스트의 목적은 단순히 회귀 테스트를 구축하는 것이 아닙니다. 실제로 단위 테스트에서는 회귀를 거의 포착하지 못합니다. 테스트 중인 코드 단위에 대한 변경 사항에는 거의 항상 단위 테스트 자체에 대한 변경 사항이 포함되기 때문입니다. 회귀 테스트는 코드가 "블랙 박스"로 테스트되는 더 높은 수준에서 훨씬 더 효과적입니다. 왜냐하면 이 수준에서는 코드의 내부 구조가 변경될 수 있지만 외부 동작은 동일하게 유지되기 때문입니다. 단위 테스트는 내부 구조를 차례로 확인하여 해당 구조가 변경될 때 단위 테스트가 실패하지 않도록 합니다. 사용할 수 없게 되므로 이제 변경하거나 폐기하거나 다시 작성해야 합니다. 이제 당신은 많은 베테랑 소프트웨어 개발자들보다 단위 테스트의 진정한 목적에 대해 더 많이 알고 있습니다.

테스트 주도 개발(TDD)이란 무엇입니까?

TDD와 단위 테스트란 무엇인가 [번역] - 9
소프트웨어 개발 과정에서 좋은 사양은 금만큼의 가치가 있습니다. TDD 접근 방식은 코드를 작성하기 전에 먼저 사양 역할을 할 테스트, 즉 코드가 수행해야 하는 작업을 정의하는 테스트를 작성하는 것입니다. 이는 매우 강력한 소프트웨어 개발 개념이지만 종종 잘못 사용됩니다. 일반적으로 테스트 중심 개발이란 단위 테스트를 사용하여 애플리케이션 코드 생성을 안내하는 것을 의미합니다. 그러나 실제로 이 접근 방식은 모든 수준에 적용될 수 있습니다. 그러나 이 기사에서는 애플리케이션에 단위 테스트를 사용한다고 가정합니다. TDD 접근 방식은 모든 것을 완전히 뒤집어서 코드를 먼저 작성한 다음 해당 코드를 테스트하기 위한 단위 테스트를 작성하는 대신 먼저 단위 테스트를 작성한 다음 코드를 작성하여 해당 테스트를 녹색으로 만듭니다. 이러한 방식으로 단위 테스트는 코드 개발을 "추진"합니다. 이 과정은 계속해서 반복됩니다. 코드가 수행해야 하는 작업에 대한 추가 기능을 정의하는 또 다른 테스트를 작성합니다. 그런 다음 테스트가 성공적으로 완료되도록 코드를 작성하고 수정합니다. 녹색 결과가 나오면 코드 리팩토링을 시작합니다. 즉, 코드를 더 간결하게 만들기 위해 리팩토링하거나 정리합니다. 이 프로세스 체인은 종종 "적색-녹색-리팩토링"이라고 불립니다. 먼저 단위 테스트가 실패하고(빨간색) 코드가 테스트에 적응하도록 작성되어 성공했는지 확인하고(녹색) 마지막으로 코드가 최적화되기 때문입니다( 리팩토링). .

TDD의 목표는 무엇입니까?

TDD와 단위 테스트란 무엇인가 [번역] - 10
단위 테스트와 마찬가지로 TDD(테스트 중심 개발)도 잘못 사용될 수 있습니다. 자신이 하는 일을 "TDD"라고 부르기도 쉽고, 왜 그렇게 하는지 이해하지 못한 채 연습을 따르는 것도 매우 쉽습니다. TDD의 가장 큰 가치는 품질 사양을 생성하기 위해 테스트가 수행된다는 것입니다. TDD 는 본질적으로 코딩을 작성하기 전에 자동으로 확인할 수 있는 정확한 사양을 작성하는 관행입니다. 테스트는 거짓말을 하지 않기 때문에 최고의 사양입니다. 그들은 "내가 의도한 바는 전혀 그게 아니다"라는 코드로 2주 동안 고통을 겪은 후에도 당신에게 말하지 않을 것입니다. 테스트는 올바르게 작성되면 통과하거나 실패합니다. 테스트는 특정 상황에서 어떤 일이 발생해야 하는지 명확하게 나타냅니다. 따라서 TDD의 목표는 구현을 시작하기 전에 구현해야 할 사항을 완전히 이해하는 것입니다. TDD를 시작하는데 테스트에서 무엇을 테스트해야 할지 알 수 없다면 더 많은 질문을 해야 합니다. TDD의 또 다른 중요한 역할은 코드를 보존하고 최적화하는 것입니다. 코드 유지 관리 비용이 많이 듭니다. 나는 어떤 문제를 해결하는 가장 짧은 코드를 작성하는 사람이 최고의 프로그래머라는 농담을 자주 합니다. 또는 이 문제를 해결할 필요가 없다는 것을 증명하여 코드를 완전히 제거한 사람도 있습니다. 오류 수를 줄이고 애플리케이션 유지 비용을 줄이는 올바른 방법을 찾은 사람이 바로 이 프로그래머였기 때문입니다. TDD를 사용하면 테스트를 통과하기 위한 코드만 작성하게 되므로 불필요한 코드를 작성하지 않는다는 것을 절대적으로 확신할 수 있습니다. YAGNI라는 소프트웨어 개발 원칙이 있습니다(필요하지 않음). TDD는 YAGNI를 방지합니다.

일반적인 테스트 중심 개발(TDD) 워크플로

TDD와 단위 테스트란 무엇인가 [번역] - 11
순전히 학문적인 관점에서 TDD의 의미를 이해하는 것은 어렵습니다. 이제 TDD 세션의 예를 살펴보겠습니다. 책상에 앉아서 사용자가 애플리케이션에 로그인하고 암호를 잊어버린 경우 암호를 변경할 수 있는 기능에 대한 높은 수준의 설계가 무엇인지 빠르게 스케치한다고 상상해 보십시오. 로그인 기능의 첫 번째 구현부터 시작하여 로그인 프로세스에 대한 모든 논리를 처리할 클래스를 생성하기로 결정했습니다. 즐겨 사용하는 편집기를 열고 "빈 로그인으로 인해 사용자가 로그인할 수 없습니다."라는 단위 테스트를 만듭니다. (아직 생성하지 않은) Login 클래스의 인스턴스를 먼저 생성하는 단위 테스트 코드를 작성합니다. 그런 다음 빈 사용자 이름과 비밀번호를 전달하는 Login 클래스의 메서드를 호출하는 코드를 작성합니다. 마지막으로 예상 결과에 대한 검사를 작성하여 빈 로그인을 가진 사용자가 실제로 로그인되지 않았는지 확인합니다. 테스트를 실행하려고 하는데 로그인 클래스가 없기 때문에 컴파일조차 되지 않습니다. 이 상황을 해결하고 해당 클래스의 메소드와 함께 로그인 클래스를 생성하여 로그인하고 사용자의 상태를 확인하여 로그인했는지 확인합니다. 지금까지 이 클래스의 기능과 필요한 메서드를 구현하지 않았습니다. 이 시점에서 테스트를 실행합니다. 이제 컴파일되지만 즉시 실패합니다.
TDD와 단위 테스트란 무엇인가 [번역] - 12
이제 코드로 돌아가서 테스트를 통과하는 기능을 구현합니다. 우리의 경우 이는 "사용자가 로그인되어 있지 않습니다."라는 결과를 얻어야 함을 의미합니다. 테스트를 다시 실행하면 이제 통과됩니다. 다음 테스트로 넘어가겠습니다. 이제 "유효한 사용자 이름과 비밀번호를 입력하면 사용자가 로그인됩니다."라는 테스트를 작성해야 한다고 가정해 보겠습니다. Login 클래스를 인스턴스화하고 사용자 이름과 비밀번호를 사용하여 로그인을 시도하는 단위 테스트를 작성합니다. 단위 테스트에서는 사용자가 로그인했는지 여부에 대한 질문에 로그인 클래스가 예라고 대답해야 한다는 명령문을 작성합니다. 이 새로운 테스트를 실행했는데 당연히 실패합니다. 로그인 클래스가 항상 사용자가 로그인되어 있지 않다는 결과를 반환하기 때문입니다. Login 클래스로 돌아가서 사용자가 로그인했는지 확인하는 일부 코드를 구현합니다. 이 경우, 이 모듈을 분리하는 방법을 알아내야 합니다. 현재로서는 가장 쉬운 방법은 테스트에 사용한 사용자 이름과 비밀번호를 하드코딩하고 일치하는 경우 "사용자가 로그인했습니다."라는 결과를 반환하는 것입니다. 이렇게 변경하고 두 테스트를 모두 실행하면 둘 다 통과됩니다. 마지막 단계로 넘어가겠습니다. 생성된 코드를 살펴보고 이를 재구성하고 단순화하는 방법을 찾습니다. 따라서 TDD 알고리즘은 다음과 같습니다.
  1. 테스트를 만들었습니다.
  2. 우리는 이 테스트를 위한 코드를 작성했습니다.
  3. 코드를 리팩토링했습니다.

결론

TDD와 단위 테스트란 무엇인가 [번역] - 13
이것이 제가 이 단계에서 단위 테스트와 TDD에 대해 말하고 싶었던 전부입니다. 실제로 코드가 매우 복잡하고 혼란스러울 수 있기 때문에 코드 모듈을 분리하는 데에는 많은 어려움이 있습니다. 완전히 격리된 클래스는 거의 없습니다. 대신 종속성이 있고 해당 종속성이 종속성 등이 있습니다. 이러한 상황을 처리하기 위해 TDD 베테랑은 종속 모듈의 개체를 대체하여 개별 클래스를 격리하는 데 도움이 되는 모의 개체를 사용합니다. 이 기사는 단위 테스트 및 TDD에 대한 개요이자 다소 단순화된 소개일 뿐이며, 더미 모듈 및 기타 TDD 기술에 대해서는 자세히 다루지 않습니다. 아이디어는 여러분이 현재 알고 있는 TDD 및 단위 테스트의 기본 개념과 원칙을 제공하는 것입니다. 원본 - https://simpleprogrammer.com/2017/01/30/tdd-unit-testing/
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION