[java] 왜 테스트를 위해 JUnit을 사용합니까?

어쩌면 내 질문은 초보자 질문 일지 모르지만 내가 사용할 상황을 실제로 이해할 수는 없습니다. ?

간단한 응용 프로그램을 작성하든 더 큰 응용 프로그램을 작성하든 System.out진술을 사용하여 테스트하고 솔기가 나옵니다.

JUnit을 사용하여 테스트 클래스를 작성하고 왜 동일한 메소드를 호출 해야하는 경우 프로젝트에서 불필요한 폴더를 작성하고 리턴하는지 확인한 다음 모든 것에 주석을 달 때 오버 헤드가 발생합니까?

왜 클래스를 작성하고 한 번에 System.out테스트하지만 테스트 클래스를 작성하지 않습니까?

추신. 나는 방금 배우고있는 큰 프로젝트에서 일한 적이 없다.

그래서 목적은 무엇입니까?



답변

그것은 테스트가 아니라 “수동으로 출력을 보는 것”(비즈에서 LMAO로 알려짐)입니다. 보다 공식적으로는 “정상 출력을 수동으로 찾는 것”(LMFAO)이라고합니다. (아래 참고 참조)

코드를 변경할 때마다 해당 변경의 영향을받는 모든 코드에 대해 앱과 LMFAO를 실행해야합니다. 소규모 프로젝트에서도 문제가 발생하기 쉽고 오류가 발생하기 쉽습니다.

이제 코드를 변경할 때마다 최대 50k, 250k, 1m LOC 이상 및 LMFAO로 확장 할 수 있습니다. 그것은 불쾌 할뿐만 아니라 불가능합니다 : 입력, 출력, 플래그, 조건의 조합을 확장했으며 가능한 모든 분기를 수행하기가 어렵습니다.

더 나쁜 것은 LMFAO는 웹 앱 페이지에서 페이지를 방문하고, 보고서를 실행하고, 수십 개의 파일과 머신에 수백만 개의 로그 라인을 쏟아 붓고, 생성 및 전달 된 이메일을 읽고, 문자 메시지를 확인하고, 로봇의 경로를 확인하고, 병을 채우는 것을 의미 할 수 있습니다. 소다, 수백 개의 웹 서비스에서 데이터를 집계하고 금융 거래의 감사 내역을 확인하면 아이디어를 얻을 수 있습니다. “출력”은 몇 줄의 텍스트를 의미하지 않으며 “출력”은 전체 시스템 동작을 의미합니다.

마지막으로, 단위 및 동작 테스트 시스템 동작을 정의 합니다. 지속적인 통합 서버에서 테스트를 실행하고 정확성을 검사 할 수 있습니다. 물론 그렇습니다 System.out. 그러나 CI 서버는 그 중 하나가 잘못되었는지 알지 못합니다. 그렇지 않은 경우 단위 테스트이므로 프레임 워크를 사용할 수도 있습니다.

우리가 아무리 잘 생각하더라도 인간은 단위 테스트 프레임 워크 나 CI 서버가 아닙니다.


참고 : LMAO 테스트 중이지만 매우 제한적입니다. 전체 프로젝트에서 또는 프로세스의 일부로 의미있는 방식으로 반복 할 수 없습니다. REPL에서 점진적으로 개발하는 것과 유사하지만 이러한 증분 테스트를 공식화하지는 않습니다.


답변

우리는 프로그램 행동의 정확성을 검증하기위한 테스트를 작성합니다.

사용자의 눈을 사용하여 출력 명령문의 내용을 검사하여 프로그램 동작의 정확성을 확인하는 것은 수동 또는보다 구체적으로 시각적 프로세스입니다.

당신은 그것을 주장 할 수 있습니다

육안 검사가 작동 합니다.이 시나리오에서 코드가 의도 한대로 작동하는지 확인하고 코드가 올바른지 확인하면 좋습니다.

우선 코드가 올바르게 작동하는지에 관심이 있다는 것이 좋습니다. 좋은 일입니다. 당신은 곡선보다 앞서 있습니다! 슬프게도이 방법에는 문제가 있습니다.

육안 검사의 첫 번째 문제는 코드의 정확성을 다시 확인할 수 없다는 점에서 용접 사고가 심하다는 것입니다.

