๐Ÿ‘ฉโ€๐Ÿ’ป
Megaptera Frontend
  • ์ฃผ์ฐจ๋ณ„ ํ•™์Šต
    • megaptera-front
    • 1. ๊ฐœ๋ฐœ ํ™˜๊ฒฝ
      • 1. ๊ฐœ๋ฐœ ํ™˜๊ฒฝ
      • 2. TypeScript
      • 3. React
      • 4. Testing Library
      • 5. Parcel & ESLint
      • ํ•œ ์ฃผ๋ฅผ ๋งˆ์น˜๋ฉฐ
    • 2. JSX
      • 1. JSX
      • ํ•œ ์ฃผ๋ฅผ ๋งˆ์น˜๋ฉฐ
    • 3. React๋กœ ์‚ฌ๊ณ ํ•˜๊ธฐ
      • 1. React Component
      • 2. React State
      • ํ•œ ์ฃผ๋ฅผ ๋งˆ์น˜๋ฉฐ
    • 4. React Hooks
      • 1. Express
      • 2. Fetch API & CORS
      • 3. React์˜ Hook
      • 4. useRef & Custom Hook
      • 5. usehooks-ts
      • ํ•œ ์ฃผ๋ฅผ ๋งˆ์น˜๋ฉฐ
    • 5. ํ…Œ์ŠคํŠธ
      • 1. TDD
      • 2. React Testing Library
      • 3. MSW
      • 4. Playwright
      • ํ•œ ์ฃผ๋ฅผ ๋งˆ์น˜๋ฉฐ
    • 6. External Store
      • 1. External Store
      • 2. TSyringe
      • 3. Redux ๋”ฐ๋ผํ•˜๊ธฐ
      • 4. usestore-ts
      • ํ•œ ์ฃผ๋ฅผ ๋งˆ์น˜๋ฉฐ
    • 7. React Router
      • 1. Routing
      • 2. Routes
      • 3. Router
      • 4. Navigation
      • ํ•œ ์ฃผ๋ฅผ ๋งˆ์น˜๋ฉฐ
    • 8. CSS in JS
      • 1. Design System
      • 2. Style Basics
      • 3. CSS in JS
      • 4. styled-components
      • 5. props์™€ attrs
      • 6. Global Style & Theme
      • ํ•œ ์ฃผ๋ฅผ ๋งˆ์น˜๋ฉฐ
    • 9. ์‡ผํ•‘๋ชฐ ๋ชฉ๋ก, ์ƒํ’ˆ ํŽ˜์ด์ง€
      • 1. ๊ฐœ๋ฐœํ•˜๊ธฐ ์ „ ์ค€๋น„
      • 2. ๋ชฉ๋ก ๋ณด๊ธฐ
      • 3. ์ƒํ’ˆ ์ƒ์„ธ ๋ณด๊ธฐ
      • 4. ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋ณด๊ธฐ
      • 5. ์žฅ๋ฐ”๊ตฌ๋‹ˆ์— ์ƒํ’ˆ ๋‹ด๊ธฐ
      • ํ•œ ์ฃผ๋ฅผ ๋งˆ์น˜๋ฉฐ
    • 10. ์‚ฌ์šฉ์ž ์ธ์ฆ, ์ธ๊ฐ€
      • 1. ๋กœ๊ทธ์ธ
      • 2. ๋กœ๊ทธ์•„์›ƒ
      • 3. ํšŒ์›๊ฐ€์ž…
      • 4. ์ฃผ๋ฌธ ๋ชฉ๋ก & ์ฃผ๋ฌธ ์ƒ์„ธ
      • ํ•œ ์ฃผ๋ฅผ ๋งˆ์น˜๋ฉฐ
    • 11. ์ฃผ๋ฌธ, ๊ฒฐ์ œ
      • 1. ๋ฐฐ์†ก ์ •๋ณด ์ž…๋ ฅ
      • 2. ํฌํŠธ์› ๊ฒฐ์ œ ์š”์ฒญ
      • 3. ๋ฐฐ์†ก ๋ฐ ๊ฒฐ์ œ ์ •๋ณด ์ „๋‹ฌ
      • ํ•œ ์ฃผ๋ฅผ ๋งˆ์น˜๋ฉฐ
    • 12. ์–ด๋“œ๋ฏผ
      • 1. ๊ด€๋ฆฌ์ž ์›น ์‚ฌ์ดํŠธ ๊ฐœ๋ฐœ ์‹œ์ž‘
      • 2. ๋กœ๊ทธ์ธ, ์‚ฌ์šฉ์ž ๋ชฉ๋ก
      • 3. ์นดํ…Œ๊ณ ๋ฆฌ ๊ด€๋ฆฌ
      • 4. ์ฃผ๋ฌธ ๊ด€๋ฆฌ
      • 5. ์ƒํ’ˆ ๊ด€๋ฆฌ
      • ํ•œ ์ฃผ๋ฅผ ๋งˆ์น˜๋ฉฐ
