찾다
웹 프론트엔드CSS 튜토리얼반응 통합 테스트 : 커버리지가 커지고 테스트가 적습니다

반응 통합 테스트 : 커버리지가 커지고 테스트가 적습니다

React로 구축 된 웹 사이트와 같은 대화 형 웹 사이트의 경우 통합 테스트가 당연한 선택입니다. 엔드 투 엔드 테스트의 추가 오버 헤드없이 사용자가 응용 프로그램과 상호 작용하는 방법을 검증합니다.

이 기사는 간단한 웹 사이트로 시작하고 단위 테스트 및 통합 테스트를 사용하여 동작을 확인하고 통합 테스트가 적은 코드 라인으로 더 큰 가치를 달성 할 수있는 방법을 보여줍니다. 이 기사에서는 REACT 및 JavaScript의 테스트에 익숙하다고 가정합니다. Jest 및 React Testing Library에 대한 친숙 함은 도움이 될 수 있지만 필요하지 않습니다.

세 가지 유형의 테스트가 있습니다.

  • 단위 테스트는 독립적으로 코드를 확인합니다. 글을 쓰기 쉽지만 큰 그림을 무시할 수 있습니다.
  • 엔드 투 엔드 테스트 (E2E)는 Cypress 또는 Selenium과 같은 자동화 된 프레임 워크를 사용하여 사용자와 같은 웹 사이트와 상호 작용합니다 : 페이지로드, 양식 작성, 클릭 버튼 등. 일반적으로 쓰여지고 느리게 실행되지만 실제 사용자 경험에 매우 가깝습니다.
  • 통합 테스트는 그 사이 어딘가에 있습니다. 응용 프로그램의 여러 단위가 어떻게 작동하는지 확인하지만 E2E 테스트보다 가볍습니다. 예를 들어, Jest에는 일부 내장 유틸리티가 제공되어 통합 테스트를 용이하게합니다. Jest는 백그라운드에서 JSDOM을 사용하여 자동화보다 오버 헤드가 적은 공통 브라우저 API를 시뮬레이션하며 강력한 조롱 도구는 외부 API 통화를 시뮬레이션 할 수 있습니다.

주목해야 할 또 다른 사항 : React Applications에서는 단위 테스트 및 통합 테스트가 동일한 방식으로 작성되며 도구가 사용됩니다 .

React 테스트를 시작하십시오

로그인 양식으로 간단한 React 응용 프로그램 (Github에서 사용 가능)을 만들었습니다. 프론트 엔드 프로젝트를 테스트하는 데 사용한 편리한 API 인 reqres.in에 연결했습니다.

성공적으로 로그인 할 수 있습니다.

... 또는 API의 오류 메시지가 발생합니다.

코드 구조는 다음과 같습니다.

 <code>LoginModule/ ├── components/ │ ├── Login.js // 渲染LoginForm、错误消息和登录确认│ └── LoginForm.js // 渲染登录表单字段和按钮├── hooks/ │ └── useLogin.js // 连接到API 并管理状态└── index.js // 将所有内容整合在一起</code>

옵션 1 : 단위 테스트

나와 같은 테스트를 좋아한다면 헤드폰을 착용하고 Spotify에서 멋진 음악을 재생하는 것을 좋아한다면 각 파일에 대한 단위 테스트 작성에 저항 할 수 없습니다.

테스트 애호가가 아니더라도 명확한 전략없이 "테스트를 잘 수행하려고 노력하는"프로젝트를 진행할 수 있으며 테스트 방법은 "모든 파일 자체 테스트가 있어야한다고 생각합니까?"입니다.

이것은 다음과 같습니다 (명확성을 위해 테스트 파일 이름에 단위를 추가했습니다).

 <code>LoginModule/ ├── components/ │  ├── Login.js │  ├── Login.unit.test.js │  ├── LoginForm.js │  └── LoginForm.unit.test.js ├── hooks/ │  ├── useLogin.js │  └── useLogin.unit.test.js ├── index.js └── index.unit.test.js</code>