두 번째 문제는 사용 된 한 쌍의 눈이 눈 소유자의 뇌와 밀접하게 연결되어 있다는 것입니다. 코드 작성자가 육안 검사 프로세스에 사용 된 눈을 소유하는 경우 정확성을 검증하는 프로세스는 육안 검사자의 뇌에 내재 된 프로그램에 대한 지식에 의존합니다.

새로운 코 쌍이 들어 와서 코더의 두뇌와 제휴하지 않기 때문에 코드의 정확성을 검증하는 것은 어렵습니다. 두 번째 눈의 소유자는 문제의 코드를 완전히 이해하기 위해 코드의 원래 작성자와 대화 해야합니다 . 지식을 공유하는 수단으로서의 대화는 믿을 수 없을 정도로 악명 높습니다. 원래 코더를 새 쌍 눈에 사용할 수없는 경우 약점입니다. 이 경우 새로운 눈 쌍은 원래 코드를 읽어야합니다.

단위 테스트에서 다루지 않는 다른 사람의 코드를 읽는 것은 단위 테스트와 관련된 코드를 읽는 것보다 어렵습니다. 다른 사람의 코드를 읽는 것이 가장 까다로운 작업이지만 최악의 경우 소프트웨어 엔지니어링에서 가장 터무니없는 작업입니다. 구인 광고를 할 때 고용주가 프로젝트가 그린 필드 (또는 새로운) 프로젝트임을 강조하는 이유가 있습니다. 코드를 처음부터 작성하는 것이 기존 코드를 수정하는 것보다 쉬우므로 광고 된 작업이 잠재적 인 직원에게 더 매력적으로 보입니다.

단위 테스트를 통해 코드를 구성 요소 부분으로 나눕니다. 그런 다음 각 구성 요소에 대해 프로그램의 작동 방식을 알려주는 스톨을 설정했습니다 . 각 단위 테스트는 특정 시나리오에서 프로그램의 해당 부분이 어떻게 작동해야하는지에 대한 이야기를 제공합니다. 각 단위 테스트는 클라이언트 코드의 관점에서 수행되어야하는 작업을 설명하는 계약의 조항과 같습니다.

이것은 새로운 쌍의 눈이 문제의 코드에 대한 두 가지 가닥의 라이브 문서 와 정확한 문서를 가지고 있음을 의미합니다 .

먼저 코드 자체, 구현, 코드 수행 방식이 있습니다 . 둘째, 그들은 원래의 코더가이 코드 가 어떻게 행동 해야하는지에 대한 이야기를하는 공식적인 진술서에 기술 된 모든 지식을 가지고 있습니다 .

단위 테스트는 원래 작성자가 수업을 구현할 때 보유한 지식을 캡처하고 공식적으로 설명합니다. 클라이언트가 사용할 때 해당 클래스의 작동 방식에 대한 설명을 제공합니다.

쓸모없는 단위 테스트를 작성할 수 있고, 문제가되는 모든 코드를 다루지 않고, 오래되거나 오래되지 않은 등의 작업을 수행 할 수 있기 때문에이 작업의 유용성에 의문을 갖는 것이 맞습니다. 단위 테스트가 런타임에 코드의 출력문을 시각적으로 검사하는 지식이 풍부하고 양심적 인 저자의 프로세스를 모방 할뿐만 아니라 개선 할 수 있도록하려면 어떻게해야합니까? 먼저 단위 테스트를 작성한 다음 테스트를 통과하는 코드를 작성하십시오. 작업이 끝나면 컴퓨터가 테스트를 실행하도록하고, 작업에 가장 적합한 반복 작업을 수행하는 데 빠릅니다.

테스트 할 코드를 터치 할 때마다 테스트 품질을 검토하고 각 빌드에 대해 테스트를 실행하십시오. 테스트가 실패하면 즉시 수정하십시오.

테스트 빌드 프로세스를 자동화하여 프로젝트 빌드를 수행 할 때마다 테스트가 실행되도록합니다. 또한 테스트에서 다루고 실행하는 코드 비율을 자세히 설명하는 코드 적용 보고서 생성을 자동화합니다. 우리는 높은 비율을 위해 노력합니다. 일부 회사는 코드 변경 사항을 설명하기 위해 작성된 단위 테스트가 충분하지 않은 경우 코드 변경 사항을 소스 코드 제어에 체크인하지 못하게합니다. 일반적으로 두 번째 눈 쌍은 변경 사항의 작성자와 함께 코드 변경 사항을 검토합니다. 검토자는 변경 사항을 검토하여 변경 사항을 이해하고 테스트에 충분히 포함되도록합니다. 검토 과정은 수동이며 그러나 테스트 (단위 및 통합 테스트 및 사용자 승인 테스트)가이 수동 검토 프로세스를 통과하면 자동 빌드 프로세스의 일부가됩니다. 변경 사항이 체크인 될 때마다 실행됩니다. A 서버는 빌드 프로세스의 일부로이 작업을 수행합니다.