Powered by GitBook
On this page
  • 1. E2E(End to End) Test
  • ์žฅ์ 
  • E2E ํ…Œ์ŠคํŠธ ๋„๊ตฌ
  • 2. Playwright
  • ์‚ฌ์šฉ ๋ฐฉ๋ฒ•
  • ํ…Œ์ŠคํŠธ ์‹คํ–‰
  • 3. Headless Chrome
  • Headless Browser
  • ์‚ฌ์šฉ ์˜ˆ์‹œ
  • 4. Puppeteer
  • 6. CodeceptJS
  • ์‚ฌ์šฉ ๋ฐฉ๋ฒ•
  1. ์ฃผ์ฐจ๋ณ„ ํ•™์Šต
  2. 5. ํ…Œ์ŠคํŠธ

4. Playwright

Previous3. MSWNextํ•œ ์ฃผ๋ฅผ ๋งˆ์น˜๋ฉฐ

Last updated 2 years ago

1. E2E(End to End) Test

End To End ํ…Œ์ŠคํŠธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ํ๋ฆ„์„ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋๊นŒ์ง€ ํ…Œ์ŠคํŠธํ•˜๋Š” ๊ฒƒ

์‘์šฉ ํ”„๋กœ๊ทธ๋žจ ํ๋ฆ„์ด ์˜ˆ์ƒ๋Œ€๋กœ ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ์ฒ˜์Œ๋ถ€ํ„ฐ ๋๊นŒ์ง€ ์ „์ฒด ์†Œํ”„ํŠธ์›จ์–ด ์ œํ’ˆ์„ ํ…Œ์ŠคํŠธํ•˜๋Š” ๋ฐฉ๋ฒ• ์ œํ’ˆ์˜ ์‹œ์Šคํ…œ ์ข…์†์„ฑ์„ ์ •์˜ํ•˜๊ณ  ํ†ตํ•ฉ๋œ ๋ชจ๋“  ๋ถ€๋ถ„์ด ์˜ˆ์ƒ๋Œ€๋กœ ํ•จ๊ป˜ ์ž‘๋™ํ•˜๋„๋ก ํ•จ ์ฃผ์š” ๋ชฉ์ ์€ ์‹ค์ œ ์‚ฌ์šฉ์ž ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ํ•˜๊ณ , ํ†ตํ•ฉ ๋ฐ ๋ฐ์ดํ„ฐ ๋ฌด๊ฒฐ์„ฑ์„ ์œ„ํ•ด ํ…Œ์ŠคํŠธ ์ค‘์ธ ์‹œ์Šคํ…œ๊ณผ ํ•ด๋‹น ๊ตฌ์„ฑ ์š”์†Œ์˜ ์œ ํšจ์„ฑ์„ ๊ฒ€์‚ฌํ•˜์—ฌ ์ตœ์ข… ์‚ฌ์šฉ์ž์˜ ๊ฒฝํ—˜์—์„œ ํ…Œ์ŠคํŠธํ•˜๋Š” ๊ฒƒ

