티스토리 뷰

해당 글은 github goldbergyoni 님의 javascript-testing-best-practices 를 번역하여 작성한 글 입니다. 번역 과정중 오류가 있을 수 있으니 댓글을 통해 피드백 주시면 감사하겠습니다.

스냅샷 테스트를 할 때는 짧은 인라인 스냅샵만 사용하라


snapshot testing이 필요하다면 핵심 검증 사항에만 집중된 (3~7 라인) 짧은 snapshots 을 외부 파일이 아닌 테스트 코드 내에서 사용하는 것을 권장합니다. 이 가이드라인만 지킨다면 테스트가 쉽게 깨지지 않고 좋은 가독성을 유지할 수 있습니다.

 

반면에, '고전적인 스냅샷'의 튜토리얼이나 도구들은 스냅샷을 매우 크게 만들고 외부 파일로 저장하도록 유도하고 있습니다. 그리고 테스트가 실행될 때 마다 외부에 저장된 파일과 비교하여 문제가 없는지 알려주는 방식으로 검증 합니다.

 

이렇게 큰 파일로, 많은 부분을 커버하는 스냅샷으로 테스트를 작성하면 약간의 코드를 변경하더라도 스냅샷이 유효하지 않게 될 가능성이 커집니다. 따라서 테스트가 쉽게 깨질 수 있습니다. 또한 하나의 테스트케이스가 수십 라인의 코드를 커버하기 때문에 테스트가 실패하더라도 실패한 원인을 쉽게 파악하기 어렵습니다.

 

이러한 문제들은 잘못 작성된 스냅샷 테스트 뿐만 아니라 지나치게 많은 것을 목표로 하는 모호한 테스트에서 많이 발생하는 문제 입니다.

 

하지만 스키마 이거나 데이터가 아닌 것들을 검증할 때 또는 테스트 하고자 하는 docuemnt 가 거의 변경될 일이 없을때와 같은 경우는 예외적으로 해당 가이드라인을 지킬 필요는 없습니다.

 

권장하지 않는 예제

아래 테스트 코드는 보이지 않는 수 많은 코드 라인과 커플링 되어 깨지기가 매우 쉬운 상태입니다.

it('TestJavaScript.com is renderd correctly', ()  => {

//Arrange
const element = (<DisplayPage page  =  "http://www.testjavascript.com"  > Test JavaScript < /DisplayPage>);


//Act
const receivedPage = renderer.create(element).toJSON();

//Assert
expect(receivedPage).toMatchSnapshot();
//We now implicitly maintain a 2000 lines long document
//every additional line break or comment - will break this test

});

권장하는 예제

요구사항이 정확하게 드러나있다.

it('When visiting TestJavaScript.com home page, a menu is displayed', () => {
  //Arrange
  const element = <DisplayPage page  =  "http://www.testjavascript.com"  > Test JavaScript < /DisplayPage>;
  const snapshot = `
      <ul>
      <li>Home</li>
      <li> About </li>
      <li> Contact </li>
      </ul>
    `;

  //Act
  receivedPage tree = renderer.create(element).toJSON();

  //Assert
  const menu = receivedPage.content.menu;
  expect(menu).toMatchInlineSnapshot(snapshot);
});

전역 fixtures, seeds 를 피하고 테스트 마다 데이터를 추가하라


테스트를 위해 필요한 사전 작업 또는 데이터를 사용할 때는 각각의 테스트케이스별로 분리해서 작업하면 커플링이 방지되고 테스트 흐름을 쉽게 파악할 수 있습니다. 하지만 현실은 종종 성능 개선을 이유로 테스트 수행전 한번에 DB에 데이터를 추가하는 등의 경우가 발생한다.

 

실제로 성능은 중요한 문제이지만, 이는 얼마든지 다른 방법으로도 개선 가능한 경우가 많습니다. 하지만 대부분의 경우 테스트의 복잡성은 다른 최우선으로 고려해야 할 만큼 엄격하게 관리해야 합니다. 따라서 각 테스트가 명시적으로 필요한 레코드, 데이터를 DB 에 추가하고 해당 레코드만 사용하여 작업하도록 만드는게 좋습니다.

 

만약 성능이 중요한 관심사가 되었을 때 현명한 타협점은 데이터를 변경하지 않는 테스트 집합으로 만들고 테스트 수행 전 한번에 데이터를 셋팅하는 형태로 만들 수 있습니다.

 

권장하지 않는 예제

각 테스트들이 독립적이지 않고 글로벌 DB 에 데이터를 추가하는 before hook에 의존합니다.

before(() => {
  //adding sites and admins data to our DB. Where is the data? outside. At some external json or migration framework
  await DB.AddSeedDataFromJson('seed.json');
});
it("When updating site name, get successful confirmation", async () => {
  //I know that site name "portal" exists - I saw it in the seed files
  const siteToUpdate = await SiteService.getSiteByName("Portal");
  const updateNameResult = await SiteService.changeName(siteToUpdate, "newName");
  expect(updateNameResult).to.be(true);
});
it("When querying by site name, get the right site", async () => {
  //I know that site name "portal" exists - I saw it in the seed files
  const siteToCheck = await SiteService.getSiteByName("Portal");
  expect(siteToCheck.name).to.be.equal("Portal"); //Failure! The previous test change the name :[
});

권장하는 예제

각 테스트는 자체 데이터 세트를 활용하여 작업합니다.

it("When updating site name, get successful confirmation", async () => {
  //test is adding a fresh new records and acting on the records only
  const siteUnderTest = await SiteService.addSite({
    name: "siteForUpdateTest"
  });
  
  const updateNameResult = await SiteService.changeName(siteUnderTest, "newName");
  
  expect(updateNameResult).to.be(true);
});

원문 자료


 

goldbergyoni/javascript-testing-best-practices

📗🌐 🚢 Comprehensive and exhaustive JavaScript & Node.js testing best practices (August 2019) - goldbergyoni/javascript-testing-best-practices

github.com

 

댓글
댓글쓰기 폼
Total
363,632
Today
23
Yesterday
501
링크
«   2019/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        
글 보관함