자동으로 실행되는 테스트는 코드 동작의 무결성을 유지하며 향후 코드베이스 변경으로 인해 코드손상 되는 것을 방지합니다 .

마지막으로, 테스트를 제공하면 변경 사항이 기존 테스트를 중단하지 않는다는 점에서 큰 코드를 안전하게 개선 할 수 있으므로 코드 를 적극적으로 리팩터링 할 수 있습니다.

테스트 주도 개발에 대한주의 사항이 있으며 테스트 가능하게 만들기 위해 코드를 작성해야한다는 것입니다. 인터페이스에 코딩하고 협업 객체를 인스턴스화하기 위해 Dependency Injection과 같은 기술을 사용합니다. TDD를 잘 설명 하는 Kent Beck 의 작품을 확인하십시오 . 조회 인터페이스를 코딩 및 연구


답변

System.out과 같은 것을 사용하여 테스트 할 때는 가능한 유스 케이스의 작은 서브 세트 만 테스트합니다. 거의 무한한 양의 서로 다른 입력을 받아 들일 수있는 시스템을 다룰 때는 그리 철저하지 않습니다.

단위 테스트는 매우 다양하고 다양한 데이터 입력 세트를 사용하여 애플리케이션에서 테스트를 빠르게 실행할 수 있도록 설계되었습니다. 또한 최상의 단위 테스트는 유효한 것으로 간주되는 것의 가장자리에있는 데이터 입력과 같은 경계 사례도 설명합니다.

인간이 이러한 모든 입력을 테스트하는 데 몇 주가 걸리고 기계에는 몇 분이 걸릴 수 있습니다.

이것을 다음과 같이 생각하십시오. 또한 정적 일 것을 “테스트”하지 않습니다. 응용 프로그램이 계속 변경 될 가능성이 높습니다. 따라서 이러한 단위 테스트는 컴파일 또는 배포주기의 다른 지점에서 실행되도록 설계되었습니다. 아마도 가장 큰 장점은 다음과 같습니다.

코드에서 문제가 발생하면 배포 후가 아니라 QA 테스터가 버그를 잡을 때가 아니라 고객이 취소 한 시점이 아니라 지금 당장 알게 될 것입니다. 문제가되는 코드의 일부를 손상시킨 것이 마지막 컴파일 이후에 발생했을 가능성이 높기 때문에 글리치를 즉시 수정할 가능성이 더 높습니다. 따라서 문제를 해결하는 데 필요한 조사 작업의 양이 크게 줄어 듭니다.


답변

다른 System.out이 할 수없는 것을 추가했습니다.

  • 각 테스트 사례를 독립적으로 만듭니다 (중요)

    JUnit은이를 수행 할 수 있습니다. 새로운 테스트 케이스 인스턴스가 작성되고 @Before호출 될 때마다 .

  • 소스와 테스트 코드 분리

    JUnit이 할 수 있습니다.

  • CI와 통합

    JUnit은 Ant와 Maven으로 할 수 있습니다.

  • 테스트 케이스를 쉽게 정리하고 결합

    JUnit은 @Ignore스위트를 수행 하고 테스트 할 수 있습니다 .

  • 확인하기 쉬운 결과

    JUnit은 많은 Assert 메소드를 제공합니다 ( assertEquals, assertSame…)

  • 모의와 스텁은 테스트 모듈에 집중하게합니다.

    JUnit은 다음을 수행 할 수 있습니다. 모의 및 스터브를 사용하면 올바른 고정물을 설정하고 테스트 모듈 논리에 중점을 둡니다.


답변

단위 테스트는 코드가 의도 한대로 작동하는지 확인합니다. 또한 버그를 수정하기 위해 새로운 기능을 구축하기 위해 나중에 코드를 변경해야하는 경우 코드가 의도 한대로 작동하도록하는 데 매우 유용합니다. 코드의 테스트 범위가 높으면 많은 수동 테스트를 수행하지 않고도 기능을 계속 개발할 수 있습니다.

