소프트웨어 테스트 특강
강사님은 우아한형제들의 민태강사님과 같은 팀에서 테크리더로 계시며 소프트웨어 테스트의 주제를 갖고 테스트의 종류, 장단점, 자동화 등과 관련된 지식을 공유해주셨다.
소프트웨어 테스트는 소프트웨어가 의도한 대로 동작하는지 검사하는 과정이다. 이를 통해 오류나 결함이 있는지 확인할 수 있으며 개발자의 입장에서는 테스트를 통해 버그가 있는지, 구현된 기능이 정상적으로 작동하는지를 확인한다.
수동 테스트
테스트 케이스(시나리오)를 기반으로 수동으로 기능을 확인하는 방식이다. 예를 들어 API 요청이 정상적으로 이루어지고, 데이터가 올바르게 출력되는지, 페이지 간 이동이나 수정이 잘 이루어지는지를 직접 확인한다.
QA 직군
QA(Quality Assurance) 직군은 소프트웨어 제품의 품질을 보증하기 위해 테스트를 수행하는 사람들로 시나리오를 기반으로 수동으로 테스트를 수행한다.
예를 들어, API 호출이 실패하는 이유를 수동테스트만으로는 확인하기 어렵다. 잘 찾아서 문제 발생 지점을 확인하더라도 이를 수정한 뒤 다시 테스트해야 하기 때문에 많은 비용이 드는 뿐만 아니라 사람이 직접 테스트하다 보니 반복 작업에서 실수가 발생할 수 있어 시간과 비용이 많이 든다.
실제 사용자 기반의 테스트로, QA 직군이 시나리오대로 수동으로 수행하는 테스트처럼 다양한 사용자 흐름이 예상대로 작동하는지 확인한다.
보통 모든 개발이 끝난 후에 실행되며, '헤드리스 브라우저'를 이용해 시뮬레이션한다.
여러 모듈이 상호 작용하는 부분을 테스트하는 방식으로 각 컴포넌트가 원하는 대로 동작하는지, 데이터베이스와 상호 작용이 잘 되는지를 확인하며, 안정성이 중요한 기능(예: 결제, 장바구니)에서 주로 사용된다.
단위테스트는 가장 작은 단위의 기능을 테스트하는 방식으로 구성 요소, 모듈의 개별 메서드 및 함수 등을 테스트한다. 세부적인 기능을 구현하기 전에 미리 테스트를 작성할 수 있어 매우 빠르게 실행할 수 있고 실제 사용자 흐름을 점검하는 E2E 테스트와 달리 특정 기능을 세밀하게 검증하는 데 중점을 둔다.
const addNumber = (a: number, b: number) => {
return a + b;
};
describe('addNumber', () => {
test('1 + 2 = 3', () => {
expect(addNumber(1, 2)).toBe(3);
});
test('3 + 5 = 8', () => {
expect(addNumber(3, 5)).toBe(8);
});
});
Cypress, Playwright 같은 도구를 사용해 브라우저에서 발생하는 작업을 자동으로 테스트할 수 있다. 수동테스트에 반해 테스트 스크립트를 작성해야하는 단계가 있지만 테스트 스크립트를 만들고 자동화한다면 큰 장점이 된다.
GitHub Actions를 이용하여 CI 환경에서 테스트 자동화 워크플로우를 작성할 수 있고, Mock API를 이용해 실제 API호출하고 다양한 시나리오대로 테스트할 수 있다.
// ex) 토이3프로젝트 당시 작성했었던 github/workflows/playwright.yml
test:
timeout-minutes: 60
runs-on: ubuntu-latest
services:
api:
image: node:16
ports:
- 8080:8080
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: lts/*
- name: Install dependencies
run: npm ci
- name: Install Playwright Browsers
run: npx playwright install --with-deps
- name: Start API Server
run: npm run start-api
- name: Wait for API to be ready
run: npx wait-on http://localhost:8080
- name: Run Playwright tests
run: npx playwright test
- uses: actions/upload-artifact@v2
if: always()
with:
name: playwright-report
path: playwright-report/
실습 레포는 강사님께서 공유해주셨다.
테스트를 위해 주석의 조건에 맞게 코드를 작성하고 테스트를 실행하여 코드가 잘 작성되었는지 확인한다.
테스트를 실행한 이후 품절 상품에 대한 처리를 하지 않았음을 확인 할 수 있다.
pnpm test
> with-remix@ test /fast-campus-2024-fe-test-practice
> jest
FAIL test/sort.test.ts
Product.id 기준 정렬
✕ id 오름차순 정렬이 정상적으로 이루어지고, 품절 상품이 모두 맨 뒤에 정렬되어있는가
✕ id 내림차순 정렬이 정상적으로 이루어지고, 품절 상품이 모두 맨 뒤에 정렬되어있는가
Product.name 기준 정렬
✕ name 오름차순 정렬이 정상적으로 이루어지고, 품절 상품이 모두 맨 뒤에 정렬되어있는가
✕ name 내림차순 정렬이 정상적으로 이루어지고, 품절 상품이 모두 맨 뒤에 정렬되어있는가
Product.price 기준 정렬
✕ price 오름차순 정렬이 정상적으로 이루어지고, 품절 상품이 모두 맨 뒤에 정렬되어있는가
✕ price 내림차순 정렬이 정상적으로 이루어지고, 품절 상품이 모두 맨 뒤에 정렬되어있는가
테스트 실행을 통해 확인한 품절 상품에 대한 처리를 SortProduct
함수에 추가한다.
테스트 실행을 통해 조건에 맞는 로직을 정상적으로 구현했음을 확인 할 수 있다.
pnpm test
> with-remix@ test /fast-campus-2024-fe-test-practice
> jest
PASS test/sort.test.ts
Product.id 기준 정렬
✓ id 오름차순 정렬이 정상적으로 이루어지고, 품절 상품이 모두 맨 뒤에 정렬되어있는가
✓ id 내림차순 정렬이 정상적으로 이루어지고, 품절 상품이 모두 맨 뒤에 정렬되어있는가
Product.name 기준 정렬
✓ name 오름차순 정렬이 정상적으로 이루어지고, 품절 상품이 모두 맨 뒤에 정렬되어있는가
✓ name 내림차순 정렬이 정상적으로 이루어지고, 품절 상품이 모두 맨 뒤에 정렬되어있는가
Product.price 기준 정렬
✓ price 오름차순 정렬이 정상적으로 이루어지고, 품절 상품이 모두 맨 뒤에 정렬되어있는가
✓ price 내림차순 정렬이 정상적으로 이루어지고, 품절 상품이 모두 맨 뒤에 정렬되어있는가