์žฅ์ 

  • ํ…Œ์ŠคํŠธ ๋ฒ”์œ„ ํ™•์žฅ

  • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ •ํ™•์„ฑ์„ ๋ณด์žฅ

  • ์ถœ์‹œ ๊ธฐ๊ฐ„ ๋‹จ์ถ•

  • ๋น„์šฉ ์ ˆ๊ฐ

  • ๋ฒ„๊ทธ ๊ฐ์ง€

E2E ํ…Œ์ŠคํŠธ ๋„๊ตฌ

  • Headless Browser

  • : ํฌ๋กฌ์„ ํ—ค๋“œ๋ฆฌ์Šค ๋ธŒ๋ผ์šฐ์ €๋กœ ํ…Œ์ŠคํŠธ (Headless Chrome์ด ๋‚˜์™€์„œ ๊ฐœ๋ฐœ ์ค‘๋‹จ)

  • Puppeteer : Headless Chrome์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ตฌ๊ธ€์—์„œ ๋งŒ๋“  ๋„๊ตฌ

  • Playwright : MS์—์„œ ๋งŒ๋“  ํ…Œ์ŠคํŠธ ์ง€์› ๋„๊ตฌ, ๋ชจ๋“  ๋ธŒ๋ผ์šฐ์ €๋ฅผ ์ง€์›

  • CodeceptJS : ๋‹จ์ˆœํ•˜๋ฉด์„œ ์ฝ๊ธฐ ํŽธํ•จ

2. Playwright

๐Ÿ’ก ์›น ๋ธŒ๋ผ์šฐ์ € ๊ธฐ๋ฐ˜ E2E ํ…Œ์ŠคํŠธ ์ž๋™ํ™” ๋„๊ตฌ API ์ œ๊ณต , ํ…Œ์ŠคํŠธ ๋Ÿฌ๋„ˆ๋„ ์ง€์› Headless Chrome์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ Puppeteer๋ฅผ ๊ณ„์Šนํ•˜๋ฉด์„œ, ๋” ๋งŽ์€ ์›น ๋ธŒ๋ผ์šฐ์ €๋ฅผ ์ง€์›

API๋ฅผ ์กฐ์ž‘ํ•ด์„œ ์ž๋™ํ™”ํ•˜๊ฑฐ๋‚˜, ํฌ๋กค๋งํ•  ๋•Œ๋„ ์‚ฌ์šฉ

๐Ÿšจ ์ฃผ์˜์ 

์ง„์งœ ์ž‘๋™ํ•˜๋Š” ํ…Œ์ŠคํŠธ๋ฅผ ํ•˜๋Š” ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ํ”„๋กœ๋•์…˜์—์„œ ์‚ฌ์šฉํ•˜๋ฉด ์•ˆ ๋จ ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ์„ ๊ตฌ์ถ•ํ•ด๋†“๊ณ  ๋Œ๋ ค์•ผ ํ•จ

์‚ฌ์šฉ ๋ฐฉ๋ฒ•

Playwright ํŒจํ‚ค์ง€ ์„ค์น˜

npm i -D @playwright/test eslint-plugin-playwright

์„œ๋ฒ„ ๋„์šฐ๊ธฐ

npx nodemon app.ts

playwright.config.ts ํŒŒ์ผ ์ƒ์„ฑ

import {PlaywrightTestConfig} from '@playwright/test';

const config: PlaywrightTestConfig = {
    testDir: './tests',
    retries: 0,
    use: {
        channel: 'chrome',
        baseURL: 'http://localhost:8080',
        headless: !!process.env.CI,
        screenshot: 'only-on-failure',
    },
};

export default config;
  • ์‹คํ–‰ ๋ฐฉ๋ฒ•

CI=true npx playwright test

tests/.eslintrc.js ํŒŒ์ผ ์ƒ์„ฑ

module.exports = {
    env: {
        jest: false,
    },
    extends: ['plugin:playwright/playwright-test'],
    rules: {
        'import/no-extraneous-dependencies': 'off',
    },
};

tests/home.spec.ts ํŒŒ์ผ ์ž‘์„ฑ

import {test, expect} from '@playwright/test';