GitHub에서 연습을 완료하여 이러한 모든 단위 테스트를 추가하고 테스트 : 커버리지 : 커버리지 보고서 (JEST의 내장 기능)를 생성하기위한 단위 스크립트를 만들었습니다. 4 개의 단위 테스트 파일을 통해 100% 적용 범위를 달성 할 수 있습니다.

100% 적용 범위는 일반적으로 압도적이지만 간단한 코드베이스는 가능합니다.

Onlogin React Hook 용으로 생성 된 단위 테스트 중 하나를 파헤쳐 봅시다. React 후크에 익숙하지 않거나 테스트하는 방법에 익숙하지 않은 경우 걱정하지 마십시오.

 테스트 ( '성공적인 로그인 흐름', async () => {
 // 성공적인 API 응답 농담을 시뮬레이션합니다
  .spyon (창, '페치')
  .MockResolvedValue ({json : () => ({Token : '123'})});

 const {result, waitfornextUpdate} = renderHook (() => uselogin ());

 act (() => {
  result.current.onsubmit ({{
   이메일 : '[이메일 보호]',
   비밀번호 : '비밀번호',
  });
 });

 // 상태를 보류 중으로 설정합니다
 expling (result.current.state) .toequal ({{
  상태 : '보류',
  사용자 : null,
  오류 : null,
 });

 WaitforNextUpdate ()를 기다립니다.

 // 해결 상태를 해결하고 이메일 주소를 저장하고 excome (result.current.state).
  상태 : '해결',
  사용자 : {
   이메일 : '[이메일 보호]',
  },
  오류 : null,
 });
});

이 테스트는 (React Hooks 테스트 라이브러리가 테스트 후크를 산들 바람으로 만들기 때문에) 작성하는 것이 흥미 롭습니다.

먼저, 테스트 검증 내부 상태는 '보류 중'에서 '해결 된'으로 변경됩니다. 이 구현 세부 사항은 사용자에게 노출되지 않으므로 테스트하는 것이 좋지 않을 수 있습니다. 응용 프로그램을 리팩터링하면 사용자의 관점에서 아무런 변경이 변경되지 않더라도이 테스트를 업데이트해야합니다.

또한 단위 테스트로서 이것은 그 일부일뿐입니다. 제출 버튼 텍스트를 "로드"로 변경하는 등 로그인 프로세스의 다른 기능을 확인하려면 다른 테스트 파일로 수행해야합니다.

옵션 2 : 통합 테스트

이 프로세스를 검증하기 위해 통합 테스트에 대한 대안을 추가하는 것을 고려해 봅시다.

 <code>LoginModule/ ├── components/ │  ├── Login.js │  └── LoginForm.js ├── hooks/ │  └── useLogin.js ├── index.js └── index.integration.test.js</code>

이 테스트와 테스트 : 적용 범위 : 통합 스크립트를 구현하여 커버리지 보고서를 생성했습니다. 단위 테스트와 마찬가지로 100% 적용 범위에 도달 할 수 있지만 이번에는 하나의 파일에 있으며 코드 줄이 적습니다.

성공적인 로그인 프로세스를 다루는 통합 테스트는 다음과 같습니다.

 test ( '성공적인 로그인', async () => {
  농담
    .spyon (창, '페치')
    .MockResolvedValue ({json : () => ({Token : '123'})});

  세우다(<loginmodule></loginmodule> );

  const emailfield = screen.getByRole ( 'textbox', {name : 'email'});
  const passwordfield = screen.getByLabelText ( 'password');
  const button = screen.getByRole ( '버튼');

  // fireeevent.change 양식을 작성하고 제출합니다 (emailfield, {target : {value : '[email protected]'});
  fireeevent.change (passwordfield, {target : {value : 'password'}});
  fireeevent.click (버튼);

  // 부하 상태를 설정합니다.
  expling (button).

  대기 중 (() => {
    // 양식 요소를 숨 깁니다.
    expling (emailfield) .not.tobeinthedocument ();
    expling (passwordfield) .not.tobeinthedocument ();

    // 성공 텍스트 및 이메일 주소를 표시합니다. const loggedIntext = screen.getByText ( '로그인 AS');
    기대 (loggedintext) .tobeinthedocument ();
    const emailaddresstext = screen.getBytext ( '[이메일 보호]');
    expling (emailaddresstext) .tobeinthedocument ();
  });
});