수동 방법 System.out은 훌륭하지만 최선의 방법 은 아닙니다. 실제로는 요구 사항이 계속 변하고 대부분 기존 함수 및 클래스에 대해 많은 수정 작업을 수행합니다. 따라서… 이미 작성된 코드를 테스트 할 때마다는 아닙니다.

JUnit에는 다음과 같은 고급 기능이 있습니다.

주장 진술

JUnit은 특정 조건을 테스트하는 메소드를 제공합니다. 이러한 메소드는 일반적으로 어설 션으로 시작하며 오류 메시지, 예상 및 실제 결과를 지정할 수 있습니다.

이 방법 중 일부는

  1. fail([message])-시험 실패. 코드의 특정 부분에 도달하지 않았는지 확인하는 데 사용될 수 있습니다. 또는 테스트 코드가 구현되기 전에 테스트에 실패했습니다.
  2. assertTrue(true)/ assertTrue(false)-항상 참 / 거짓입니다. 테스트가 아직 구현되지 않은 경우 테스트 결과를 미리 정의하는 데 사용할 수 있습니다.
  3. assertTrue([message,] condition)-부울 condition이 참 인지 확인 합니다.
  4. assertEquals([message,] expected, actual)equals구현 된 경우 방법 에 따라 , 그렇지 않으면 ==참조 비교를 사용하여 두 값이 같은지 테스트합니다 . 참고 : 배열의 경우 내용이 아닌 확인 된 참조로 사용 assertArrayEquals([message,] expected, actual)됩니다.
  5. assertEquals([message,] expected, actual, delta) -두 개의 float 또는 double 값이 서로 일정한 거리에 있는지 테스트합니다. delta .
  6. assertNull([message,] object) -객체가 null인지 확인

등등. 모든 예제는 전체 Javadoc을 참조 하십시오 .

스위트

테스트 스위트를 사용하면 여러 테스트 클래스를 단일 단위로 결합 하여 한 번에 모두 실행할 수 있습니다. 간단한 예는 테스트 클래스 결합 MyClassTestMySecondClassTest하나 개의 스위트로 불리는 AllTests:

import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;

@RunWith(Suite.class)
@SuiteClasses({ MyClassTest.class, MySecondClassTest.class })
public class AllTests { } 


답변

JUnit의 주요 장점은 수동으로 출력물을 확인하지 않고 자동화한다는 것입니다. 작성하는 각 테스트는 시스템에 유지됩니다. 즉, 예기치 않은 부작용이있는 변경을 수행하면 각 변경 후 모든 것을 수동으로 테스트해야한다는 것을 기억하지 않고 테스트에서 실패하고 실패합니다.


답변

JUnit은 Java Programming Language의 단위 테스트 프레임 워크입니다. 테스트 중심 개발에서 중요하며 xUnit이라고 통칭하는 단위 테스트 프레임 워크 제품군 중 하나입니다.

JUnit은 먼저 테스트 한 다음 구현할 수있는 코드 조각에 대한 테스트 데이터를 설정하는 데 중점을 둔 “첫 번째 테스트 및 코딩”이라는 아이디어를 장려합니다. 이 접근법은 “약간 테스트, 약간 코딩, 약간 테스트, 약간 코딩 …”과 같이 프로그래머의 생산성과 프로그램 코드의 안정성을 높여 프로그래머의 스트레스와 디버깅에 소요되는 시간을 줄입니다.

특징 JUnit은 테스트 작성 및 실행에 사용되는 오픈 소스 프레임 워크입니다.

테스트 방법을 식별하기위한 주석을 제공합니다.

예상 결과를 테스트하기위한 어설 션을 제공합니다.

테스트 실행을위한 테스트 러너를 제공합니다.

JUnit 테스트를 통해 코드를 더 빨리 작성할 수있어 품질 향상

JUnit은 우아하게 간단합니다. 덜 복잡하고 시간이 덜 걸립니다.

JUnit 테스트는 자동으로 실행될 수 있으며 자체 결과를 확인하고 즉각적인 피드백을 제공합니다. 테스트 결과 보고서를 수동으로 정리할 필요가 없습니다.

JUnit 테스트는 테스트 케이스 및 기타 테스트 스위트를 포함하는 테스트 스위트로 구성 될 수 있습니다.

Junit은 테스트가 제대로 진행되면 녹색으로 표시되고 테스트에 실패하면 빨간색으로 바뀝니다.