test('Filter products', async ({page}) => {
    await page.goto('/');

    await expect(page.getByText('Apple')).toBeVisible();

    const searchInput = page.getByLabel('Search'); // label๋กœ ์ฐพ์€ input์„ ์˜๋ฏธ 

    await searchInput.fill('a');

    await expect(page.getByText('Apple')).toBeVisible();

    await searchInput.fill('aa');

    await expect(page.getByText('Apple')).toBeHidden();
});

test('Click the โ€œIncreaseโ€ button', async ({page}) => {
    await page.goto('/');

    const count = 13;

    await Promise.all((
        [...Array(count)].map(async () => {
            await page.getByText('Increase').click();
        })
    ));

    await expect(page.getByText(`${count}`)).toBeVisible();
});

๐Ÿ’ก ๊ฐ€๋Šฅํ•œ ๋‹จ์ˆœํ•˜๊ฒŒ ์ž‘์„ฑํ•˜๋ฉด ์ข‹์Œ

ํ…Œ์ŠคํŠธ ์‹คํ–‰

npx playwright test

.gitignore ํŒŒ์ผ์— ์—๋Ÿฌ ์ƒํ™ฉ์˜ ์Šคํฌ๋ฆฐ์ƒท ๋“ฑ์ด ๋‹ด๊ธฐ๋Š” test-results ๋””๋ ‰ํ† ๋ฆฌ ์ถ”๊ฐ€

/test-results/

3. Headless Chrome

Headless Browser

๊ทธ๋ž˜ํ”ฝ ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค(GUI)๊ฐ€ ์—†๋Š” ์›น ๋ธŒ๋ผ์šฐ์ € ํ™”๋ฉด์— ๋œจ์ง€ ์•Š๊ณ  ๋’ค์—์„œ ์‹คํ–‰๋˜๋Š” ๊ฒƒ โ†’ ์†๋„๊ฐ€ ๋น ๋ฆ„ ํ—ค๋“œ๋ฆฌ์Šค ๋ธŒ๋ผ์šฐ์ €๋Š” ๋ˆˆ์— ๋ณด์ด๋Š” UI ์…ธ์ด ํ•„์š”ํ•˜์ง€ ์•Š์€ ์ž๋™ํ™”๋œ ํ…Œ์ŠคํŠธ ๋ฐ ์„œ๋ฒ„ ํ™˜๊ฒฝ์„ ์œ„ํ•œ ๋„๊ตฌ

๊ตฌ๊ธ€ ํฌ๋กฌ ๋ฒ„์ „ 59๋ถ€ํ„ฐ ๋ธŒ๋ผ์šฐ์ €์˜ ์›๊ฒฉ ์ œ์–ด๋ฅผ ์œ„ํ•œ ๋„ค์ดํ‹ฐ๋ธŒ ์ง€์›์ด ์ œ๊ณต, Mac ๋ฐ Linux์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅ

์‚ฌ์šฉ ์˜ˆ์‹œ

  • ์‹ค์ œ ์›น ํŽ˜์ด์ง€์— ๋Œ€ํ•ด ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰

  • ๋ธŒ๋ผ์šฐ์ €๊ฐ€ URL์„ ๋ Œ๋”๋งํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๊ฒ€์‚ฌ

  • ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰์‹œํ‚ค๊ณ  ๋‹ค๋ฅธ ์ž‘์—…์„ ํ•  ๋•Œ (ํ—ค๋“œ๋ฆฌ์Šค๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ, ํฌ์ปค์Šค๋ฅผ ๊ฐ€์ ธ๊ฐ€์„œ ๋‹ค๋ฅธ ์ž‘์—…์„ ํ•˜๊ธฐ ๋ถˆํŽธํ•จ)

4. Puppeteer

ํฌ๋กฌ ์ž๋™ํ™”๋ฅผ ์œ„ํ•œ Node.js ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ DevTools ํ”„๋กœํ† ์ฝœ์„ ํ†ตํ•ด ํ—ค๋“œ๋ฆฌ์Šค Chrome ๋˜๋Š” Chromium์„ ์ œ์–ดํ•˜๊ธฐ ์œ„ํ•œ ๊ณ ๊ธ‰ API๋ฅผ ์ œ๊ณตํ•˜๋Š” ๋…ธ๋“œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

