YUI 테스트와 함께 효과적인 자바 스크립트 단위 테스트를 작성
년 | 10시 38분에서 2009년 1월 5일 니콜라스 C. Zakas하여 오전 개발 | 6 개의 댓글2,008 동안 자바 스크립트 개발에서 아래 - - 레이더 움직임 가장 큰 중 하나는 단위 테스트에 관심 reemergence했습니다. YUI 테스트 , YUI의 단위 테스트 프레임 워크는 2 월 및 기타 라이브러리 GA 상태에 도달하거나 자신의 유닛 테스트 프레임 워크를 도입하거나 시작 기존 홍보. 따라서, 자바 스크립트 단위 테스트의 생성에 관한 더 많은 문서가 있습니다. 간단히 자바 스크립트 단위 테스트를하는 것이지만, 충분하지 않다, 당신의 검사 결과가 잘못 작성하는 경우, 그들은 잃어버린 시간을 많이 발생할 수 있습니다. 효과적인 자바 스크립트 단위 테스트를 작성하는 배우는 것은 미래에 시간과 두통을 저장합니다.
당신은 무엇을 시험입니까?
효과적인 유닛 테스트를 작성하는 핵심 단어는 이해하기는 "장치를." 테스트 조건에서 단위 코드의 다른 조각과 독립적 테스트 수있는 코드의 절연 부분입니다. 자바 스크립트와 같은 객체 지향 언어에서는 각 방법을 단위로 간주됩니다. 적절한 OO 설계는 일반적으로 하나의 목적을 제공하므로 테스트하기 쉽고 멋지게 캡슐 방법을 알아볼 수 있습니다.
전통적인 단위 테스트는 인터페이스의 구현을 테스트하도록 설계, 개인 방법을 명시적으로 검사하지 않아도됩니다. 이것은 블랙 박스 테스트라고합니다. 아이디어는 그들이 완전히 기본 구현 불가 지론이기 때문에 당신이 인터페이스의 구현을 교환할 수 있으며 단위 테스트 모두 통과 여전히 것입니다. 모든 테스트는 충족되어야합니다 제약의 집합입니다 알고, 그들은 이러한 제약 조건이 충족하는 방법에 상관 안해.
쓰기 테스트
내 이야기에서 말했듯이, 단위 테스트는 입력 및 출력을 테스트해야합니다. 입력이 메서드 인자 또는 메서드가 제대로 작동하려면 달려 것을 전 세계에 액세스할 변수의 변화라는하실 수 있습니다. 출력은 리턴 값, 변수의 상태 변화, 심지어 들어가는 오류가있을 수 있습니다. 각각의 입력 - 출력 설정을 위해, 하나의 단위 테스트가 있어야합니다. 각 테스트는 명시적으로 "이 입력 주어진, 내가이 출력을 기대하고 있습니다."상태해야 그 진술의 모든 편차는 실패 테스트입니다.
각 시험은 가능한 단순하게 오직 하나의 입력 - 출력 설정을 테스트해야한다 하나의 테스트로 세트를 결합하면 단위 테스트의 효과를 최소화합니다. 예를 들어, 함수의 다음 테스트라고 생각 trim() :
var에 testCase = 새로운 YAHOO.tool.TestCase ({ 이름 : ") (가장자리는 테스트" testTrim : 함수 () { var에 result1 = 트림 ( "안녕하세요"); YAHOO.util.Assert.areEqual ( "안녕하세요", result1, "공백을 선도가 분해까지해야합니다."); var에 result2 = 트림 ( "안녕하세요"); YAHOO.util.Assert.areEqual ( "안녕하세요", result2, "공백을 후행을 벗기고해야합니다."); } });
여기 testTrim() : 시험 케이스의 방법은 실제로 두 개의 서로 다른 입력 - 출력 세트를 테스트합니다
- 입력 문자열은 공백을 선도했다; 반환 값은 선행 공백이 없습니다.
- 입력 문자열은 공백을 후행도있다; 반환 값은에는 공백을 후행있다.
문제는 첫 번째 입력 - 출력 설정이 올바른 결과를 생성하지 않을 경우이 두 집합은 아직 그대로 서로 아무런 관계가 없다는 것을, 두 번째 설정은 테스트되지 않습니다이다. 이것은 하나의 실패 마스크 또 다른 상황이다. 그것은 두 개의 테스트로 이러한 입력 - 출력 세트를 분리하는 더 효과적입니다
var에 testCase = 새로운 YAHOO.tool.TestCase ({ 이름 : ") (가장자리는 테스트" testTrimWithLeadingWhiteSpace : 함수 () { var에 결과 = 트림 ( "안녕하세요"); YAHOO.util.Assert.areEqual ( "안녕하세요", 결과, "공백을 선도가 분해까지해야합니다."); } testTrimWithTrailingWhiteSpace : 함수 () { var에 결과 = 트림 ( "안녕하세요"); YAHOO.util.Assert.areEqual ( "안녕하세요", 결과, "공백을 후행을 벗기고해야합니다."); } });
이 코드는 올바르게 검사 trim() 그들이 별도의 유지, 함수의 입력 - 출력 설정합니다.
테스트중인 코드가 올바르게 작동하는 경우와 같은 단위 테스트는 항상 기록됩니다. 좋은 소프트웨어 설계는 결과가 각각의 경우에 있어야 정확하게 알고있는 이러한 입력 - 출력을 매핑하는 것은 미리 설정이 포함됩니다. 이러한 방법으로 단위 테스트는 실제 코드 이외에 기술 요구 사항 문서의 형식이된다.
효과적인 주장
단위 테스트를 작성하는 가장 중요한 부분 중 하나는 적절한 주장 정의입니다. 각각의 주장 만난하지 않을 경우, 기능이 적절하게 행동하지 않음을 나타냅니다, 조건을 지정합니다. 올바르게 코드 출력을 테스트하기 위해서만 필요한 많은 주장으로 사용하는 것이 중요합니다. 부족 거짓 패스로 이어질 수있을 때 너무 많은 주장은 거짓 오류가 발생할 수 있습니다.
그 필요의 모든이기 때문에 이전 예제에서, 각 시험은 하나의 주장이 포함되어 있습니다. 저는 정확하게 반환 그래서 내가 그 시험을 위해 특별히하는 그 가치를 알아. 테스트는 모두 매우 간단 볼 수 있지만, 그들은 작업을 수행하십시오. 다시, 좋은 테스트를 할 주장의 수에 대한 아무런 규칙이없는, 당신이 주어진 입력에 대한 코드의 모든 예상 출력을 테스트하고 있는지 확인하십시오.
테스트 실패가 더 일관된하기 위해서, 각 주장과 실패 메시지를 포함해야합니다. YUI 테스트에서, 이것은 항상 어떤 주장 메서드의 마지막 인자이다. 실패 메시지는 왜 그런 일이 있어야 뭘하지 알려야합니다. 몇 가지 예제 코드를 보자 :
/ / 잘못된 오류 메시지가 YAHOO.util.Assert.areEqual ( "안녕하세요", 결과는 "결과는 '안녕하세요 세계 아니라"); / / 좋은 실패 메시지 YAHOO.util.Assert.areEqual ( "안녕하세요", 결과, "공백을 선도가 분해까지해야합니다.");
나쁜 좋은 고장 메시지의 차이를주의 : 나쁜 일이 그리고 좋은 예상 있었는지 알려주 무엇을 알려줍니다. 귀하의 테스트를 실행하면, 실패는 이미 예기치 못한 일이 일어난 의미하므로 단순히 예기치 못한 무슨 일이 반복하실 필요가 없습니다. 그것이 귀하의 요구 사항의 정확한 표현이기 때문에 그 일이어야 어떤 건지가 더 도움. 이 접근법을 복용함으로써, 실패는 이상 돌아가서 평가할 수 이루어지지 않은 요구 사항의 목록이 끝나게.
DOM 작업
자바 스크립트는 자주 환경, DOM에 관계를 가지고 다른 언어 사용자에게 고유합니다. 전체 환경을 완벽하게 실행할 수있는 방법을 순서대로 설치를해야하기 때문에 DOM과 상호 작용하는 방법은 크게 유닛 테스트 어렵습니다. 더 복잡한 문제는 마우스 클릭과 같은 사용자 동작에 의해 실행되는 자바 스크립트의 경향이다. YUI 테스트 DOM 상호 작용에 의존 방법에 대한 테스트를 만드는 돕기 위해 이벤트 시뮬레이션을 제공하지만, 이것은 기능 테스트의 영역으로 국경을 넘을 시작합니다.
로 단위 테스트에 반대 기능 테스트는, 사용자의 제품에 대한 사용 경험보다는 코드를 입력 - 출력 세트를 테스트하도록 설계되었습니다. 자신의 사용자 인터페이스가 사용자 상호 작용으로 인해 특정 방법으로 응답되는 테스트하고자 찾으면, 당신은 진짜로 오히려 단위 테스트보다 몇 가지 기능 테스트를 쓰고 싶어요. YUI 시험 몇 가지 기본적인 기능 테스트를 작성하는 데 사용하지만, 같은 테스트를위한 가장 인기있는 (그리고 매우 좋은) 도구입니다 수 있습니다 셀레늄 .
무언가가 단위 테스트 있는지 확인하는 가장 좋은 방법은 그것이 그것이 존재하는 실제 테스트를 설계하는 코드 작성 전에 수 있는지 문의하는 것입니다. 단위 테스트는 테스트 주도 개발의 일환으로, 실제 개발 노력을 안내하는 방법으로 실제 코드를 먼저 작성해야됩니다. 그들은 따라서 사용자 상호 작용에 대한 응답으로 변경하는 방법 사용자 인터페이스에 묶여하고 있기 때문에 기능성 테스트, 반면에 미리 존재할 수 없습니다.
테스트 계층 구조에
YUI 테스트, 그냥 다른 단위 테스트 프레임 워크와 같은 테스트 케이스 및 테스트 스위트의 계층 구조를 지원합니다. 각각의 테스트 스위트는 다른 테스트 스위트뿐만 아니라 테스트 케이스를 포함할 수 있으며, 단 테스트 케이스는 (방법이 단어는 "test"로 시작하는) 실제 테스트를 포함할 수 있습니다. 테스트 계층 구조를 구성하는 가장 좋은 방법은 매우 간단한 패턴을 따라하는 것입니다 :
- 테스트할가는 모든 객체에 대해 하나의 테스트 스위트를 만듭니다.
- 당신이 테스트 및 객체의 테스트 스위트에 추가거야 개체의 모든 메서드에 대해 하나의 테스트 케이스를 생성합니다.
- 각각의 입력 - 출력 설정에 대한 각 테스트 케이스에서 한 테스트를 만듭니다.
이러한 방법으로 테스트 계층 구조는 테스트 코드를 거울하고 새로운 테스트가 생성되어야 어디 인지만 알아 내면 쉽게.
당신의 검사를 실행합니다!
아마도 단위 테스트의 가장 중요한 부분은 자주 테스트를 실행하는 것입니다. 정기적으로 완료되면 시험에만 유효합니다. 최소한, 당신은 소스 제어 변경 사항 확인하기 전에 단위 테스트를 실행해야합니다. 최적, 당신은 또한 그들이 소스 제어하기 위해 최선을 다하고 있었 후 변경 사항을 확인하기 위해 정기적으로 자동으로 테스트를 실행하는 거예요. 이것은 단위 테스트의 가장 큰 혜택을거야 방법입니다 : 빠른 통찰력을, 그리고 regressions의 희망 방지.
자세한 내용은
- YUI 테스트
- YUI 극장 : YUI 테스트와 테스트 기반 개발, 니콜라스 C. Zakas로
- FireUnit
- YUI 시험 FireUnit 확장
- JavaScript는 너무 코드입니다 : 그것을 테스트!
- 자바 스크립트 단위 테스트 격리
공유 및 확장 : del.icio.us로 스크랩 | 디그 그것! | 레딧!
6 개의 댓글
죄송합니다, 코멘트 양식이 시간에 문을 닫습니다.