이 테스트는 사용자의 관점에서 전체 로그인 프로세스 (양식,로드 상태 및 성공적인 확인 메시지를 확인하기 때문에이 테스트를 정말 좋아합니다. 통합 테스트는이 사용 사례로 인해 반응 응용 프로그램에 적합합니다. 사용자 경험은 우리가 테스트하고자하는 입니다. 여기에는 거의 항상 여러 가지 다른 코드 스 니펫이 함께 작동합니다 .

이 테스트는 예상되는 동작이 작동하는 구성 요소 나 후크를 이해하지 못합니다. 사용자 경험이 동일하게 유지되는 한 테스트를 중단하지 않고 이러한 구현 세부 정보를 다시 작성하고 리팩터링 할 수 있습니다.

로그인 프로세스의 초기 상태 및 오류 처리에 대한 기타 통합 테스트를 파헤치지는 않지만 Github에서이를 보는 것이 좋습니다.

그렇다면 단위 테스트 에 필요한 것은 무엇입니까?

단위 테스트 대 통합 테스트를 고려하는 대신 한 걸음 물러서서 처음부터 테스트해야 할 사항을 결정하는 방법에 대해 생각해 봅시다. LoginModule은 사용자 (응용 프로그램의 다른 파일)가 자신있게 사용할 수있는 엔티티이기 때문에 테스트해야합니다.

반면, Onlogin 후크를 테스트 할 필요는 없습니다. 로그 핀 모드의 구현 세부 사항 일뿐입니다. 그러나 요구 사항이 변경되고 Onlogin이 다른 곳에서 사용 사례가있는 경우, 재사용 가능한 유틸리티로 기능을 확인하기 위해 자체 (Unit) 테스트를 추가해야합니다. (파일도 더 이상 loginModule에만 국한되지 않으므로 파일을 이동해야합니다.)

단위 테스트에는 여전히 재사용 가능한 선택기, 후크 및 정상 기능을 확인해야 할 필요성과 같은 많은 사용 사례가 있습니다. 코드를 개발할 때는 해당 논리를 나중에 통합 테스트로 옮기더라도 단위 테스트 제동 개발을 사용하는 것이 도움이 될 수도 있습니다.

또한 단위 테스트는 여러 입력 및 사용 사례에 대한 철저한 테스트를 수행하는 데 큰 도움이됩니다. 예를 들어, 내 양식에 다양한 시나리오에 대한 인라인 유효성 검사를 표시 해야하는 경우 (예 : 유효하지 않은 이메일, 비밀번호 누락, 너무 짧은 암호) 통합 테스트에서 대표적인 사례를 다루고 단위 테스트에서 특정 사례를 파악합니다.

다른 혜택

이제 우리가 여기에 있기 때문에 통합 테스트를 명확하고 질서있게 유지하는 데 도움이되는 몇 가지 구문 팁에 대해 이야기하고 싶습니다.

대기 중 대기 중

우리의 테스트는 로딩 상태와 LoginModule의 성공적인 상태 사이의 대기 시간을 고려해야합니다.

 const button = screen.getByRole ( '버튼');
fireeevent.click (버튼);

예상 (button) .not.tobeinthedocument (); // 너무 빠르면 버튼이 여전히 있습니다!

DOM 테스트 라이브러리의 대기 헬퍼 기능을 사용하여이를 수행 할 수 있습니다.

 const button = screen.getByRole ( '버튼');
fireeevent.click (버튼);

대기 중 (() => {
 예상 (button) .not.tobeinthedocument (); // 아, 훨씬 낫다});

그러나 다른 프로젝트를 테스트하고 싶다면 어떻게해야합니까? 인터넷에는 이것을 처리하는 방법에 대한 좋은 사례는 많지 않으며 과거 프로젝트에서는 다른 프로젝트를 Waitfor 외부에 넣었습니다.

 // 대기 버튼이 대기중인 대기 중 (() => {
 예상 (button) .not.tobeinthedocument ();
});

// 그런 다음 확인 메시지를 테스트하여 const volictionText = getByText ( '로그인 [이메일 profected]');
expost (quicationText) .TobeIntheDocument ();

이것은 작동하지만,이 진술의 순서를 쉽게 전환 할 수 있더라도 버튼 조건을 특별하게 보이게하기 때문에 마음에 들지 않습니다.

 // 확인 메시지가 기다려 대기 대기 중 (() => {
 const quicationText = getByText ( '로그인 [이메일 보호]');
 expost (quicationText) .TobeIntheDocument ();
});