ํ—ค๋“œ๋ฆฌ์Šค ๋ชจ๋“œ์—์„œ ์‹คํ–‰๋˜์ง€๋งŒ, ์ „์ฒด(non-headless) Chrome/Chromium์—์„œ ์‹คํ–‰๋˜๋„๋ก ๊ตฌ์„ฑํ•  ์ˆ˜๋„ ์žˆ์Œ

6. CodeceptJS

์ธ๊ฐ„ ์นœํ™”์ ์ธ E2E ํ…Œ์ŠคํŒ… ๋„๊ตฌ ๋‹จ์ˆœํ•˜๋ฉด์„œ๋„ ์ฝ๊ธฐ ํŽธํ•จ โ†’ ํ˜‘์—…๊ณผ ์†Œํ†ต์ด ํŽธ๋ฆฌ Playwright์„ ๊ธฐ๋ณธ์œผ๋กœ ์“ธ ์ˆ˜ ์žˆ์Œ

๐ŸฅŠ CodeceptJS vs Playwright

๊ฐ„๋‹จํ•œ ์„œ๋น„์Šค๋Š” CodeceptJS, ์ข€ ๋” ๋ณต์žกํ•˜๊ณ  ์ž์„ธํ•œ ๋‚ด์šฉ์„ ์ฒ˜๋ฆฌํ•˜๋ ค๋ฉด Playwright์„ ์‚ฌ์šฉ

์‚ฌ์šฉ ๋ฐฉ๋ฒ•

ํŒจํ‚ค์ง€ ์„ค์น˜

npx create-codeceptjs .
  • package.json ํŒŒ์ผ์˜ ๋“ค์—ฌ์“ฐ๊ธฐ๊ฐ€ ๋ณ€๊ฒฝ๋จ์— ์ฃผ์˜

ํ”„๋กœ์ ํŠธ ์„ธํŒ…

npx codeceptjs init

์‹œ๋‚˜๋ฆฌ์˜ค ์ž‘์„ฑ

์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ์—ฌ๋Ÿฌ ๊ฐœ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Œ

Feature('My First Test');

Scenario('test something', ({ I }) => {
  I.amOnPage('https://github.com');
  I.see('GitHub');
});

์‹คํ–‰ํ•˜๊ธฐ

# ์›น ๋ธŒ๋ผ์šฐ์ €๋ฅผ ํ™”๋ฉด์— ๋„์›Œ ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰
npm run codeceptjs

# ์›น ๋ธŒ๋ผ์šฐ์ €๋ฅผ ํ™”๋ฉด์— ๋„์šฐ์ง€ ์•Š๊ณ  ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰
npm run codeceptjs:headless

# ์›น ๋ธŒ๋ผ์šฐ์ €์— CodeceptUI๋ฅผ ๋„์›Œ ํ›จ์”ฌ ํŽธํ•˜๊ฒŒ ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰
npm run codeceptjs:ui

headless: !!process.env.CI : CI ํ™˜๊ฒฝ์ด ์žกํ˜€์žˆ์„ ๊ฒฝ์šฐ ๋กœ ๋„์šฐ๊ธฐ(์•„๋‹Œ ๊ฒฝ์šฐ ๊ทธ๋ƒฅ ๋„์›€)

What is End-to-End (E2E) Testing?
Selenium
PhantomJS
Playwright
playwright github
Playwright Configuration
Ashal์˜ Playwright
๐Ÿ”— ์‹ค์Šต ๋งํฌ
ํ—ค๋“œ๋ฆฌ์Šค
Headless Chrome
headless browser
Puppeteer ๊ณต์‹ ๋ฌธ์„œ
Overview of Puppeteer
Getting Started with Headless Chrome
CodeceptJS
CodeceptJS 3 ์‹œ์ž‘ํ•˜๊ธฐ
CodeceptJS ์‚ฌ์šฉ