원티드 8월 챌린지 사전과제: 테스트 & 최적화 조사

Sheryl Yun·2023년 7월 25일
0

개발 상식 쌓기

목록 보기
7/11

테스트 🎍

1. 유닛 테스트 (단위 테스트)

  • 테스트할 수 있는 가장 작은 단위를 테스트
  • 매우 간단하고 명확하게 작성 가능
  • 가장 쉽고 빠르게 테스트 가능
    • 개발 과정 중에 미리 문제 파악 가능
    • 다양한 입력 값으로 테스트를 짜놓으면 버그를 미리 잡을 확률 상승
    • 테스트 단위를 기준으로 설계하며 더 명확한 설계 가능
  • 함수나 메서드와 같은 작은 단위의 코드를 테스트하는 데 중점을 두는 테스트
  • 코드의 각 단위가 예상대로 작동하고 요구 사항을 충족하는지 확인
  • 테스트 대상: 클래스, 메서드, 함수 하나하나
  • 예: 구매 기능 테스트하기 - 고객의 잔액에서 상품의 금액만큼 출금하는지, 상품의 재고를 업데이트하는지, 영수증을 잘 생성하는지 등
  • 테스트도구: Jest와 react-testing-library
  • 장점
    • 개발 과정 중에 미리 문제 파악 가능
    • 리팩토링 등 코드 변경 후의 영향을 쉽게 파악 가능
      • 테스트 케이스는 내가 가입한 보험과 같다.
    • 새로운 입력이 팀에 합류했을때 개발 스타일, 표준, 컨벤션 등을 공유하기에 좋음
    • 페어 프로그래밍 시 테스트 케이스를 작성한 사람의 설계를 공유하면서 소스 개발까지 이어질 수 있으므로 특정 기능을 집중력 있게 개발할 수 있다.
  • 테스트를 '자동화' 하면 항상 판매 가능한 제품을 만들 수 있다.

예시 1

const sum = (a, b) => a + b;

test('add 1 + 2 = 3', () => {
	expect(sum(1, 2)).toBe(3);
})

예시 2

import { render } from '@testing-library/react';
import Item from '../components/Item';

// describe는 여러 개의 it을 묶는 역할
describe('Item', () => {
  it('should render item name and price', () => {
    const { getByText } = render(
      <Item name="Test Item" price={12000} addToCart={() => {}} />
    );
    expect(getByText('Test Item')).toBeInTheDocument();
    expect(getByText('Price: 12000')).toBeInTheDocument();
  });
  
  it('should remove item stock', () => {
  // ... 
  });
  // ...
});

2. 통합 테스트

  • 서로 다른 시스템 간의 상호작용을 확인하는 테스트
  • 두 개 이상의 클래스 또는 시스템의 결합 테스트
  • 개발자가 변경할 수 없는 부분 (ex. 외부 라이브러리, db)까지 묶어서 검증
  • 단위 테스트보다 더 큰 동작을 달성하기 위해 여러 모듈들이 의도대로 협력하는지 확인
  • 단위를 넘어서 각기 다른 시스템이 잘 상호작용하는지 확인 (ex. db와 잘 연동되는지, 시스템 간의 통신에 있어서 에러 검출 등)
  • 백엔드 기준 예시: postman을 사용해서 Json 응답이 제대로 출력되는지 테스트
  • 장점: 단위 테스트에서 발견하기 어려운 버그를 찾을 수 있다.
  • 단점: 단위 테스트보다 더욱 복잡하며 더 많은 코드를 테스트하기 때문에 에러 검출이 명확하지 않다(신뢰성이 떨어진다), 어디서 에러가 발생했는지 확인하기 어려워서 유지보수가 힘들다 => 이러한 이유로 실제로 단위 테스트에 더 초점
  • 테스트 도구: Jest와 react-testing-library

3. E2E 테스트 (종단 테스트, UI 테스트)

  • End To End 테스트의 약자
  • 사용자가 실제 프로그램을 사용하는 시점(endpoint)을 테스트
  • 인수 테스트(Acceptance Test) 라고도 함
  • 시스템의 시작부터 끝까지 전체 흐름을 확인
  • 시스템이 예상대로 작동하고 사용자의 요구 사항을 충족하는지 확인하기 위해 모든 구성 요소와 해당 구성 요소의 상호 작용 테스트
  • 소프트웨어의 내부 구조보다 비즈니스 쪽에 초점
    • '사용자 시나리오'대로 잘 동작하는지
  • 진행 도구: Cypress, Puppeteer

테스트 관련 팁