// 그런 다음 버튼을 테스트합니다 (버튼) .not.tobeinthedocument ();

동일한 업데이트와 관련된 모든 것을 Waitfor Callback으로 그룹화하는 것이 훨씬 낫습니다.

 대기 중 (() => {
 예상 (button) .not.tobeinthedocument ();

 const conficationText = screen.getByText ( '로그인 [이메일 profected]');
 expost (quicationText) .TobeIntheDocument ();
});

나는 이와 같은 간단한 주장에 대한이 기술을 정말로 좋아하지만, 어떤 경우에는 테스트 속도를 늦출 수 있으며 바로 대기 외부에서 발생하는 실패를 기다릴 수 있습니다. 이 예에서는 React Testing Library Common Error에서 "단일 대기 용 콜백의 다중 어설 션"을 참조하십시오.

여러 단계가 포함 된 테스트의 경우 연속적으로 여러 대기 시간을 사용할 수 있습니다.

 const button = screen.getByRole ( '버튼');
const emailfield = screen.getByRole ( 'textbox', {name : 'email'});

// fireeevent.change 양식을 채우십시오 (emailfield, {target : {value : '[email propected]'});

대기 중 (() => {
 // 버튼이 활성화되어 있는지 확인하십시오 (button) .not.tobedisabled ();
  expling (button) .toHavetextContent ( '제출');
});

// fireeevent 양식을 제출하십시오. Click (버튼);

대기 중 (() => {
 // 버튼이 더 이상 존재하지 않는지 확인 (button) .not.tobeIntheDocument ();
});

하나의 항목 만 나타나기를 기다리고 있다면 대신 FindBy 쿼리를 사용할 수 있습니다. 백그라운드에서 대기를 사용합니다.

인라인 IT 댓글

또 다른 테스트 모범 사례는 더 적고 긴 테스트를 작성하는 것입니다. 이를 통해 테스트 사례를 중요한 사용자 프로세스와 상관 관계가있는 동시에 예상치 못한 동작을 피하기 위해 테스트를 고립시킬 수 있습니다. 나는이 접근법에 동의하지만, 코드를 정리하고 필요한 행동을 문서화하는 데 어려움을 겪을 수 있습니다. 우리는 미래의 개발자가 테스트로 돌아가서 무엇을하고 있는지, 실패한 이유 등을 이해할 수 있도록해야합니다.

예를 들어, 이러한 기대 중 하나가 실패하기 시작한다고 가정합니다.

 IT ( '성공적인 로그인 흐름을 처리', async () => {
 // 명확성을 위해 테스트의 시작을 숨 깁니다

  예상 (button) .tobedisabled ();
  expling (button).


 대기 중 (() => {
  예상 (button) .not.tobeinthedocument ();
  expling (emailfield) .not.tobeinthedocument ();
  expling (passwordfield) .not.tobeinthedocument ();


  const conficationText = screen.getByText ( '로그인 [이메일 profected]');
  expost (quicationText) .TobeIntheDocument ();
 });
});