정기적으로 자동 실행 YUI 테스트 있습니까? 그렇다면하면이 작업을 수행하는 방법에 대한 정보를 당신을 공유할 수 있습니까? 나는 특히 당신이 산란 처리하는 방법에 관심 브라우저를 닫으면 빌드 자동화 동안의 테스트를 실행하는 데 사용되는 프로세스, 또한 어떻게 빌드에 대한 테스트 결과를 수집하고 집계. 해요
사이먼에 의해 코멘트 - 2009년 1월 5일 #
제가 thusfar 봤어요 가장 좋은 방법은 테스트를 위해 브라우저 라이프 사이클을 관리하는 셀레늄을 사용하는 것입니다. 당신은 정기적으로 실행하고 결과를 페이지를 모니터로 설정할 수 있습니다.
에 의해 코멘트 니콜라스 C. Zakas - 2009년 1월 7일 #
우선,이 훌륭한 블로그 항목을 작성 주셔서 감사합니다. 필자의 경우는 다음에 대해 언급하고 싶습니다 :
개인 단위로 클래스의 생각 선호합니다. 클래스는 좀 행동을 제공하며, 내가 테스트를 통해 그 행동을 설명하고 싶습니다. 메소드 수준에서가는 것은 우리가 어떤 의미에서 구현로 시추하고있는 것.
당신은 상태 기반 단위 테스트와 같은 단위 테스트의 스타일을 자격이있다면 내가 선호하는 것입니다. 상호 작용을 기반으로 테스트 믿는 단위 테스트의 다른 학교가있다. 어디의 반환 값을 기준으로 출력, 변수의 상태 변화, 또는 폐기 오류에 대해 많이하지 않습니다. 초점은의 협력자와 상호 작용 (메서드 호출)에 있습니다.
그들은 xUnit 대회를 깨진 것 같습니다. xUnit 실패 메시지에 항상 첫 번째 인수입니다.
당신이 주장 :
제가 두 번째 예제는 첫 번째보다이지만, 내 생각엔 당신과 함께 동의하는 동안 두 번째 경우에 실패 메시지가 중복됩니다. 당신은 아래의 전체 테스트 방법을 보면,
testTrimWithLeadingWhiteSpace: function(){var result = trim(" Hello world");
YAHOO.util.Assert.areEqual("Hello world", result, "Leading white space should be stripped.");
}
메소드 이름은 이미 최고의 흰색 공간이 줄어들거나 밖으로 벗기고되어야한다는 것을 알려줍니다. 이 특정한 경우에 어떤 오류 메시지를주지 못할 것이다. 그 회사의 최상의 하나를 제공하는 경우 "선두 공백이 벗겨지고 아니"라고, 그럼 난 오히려 당신의 실패 메시지를 선호
이것은 항상 사실이 아니다. 어떤 코드를 작성하기 전에 많은 사건에서 당신은 실제로 기능 또는 수용 테스트를 작성할 수 있습니다. 수락 테스트 기반 개발을 참조하십시오
이게 중요한 이유는? 저는 이것이 도움이 될 방법을 표시되지 않는 이유는 무엇입니까?
차라리 내 생산 코드에서 중요한 기관마다 테스트 클래스를 작성하고 행동 클래스 만족을 당 하나의 테스트 메소드를 작성합니다. 때로는 한 가지 방법은 때로는 없음 이상 한 테스트를 할 수도 있습니다. 나는 모든 방법을 하나의 검사를해야한다는 지침을 만들 수 있는지 확실하지 않습니다.
에 의해 코멘트 Naresh 자이나교 - 2009년 1월 11일 #
안녕 Naresh,
당신의 통찰력의 의견을 주셔서 감사합니다. 사실, 거기에 테스트 방법론을 둘러싼 의견의 많은 학교가 있으며, 당신이 그들 중 몇 감동했습니다. 그냥 포인트 몇 명확히하고 싶습니다.
주장 오류 메시지가 뭘해야하는 일이 중복되지 않습니다의 성명을 만들기, 그냥 무슨 일이 일어 났는지 설명의. 테스트 이름과 실패 메시지가 유사하고, 시험이 너무 단순하기 때문에이 경우에 수 있으며, 테스트에 포함된 주장의 숫자가있는 경우 그러나, 그들은 매우 다를 수 있습니다.
테스트 스위트 및 테스트 케이스를 설정을위한 나의 권고는 사람들이 시작하는 것입니다. 나는 모든 방법이 당신이 가진 각 입력 - 출력 설정을 탐험 테스트를 포함하는 테스트 케이스를 가지고 있어야한다고 말하고, 모든 방법을 한 검사를해야한다고 말하는 게 아니에요. 요점은 논리적인 구조를 가지고 있는지 직접 프로그래밍하고있는 개체에 매핑됩니다.
귀하의 의견 주셔서 감사합니다, 나는이 지점의 일부를 명확히 바랍니다.
에 의해 코멘트 니콜라스 C. Zakas - 2009년 1월 12일 #
안녕하세요 니콜라스,
나는 최근에 우리가 지원을 상속하고 이미 일부 YUI 라이브러리 2를 사용하는 기존 포털에서 JS 코드의 단위 테스트 yuitest를 탐험 시작했다. 밖으로 넣어 모든 동영상과 블로그를 주셔서 감사합니다.
1. yuitest의 예제 / 샘플이 다른 상황처럼 더 실용 / 현실적인 시나리오에서가 사용되고 있으며, yuitest 사이트에서 광범위한 DOM usgae 등 예제는 매우 간단한 있습니다.
2. 페이지의 콘텐츠는 일반적으로 동적이며 일부 사전 조건을 기반으로하기 때문에 물어 보는 이유가 .. 컨테이너 요소는 동일하지만, 내용을 변경합니다. 그것은 각각의 시나리오에 대해 서로 다른 htmls 밖으로 스텁하는 것이 좋습니다?
3. DOM을 많이 사용하는 일부 스크립트가있을 수 있습니다. 원본 HTML과 같은 모든 HTML은 이런 경우에서 stubbed한다.
kaanta에 의해 코멘트 - 2010년 12월 8일 #
안녕 Kaanta,
제가 공유할 수 있습니다 예제의 모든 문서에서 현재 또는 YUI 다운로드 (ZIP 파일에서 테스트 디렉토리를 체크)의 일부로 포함되어 있습니다.
이 페이지에 상호 작용을 많이 테스트하는 경우, 그럼 일반적으로 실제 페이지에 YUI 테스트를로드하고 거기에 테스트를 실행하는 것이 좋습니다. 그런식으로, 당신은 작업 상황에 대한 페이지의 특정 조각을 stubbing에 대해 걱정할 필요가 없습니다.
에 의해 코멘트 니콜라스 C. Zakas - 2010년 12월 8일 #