함수의 기능이 단순한 연결일 경우는 테스트를 작성하지 않아도 된다.
예: NextJS의 getStaticProps는 데이터를 갖고 와서 props에 넘겨주기만 하는 함수이므로 이 함수는 테스트할 필요가 없다. (함수 내에 데이터를 변환하거나 복잡한 로직이 있을 경우 예외)

리액트 테스팅 도구

Jest

  • facebook에서 오픈 소스화한 javascript 테스트 프레임워크
  • CRA(Create-React-App)에는 기본적으로 내장되어 있음

React-Testing Library (RTL)

  • DOM을 테스트하기 위한 도구
  • 즉, React 컴포넌트를 테스트 하기 위해 만들어진 도구

Jest vs RTL

: React 내에서 테스트를 진행할 때 함께 사용되는 상호보완 관계

  • Jest를 통해 전반적인 기능 테스트 진행
  • RTL을 통해 React의 컴포넌트 렌더링에 관한 테스트 진행

Given-When-Then 순서의 RTL 테스트 예시

import {render, screen} from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import '@testing-library/jest-dom'
import Fetch from './fetch'

test('loads and displays greeting', async () => {
  // GIVEN: 주어지는 것
  render(<Fetch url="/greeting" />)

  // WHEN: 분기
  await userEvent.click(screen.getByText('Load Greeting'))
  await screen.findByRole('heading')

  // THEN: 분기에 따른 결과 확인
  expect(screen.getByRole('heading')).toHaveTextContent('hello there')
  expect(screen.getByRole('button')).toBeDisabled()

TDD 방법론 (추가 조사)

  • Test-Driven Development (테스트 주도 개발)
  • 실패하는 테스트 코드를 먼저 만들어놓고 그 테스트를 통과하도록 실제 코드를 작성하는 방식
    • 예: App.test.js 코드를 통과하는 App.js 코드 작성

테스트 코드를 짜는 이유

  • 테스트가 용이하게 코드를 작성하게 됨 => 코드 품질과 신뢰성을 높임
  • 테스팅 코드를 작성하여 미리 에러 방지
  • 버그가 있을 때 어떤 상황에서 발생하는지 알 수 있음
  • 리팩토링 중 안정성 확보 가능
  • 장기적 측면에서 개발 및 테스팅에 대한 시간과 비용 절감

테스트 코드를 짤 때 컴포넌트의 요구사항을 먼저 정의하고 테스트를 작성하면 필요한 기능을 정확하게 테스트할 수 있다.

테스트를 만들기 전에 어떤 요구사항이 있는지 글로 적어보는 게 중요하다.


최적화 🚀

CDN(Content Distributed Network)

  • 콘텐츠를 효율적으로 전달하기 위해 지리적으로 분산되어 있는 네트워크에 데이터를 저장하여 제공하는 시스템
  • 핵심: 웹 컨텐츠의 복사본을 사용자에 가까운 서버에 두기
  • 각 CDN 서버는 이른바 "네트워크 에지"에 위치
    • 웹사이트의 출처인 "호스트 서버"와 비교하면 사용자와의 거리가 더 가까운 곳
    • CDN 서버 -> "에지 서버"라고 불림

  • 각 서버는 호스트 서버에 있던 웹 컨텐츠(HTML 파일, 이미지, 오디오, 비디오, 애플리케이션 등)의 복사본을 저장하거나 캐싱
  • 장점: 호스트 서버의 컨텐츠와 사용자 간의 거리를 줄여
    • 동적 컨텐츠 전달 활성화
    • 웹 사이트 성능을 향상
    • 사용자가 경험하는 로딩 시간 단축
    • 컨텐츠 제공 기업의 대역폭 소비 및 비용 관리

  • 목적: 높은 사용성과 효율로 사용자에게 컨텐츠를 전달하는 것
  • 일반적으로 자체 서버 네트워크를 운영하는 CDN 제공업체에서 기업이 CDN 서비스를 구매하여 사용
  • 오가는 대상 컨텐츠: 웹 요소(텍스트, 그래픽, 스크립트), 다운로드 가능한 요소(미디어 파일, 소프트웨어, 문서), 애플리케이션(전자상거래, 포털), 실시간 미디어, 주문형 스트리밍, 소셜 네트워크 등

  • 미디어 회사나 전자상거래 등의 콘텐츠 제공자는 컨텐츠를 사용자에게 전달하기 위해서 CDN 회사에 사용료 지불

  • CDN은 ISP, 이동통신사업자, 네트워크 사업자들에게 데이터 센터에서의 서버 호스팅 비용을 지불

  • 장점: 더 나은 퍼포먼스와 사용성, 컨텐츠 제공자의 서버의 트래픽을 덜어주어 비용을 줄여줌, 대규모 분산 서버 장비로 공격 트래픽 완화(DoS 공격으로부터 컨텐츠 제공자를 어느 정도 보호 가능)


  • 초기 CDN은 CDN 서버를 사용하는 컨텐츠에만 적용 가능

    • 최신 트랜드는 P2P기술을 이용하는 하이브리드 모델
    • 하이브리드 모델: 컨텐츠가 지정된 서버와 주변 컴퓨터(peer-user-owned)를 모두 사용

Web Vitals

  • 전제: 'Core Web Vitals’
  • 모든 웹 경험에서 중요한 핵심 사용자 경험의 공통 요구사항
  • 예: 로딩 경험, 상호 작용, 페이지 콘텐츠의 시각적 안정성
  • 코어 웹 바이탈(Core Web Vitals)의 기준을 충족한 웹 페이지는 방문자가 사이트에서 이탈할 가능성이 24%나 낮다. (SEO 상승)
  • 대표적 항목: LCP, FID, CLS

1. LCP (Largest Contentful Paint)

  • 페이지의 주요 콘텐츠가 로딩되는 속도
  • 웹 페이지의 로딩 속도에 대한 지표
  • viewport(사용자가 스크롤하지 않고 볼 수 있는 웹 페이지 영역) 중에서 가장 큰 요소인 <main>이나 <section>와 함께 heading, div, form 요소를 포함
  • 텍스트 요소를 포함한 모든 HTML 요소들이 브라우저 화면에서 렌더링 완료되는데까지 걸리는 시간
  • 뷰포트 중에서도 이미지, 이미지 태그, 비디오 썸네일, CSS가 있는 배경 이미지, 단락, 머리글, 목록과 같은 요소의 로딩 속도만 계산
  • 구글이 제공하는 Lighthouse, Chrome DevTools, PageSpeed Insight 등에서 LCP 측정 가능
  • 2.5초 이하일 경우는 좋은 상태, 4초 이상이면 문제 (낮을수록 좋음)

2. FID (First Input Delay)

  • 사용자가 페이지와 처음 상호 작용하려고 할 때 느끼는 delay 정도
  • 사용자가 웹 페이지에 들어온 후 로딩이 되고 있는 상태에서 링크를 클릭하거나 버튼을 탭하거나 자바스크립트 기반의 조작을 하면, 브라우저는 중요 콘텐츠의 로딩이 완료될 때까지 요청받은 액션의 처리를 일정 시간 보류
  • 즉, 브라우저에서 다음 액션이 가능하게 되는 시간까지의 길이를 측정한 지표
  • 밀리세컨드(ms)로 측정
  • 사용자 환경에서 사용자가 체감하는 지표이기 때문에 테스트 환경에서 확인할 수 있는 지표가 아니어서 시뮬레이션을 통한 측정 불가
    • 다양한 테스트 환경에서 측정 가능한 총 차단 시간(Total Blocking Time, TBT)로 FID 지표를 대신할 것을 구글에서 권장

Total Blocking Time (총 차단 시간, TBT)

  • 페이지 로드 중 입력 작업이 불가능한 시간의 합계 (낮을수록 좋음)
  • 100 ms 이하이면 좋은 상태, 300 ms 이상이면 나쁜 상태

3. CLS (Cumulative Layout Shift)

  • 어떤 페이지에 들어갔을 때 갑작스럽게 발생하는 레이아웃 이동의 정도를 합산 이동 거리라는 개념을 도입해서 만들어낸 지표
  • 예: 뉴스 기사를 보려고 들어간 웹사이트에서 기사 링크를 클릭하려는 순간 레이아웃이 이동해서 광고가 나타나 기사가 아닌 광고를 클릭하게 되는 것
  • 0.1 이하이면 양호, 0.1~ 0.25라면 개선 필요, 0.25 이상이면 나쁜 상태

기타 Core Web Vitals의 요소

  • 모바일 친화성: 웹 페이지가 모바일 브라우징에 최적화되어 있는가?
  • 세이프 브라우징: 페이지에 방문자의 의도를 속이려는 의도를 가진(오해하게 만드는) 콘텐츠가 있는가? 혹은 악성 코드나 애드웨어 등이 심어져 있지 않은가?
  • HTTPS 여부: 웹 사이트가 HTTPS로 제공되고 있는가?
  • 방해 요소: 컨텐츠 소비를 방해하는 전면 광고와 같은 방해 요소가 있는가?

Lighthouse

  • Google Chrome에서 제공하는, 웹앱의 품질 개선에 도움을 주는 자동화 도구
  • 성능, 접근성, SEO 등 사이트에 대한 전반적인 진단 가능
  • 사용 방법: 측정할 웹 사이트의 페이지로 이동 -> 개발자 도구를 열어 Lighthouse 탭 오픈 -> Generate report 버튼 클릭 -> 현재 페이지가 자동으로 리로드되며 검사 진행 -> 검사가 완료되면 결과 리포트 생성 (카테고리별 측정 항목 및 점수, 계산 방식, 최적화 방안 등 포함)
  • 검사 결과를 json이나 gist로 저장해두고 Lighthouse Report Viewer 사이트에서 언제든지 다시 확인 가능

Performance (성능)

  • 6가지 Metric으로 정의됩니다.
  • 각 Metric들은 페이지가 로드되는 속도를 다양한 측면에서 측정

First Contentful Paint (FCP)

  • 초기 DOM 콘텐츠를 렌더링(표시)하는데 걸리는 시간
  • 예: 첫 번째 텍스트나 이미지
  • FCP 측정을 시작점으로 하는 다른 Metric들이 있기 때문에, 가장 먼저 찍히는 FCP는 다른 항목들의 점수 및 전체 점수에 큰 영향

Speed Index (SI)

  • 콘텐츠가 시각적으로 표시되는 진행 속도
  • 리로드되는 페이지의 비디오를 캡쳐하여 프레임 간의 속도 계산
  • 높이는 방법
    • 메인 스레드 작업 최소화, JavaScript 실행 시간 단축, 폰트가 로드되는 중에도 텍스트가 계속 표시되도록 처리

Largest Contentful Paint (LCP)

  • 뷰포트(viewport) 내에서 가장 큰 콘텐츠를 렌더링 하는데 걸리는 시간
  • 보통 중요한 콘텐츠일수록 크기가 크기 때문에 Lighthouse는 LCP 점수에 가장 높은 가중치인 25%를 주어 계산
  • LCP 관련 태그: <img> 요소, <svg> 안에 있는 <image> 요소, <video> 요소, background-image 속성의 url()로 로드되는 요소, block 레벨 요소 등

Time To Interactive (TTI)

  • 사용자가 페이지와 완전하게 상호작용할 수 있을 때까지 걸리는 시간
  • 단순히 시각적으로 보여지는 것 뿐만 아니라, 사용자가 페이지와 소통이 가능한 상태까지 렌더링 되어야
  • 예: 이벤트 핸들러가 가장 눈에 띄는 페이지 요소에 등록되는 시점에는 사용자와 사이트가 상호작용이 가능해졌다고 볼 수 있습니다.
  • 높이는 방법: JavaScript 실행 시간 최소화

Total Blocking Time (TBT)

  • 사용자 입력(예: 마우스 클릭, 화면 탭 또는 키보드 누름)에 페이지가 응답하지 못하도록 차단된 총 시간
  • FCP와 TTI 사이의 모든 Long Task 블로킹 타임을 추가하여 계산
  • 높이는 방법 (= Long Task의 근본적인 원인을 제거하는 방법): 불필요한 JavaScript 로드와 실행 코드 제거, 코드 분할로 JavaScript payload 감소, 사용하지 않는 코드 삭제

Cumulative Layout Shift (CLS)

  • 사용자가 예상치 못한 레이아웃 이동을 경험하는 것에 대한 점수
  • 레이아웃 불안정이 사용자에게 미치는 부정적인 영향을 확인하기 위한 지표

참고 자료

프론트엔드 테스트 - TDD와 종류(Unit, Integration, E2E)
프론트엔드 테스트 해야할까?
CDN(Content Delivery Network)이란?
콘텐츠 전송 네트워크
CDN(Contents Delivery Network) 개념 살펴보기(웹 최적화)
Web Vitals 소개: 건강한 사이트를 위한 필수적인 측정항목
코어 웹 바이탈(Core web Vitals)이란 무엇인가?
Lighthouse로 웹사이트 성능 측정하기

profile
영어강사, 프론트엔드 개발자를 거쳐 데이터 분석가를 준비하고 있습니다 ─ 데이터분석 블로그: https://cherylog.tistory.com/

2개의 댓글

comment-user-thumbnail
2023년 7월 25일

정리가 잘 된 글이네요. 도움이 됐습니다.

1개의 답글