이 콘텐츠를보고있는 개발자는 테스트중인 내용을 쉽게 결정할 수 없으며, 고장이 버그 (코드를 수정해야 함)인지 또는 동작 변경 (테스트를 수정해야 함)인지 판단하기가 어려울 수 있습니다.

내가 가장 좋아하는 솔루션은 각 테스트에 대해 잘 알려진 테스트 구문을 사용하고 테스트중인 각 주요 동작을 설명하는 인라인 스타일의 주석을 추가하는 것입니다.

 test ( '성공적인 로그인', async () => {
 // 명확성을 위해 테스트의 시작을 숨 깁니다

 //로드 상태를 설정합니다.
  expling (button).


 대기 중 (() => {
  // 양식 요소를 숨 깁니다.
  expling (emailfield) .not.tobeinthedocument ();
  expling (passwordfield) .not.tobeinthedocument ();


  // 성공 텍스트 및 이메일 주소를 표시합니다. const volictionText = screen.getByText ( '로그인 [이메일 propected]');
  expost (quicationText) .TobeIntheDocument ();
 });
});

이 주석은 마술처럼 농담과 통합되지 않으므로 실패가 발생하면 실패한 테스트 이름은 테스트 태그에 전달한 매개 변수,이 경우 "성공적인 로그인"에 해당합니다. 그러나 Jest의 오류 메시지에는 주변 코드가 포함되어 있으므로 이러한 IT 주석은 여전히 ​​실패한 동작을 식별하는 데 도움이됩니다. 기대에서 벗어나지 않으면 다음 오류 메시지가 표시됩니다.

더 명백한 오류를 얻으려면 Jest-Expect Message라는 패키지가있어 각 기대에 대한 오류 메시지를 정의 할 수 있습니다.

 expling (버튼, '버튼은 여전히 ​​문서에 있습니다').

일부 개발자는이 접근법을 선호하지만 대부분의 경우 너무 세분화되어 있습니다. 단일은 일반적으로 여러 가지 기대치를 포함합니다.

팀의 다음 단계

때때로 나는 우리가 인간을 위해 린터 규칙을 만들 수 있기를 바랍니다. 그렇다면 팀에 대한 선호 통합 테스트 규칙을 설정할 수 있으며 종료됩니다.

그러나 아아, 우리는 개발자가 이전에 소개 한 LoginModule 예제와 같은 일부 경우 통합 테스트를 선택하도록 장려하기 위해 더 유사한 솔루션을 찾아야합니다. 대부분의 것들과 마찬가지로 팀이 테스트 전략에 대해 논의하고 프로젝트에 어떤 의미가있는 것에 동의하고, ADR에서 문서화하는 데 동의합니다.

시험 계획을 개발할 때 개발자가 각 파일에 대한 테스트를 작성하도록하는 문화를 피해야합니다. 개발자는 "맹목적"에 대해 걱정하지 않고 자신있게 정보에 입각 한 테스트 결정을 내릴 수 있어야합니다. Jest의 적용 범위 보고서는 테스트가 통합 수준에서 병합 되더라도 정신 점검을 제공 하여이 문제를 해결하는 데 도움이 될 수 있습니다.

나는 여전히 나 자신이 통합 테스트 전문가라고 생각하지 않지만이 연습을하면 통합 테스트가 단위 테스트보다 더 많은 가치를 제공하는 사용 사례를 분류하는 데 도움이되었습니다. 이를 팀과 공유하거나 코드베이스에서 유사한 연습을하면 통합 테스트를 워크 플로에 통합하는 데 도움이되기를 바랍니다.

위 내용은 반응 통합 테스트 : 커버리지가 커지고 테스트가 적습니다의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
@keyframes 및 @Media와 같이 @Rules는 얼마나 많은 특이성을 가지고 있습니까?@keyframes 및 @Media와 같이 @Rules는 얼마나 많은 특이성을 가지고 있습니까?Apr 18, 2025 am 11:34 AM

나는 다른 날이 질문을 받았다. 나의 첫 번째 생각은 : 이상한 질문입니다! 특이성은 선택기에 관한 것이며 At-Rules는 선택기가 아니므로 ... 무의미합니까?

@Media 및 @Support 쿼리를 중첩 할 수 있습니까?@Media 및 @Support 쿼리를 중첩 할 수 있습니까?Apr 18, 2025 am 11:32 AM

그렇습니다. 당신은 할 수 있습니다. 그리고 그것은 실제로 어떤 순서로 중요하지 않습니다. CSS 전 처리기가 필요하지 않습니다. 일반 CSS에서 작동합니다.

빠른 Gulp 캐시 파열빠른 Gulp 캐시 파열Apr 18, 2025 am 11:23 AM

CSS 및 JavaScript (및 이미지 및 글꼴 등)와 같은 자산에 멀리 떨어진 캐시 헤더를 설정해야합니다. 브라우저를 알려줍니다

CSS의 품질과 복잡성을 모니터링하는 스택을 찾아CSS의 품질과 복잡성을 모니터링하는 스택을 찾아Apr 18, 2025 am 11:22 AM

많은 개발자들은 CSS 코드베이스를 유지하는 방법에 대해 글을 썼지 만 코드베이스의 품질을 어떻게 측정하는지에 대해 많은 글을 쓰지 않습니다. 물론, 우리는 가지고 있습니다

Datalist는 가치를 시행하지 않고 값을 제안하는 것입니다Datalist는 가치를 시행하지 않고 값을 제안하는 것입니다Apr 18, 2025 am 11:08 AM

짧고 임의의 텍스트를 수락 해야하는 양식이 있습니까? 이름이나 다른 것 같습니다. 정확히 무엇을위한 것입니다. 많은 것이 있습니다

취리히에서 열린 전면 회의취리히에서 열린 전면 회의Apr 18, 2025 am 11:03 AM

나는 프론트 컨퍼런스를 위해 스위스 취리히로 향하게되어 매우 기쁩니다 (그 이름과 URL을 사랑합니다!). 나는 전에 스위스에 가본 적이 없기 때문에 나는 흥분했다

CloudFlare Workers와 함께 풀 스택 서버리스 애플리케이션 구축CloudFlare Workers와 함께 풀 스택 서버리스 애플리케이션 구축Apr 18, 2025 am 10:58 AM

소프트웨어 개발에서 제가 가장 좋아하는 개발 중 하나는 서버리스의 출현이었습니다. 세부 사항에 푹 빠지는 경향이있는 개발자로서

NUXT 응용 프로그램에서 동적 경로 생성NUXT 응용 프로그램에서 동적 경로 생성Apr 18, 2025 am 10:53 AM

이 게시물에서는 들어오는 데이터를 위해 동적 경로를 만드는 방법을 보여주기 위해 NetLify에 구축하고 배포 한 전자 상거래 상점 데모를 사용합니다. 상당히입니다

See all articles

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

뜨거운 도구

MinGW - Windows용 미니멀리스트 GNU

MinGW - Windows용 미니멀리스트 GNU

이 프로젝트는 osdn.net/projects/mingw로 마이그레이션되는 중입니다. 계속해서 그곳에서 우리를 팔로우할 수 있습니다. MinGW: GCC(GNU Compiler Collection)의 기본 Windows 포트로, 기본 Windows 애플리케이션을 구축하기 위한 무료 배포 가능 가져오기 라이브러리 및 헤더 파일로 C99 기능을 지원하는 MSVC 런타임에 대한 확장이 포함되어 있습니다. 모든 MinGW 소프트웨어는 64비트 Windows 플랫폼에서 실행될 수 있습니다.

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

WebStorm Mac 버전

WebStorm Mac 버전

유용한 JavaScript 개발 도구

ZendStudio 13.5.1 맥

ZendStudio 13.5.1 맥

강력한 PHP 통합 개발 환경

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기