๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Cypress

๐Ÿ“ Cypress

by frontChoi 2025. 11. 23.
๋ฐ˜์‘ํ˜•

๐Ÿคฉ E2Eํ…Œ์ŠคํŠธ๋ž€

๊ฐœ๋ฐœ๋ฌผ์„ ์‚ฌ์šฉ์ž๊ด€์ ์—์„œ ํ…Œ์ŠคํŠธ ํ•˜๋Š” ๋ฐฉ๋ฒ•

๊ฒฐ๊ณผ๋ฌผ์ด ํ™”๋ฉด์— ์˜ˆ์ƒํ•œ๋Œ€๋กœ ๋‚˜์˜ค๋Š”์ง€ ํ…Œ์ŠคํŠธํ•˜๋Š”๋ฐฉ๋ฒ•

๐Ÿ˜† Cypress ์ด๋ž€

Cypress๋Š” Javascript E2E ํ…Œ์ŠคํŠธ ๋„๊ตฌ์ค‘ ํ•˜๋‚˜์ด๋‹ค

 

 ๐Ÿ˜ ์„ค์น˜

์„ค์น˜๋Š” ์ƒ๊ฐ๋ณด๋‹ค ๊ฐ€๋Šฅํ•˜๋‹ค

npm install cypress --save-dev

 

๐Ÿšš  Cypress ํ™˜๊ฒฝ์„ค์ • ์ •๋ฆฌ

cypress ํ™˜๊ฒฝ์„ค์ •์„ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ํ•  ์ˆ˜ ์žˆ๋‹ค.

url ,ํ™˜๊ฒฝ๋ณ€์ˆ˜, ํ™”๋ฉด์‚ฌ์ด์ฆˆ ์ง€์ • , ํƒ€์ž„์•„์›ƒ ๋“ฑ๋“ฑ 

ํ˜„์žฌ๊นŒ์ง€ ์•Œ์•„๋ณธ๊ฒƒ์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค

๊ธฐ๋Šฅ์„ค๋ช…์˜ˆ์‹œ

ํ…Œ์ŠคํŠธ ๊ธฐ๋ณธ URL ์„ค์ • ํ…Œ์ŠคํŠธ ์‹คํ–‰ ์‹œ ๊ธฐ์ค€์ด ๋˜๋Š” ๊ธฐ๋ณธ ์ฃผ์†Œ๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. baseUrl: 'http://localhost:5173'
ํ…Œ์ŠคํŠธ ํŒŒ์ผ ๊ฒฝ๋กœ ์ง€์ • Cypress๊ฐ€ ํ…Œ์ŠคํŠธ ํŒŒ์ผ์„ ์ฐพ๋Š” ๊ฒฝ๋กœ๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. specPattern: 'cypress/e2e/**/*.cy.ts'
ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ์„ค์ • API ์ฃผ์†Œ, ํ† ํฐ ๋“ฑ ํ…Œ์ŠคํŠธ์—์„œ ์‚ฌ์šฉํ•  ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. env: { apiUrl: 'https://api.example.com' }
ํ”Œ๋Ÿฌ๊ทธ์ธ ๋ฐ ์ด๋ฒคํŠธ ์„ค์ • ํ…Œ์ŠคํŠธ ์‹คํ–‰ ์ „ํ›„ ์ด๋ฒคํŠธ๋‚˜ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค. setupNodeEvents(on, config) { ... }
๋ฆฌํŠธ๋ผ์ด(์žฌ์‹œ๋„) ํšŸ์ˆ˜ ์„ค์ • ํ…Œ์ŠคํŠธ ์‹คํŒจ ์‹œ ์ž๋™ ์žฌ์‹œ๋„ ํšŸ์ˆ˜๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. retries: 2
๋ฆฌํฌํ„ฐ ์„ค์ • ํ…Œ์ŠคํŠธ ๊ฒฐ๊ณผ๋ฅผ ๋‹ค์–‘ํ•œ ๋ฆฌํฌํ„ฐ๋กœ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค. reporter: 'junit'
๋ฆฌํฌํ„ฐ ์˜ต์…˜ ์„ค์ • ๋ฆฌํฌํ„ฐ์˜ ์ƒ์„ธ ์ €์žฅ ํ˜•์‹์ด๋‚˜ ๊ฒฝ๋กœ๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. reporterOptions: { mochaFile: 'results/test.xml' }
๋ทฐํฌํŠธ ํฌ๊ธฐ ์„ค์ • ๋ธŒ๋ผ์šฐ์ € ์ฐฝ ํฌ๊ธฐ๋ฅผ ์„ค์ •ํ•˜์—ฌ ๋ฐ˜์‘ํ˜• ํ…Œ์ŠคํŠธ์— ํ™œ์šฉํ•ฉ๋‹ˆ๋‹ค. viewportWidth: 1280, viewportHeight: 720
์Šคํฌ๋ฆฐ์ƒท / ๋น„๋””์˜ค ์„ค์ • ํ…Œ์ŠคํŠธ ์ค‘ ์Šคํฌ๋ฆฐ์ƒท๊ณผ ๋น„๋””์˜ค๋ฅผ ์ €์žฅํ• ์ง€ ์—ฌ๋ถ€๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. video: true, screenshotOnRunFailure: true
์ปค๋งจ๋“œ ํƒ€์ž„์•„์›ƒ ์„ค์ • ๊ฐ Cypress ๋ช…๋ น์–ด์˜ ์ตœ๋Œ€ ๋Œ€๊ธฐ ์‹œ๊ฐ„์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. defaultCommandTimeout: 8000

 

๐ŸŽฟ Cypress ์‚ฌ์šฉ๋ฒ•

ํฌ๊ฒŒ 4๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค

  • ์š”์†Œ ํƒ์ƒ‰ ๋ฐ ์„ ํƒ
  • ์‚ฌ์šฉ์ž ์ž…๋ ฅ ์‹œ๋ฎฌ๋ ˆ์ด์…˜
  • ๊ฒ€์ฆ (Assertions)
  • ๋„คํŠธ์›Œํฌ ์š”์ฒญ (Intercept / Wait)

์š”์†Œ ํƒ์ƒ‰ ๋ฐ ์„ ํƒ

cy.visit(url) ํŠน์ • ํŽ˜์ด์ง€๋กœ ์ด๋™ cy.visit('/login')
cy.get(selector) DOM ์š”์†Œ ์„ ํƒ cy.get('#username')
cy.contains(text) ํŠน์ • ํ…์ŠคํŠธ ํฌํ•จ ์š”์†Œ ์„ ํƒ cy.contains('๋กœ๊ทธ์ธ')
cy.find(selector) ํŠน์ • ์š”์†Œ ๋‚ด๋ถ€ ํƒ์ƒ‰ cy.get('.form').find('input')
cy.first() / cy.last() ์ฒซ ๋ฒˆ์งธ / ๋งˆ์ง€๋ง‰ ์š”์†Œ ์„ ํƒ cy.get('li').first()
cy.eq(index) N๋ฒˆ์งธ ์š”์†Œ ์„ ํƒ cy.get('li').eq(2)

 

์‚ฌ์šฉ์ž ์ž…๋ ฅ ์‹œ๋ฎฌ๋ ˆ์ด์…˜

๋ช…๋ น์–ด์„ค๋ช…์˜ˆ์‹œ

cy.type(text) ํ…์ŠคํŠธ ์ž…๋ ฅ cy.get('input[name=email]').type('test@test.com')
cy.clear() ์ž…๋ ฅ ํ•„๋“œ ๋น„์šฐ๊ธฐ cy.get('input').clear()
cy.click() ํด๋ฆญ cy.get('button').click()
cy.check() / cy.uncheck() ์ฒดํฌ๋ฐ•์Šค ์„ ํƒ / ํ•ด์ œ cy.get('#agree').check()
cy.select(value) <select> ์˜ต์…˜ ์„ ํƒ cy.get('select').select('Option 1')

๊ฒ€์ฆ (Assertions)

๋ช…๋ น์–ด์„ค๋ช…์˜ˆ์‹œ

cy.should(assertion, value) ๋‹จ์ผ ์–ด์„ค์…˜ cy.get('h1').should('contain', 'Welcome')
cy.should('have.class', 'active') ํด๋ž˜์Šค ํ™•์ธ cy.get('button#submit').click().should('have.class', 'active')
cy.should('be.visible') / cy.should('not.exist') ํ‘œ์‹œ/๋ถ€์žฌ ์ƒํƒœ ํ™•์ธ cy.get('.modal').should('be.visible')cy.get('.loading').should('not.exist')
cy.url().should('include', value) URL ํฌํ•จ ์—ฌ๋ถ€ ๊ฒ€์ฆ cy.url().should('include', '/dashboard')
cy.title().should('eq', value) ํŽ˜์ด์ง€ ํƒ€์ดํ‹€ ๊ฒ€์ฆ cy.title().should('eq', 'My App')

๋„คํŠธ์›Œํฌ ์š”์ฒญ (Intercept / Wait)

๋ช…๋ น์–ด์„ค๋ช…์˜ˆ์‹œ

cy.intercept(method, url) API ์š”์ฒญ ๊ฐ€๋กœ์ฑ„๊ธฐ cy.intercept('GET', '/api/user').as('getUser')
cy.wait(alias) ์š”์ฒญ ์™„๋ฃŒ ๋Œ€๊ธฐ cy.wait('@getUser')
cy.request(url) HTTP ์š”์ฒญ ๋ณด๋‚ด๊ธฐ cy.request('POST', '/api/login', { id: 'a', pw: 'b' })
.as(aliasName) alias(๋ณ„์นญ) ๋“ฑ๋ก cy.intercept('GET', '/api/user').as('getUser')
cy.get('@alias') alias ์ฐธ์กฐ cy.get('@submitBtn').click()

 

 

๐Ÿ“ Cypress ์‹คํ–‰

 npx cypress open

 

ํ•ด๋‹น ๋ช…๋ น์„ ํ†ตํ•ด ์‹คํ–‰ํ•œ๋‹ค

 

 

๐Ÿชƒ ๐Ÿ“… Cypress.confing.ts(js)

cypressํ™˜๊ฒฝ์„ค์ • ํŒŒ์ผ์ด๋‹ค baseUrl,env,viewportWidth ์ •๋„๋กœ๋งŒ ์„ค์ •ํ•˜์˜€๋‹ค.

์™ธ์— ์„ค์ •๋“ค์€ cypress๊ณต์‹ํ™ˆํŽ˜์ด์ง€์—์„œ๋„ ํ™•์ธ์ด๊ฐ€๋Šฅํ•˜๋‹ค

 

import { defineConfig } from "cypress";
import fs from "fs";
type EnvDataType = {
  baseUrl: string;
};
const envName = process.env.CYPRESS_ENV || "dev";
const envPath = `cypress.env.${envName}.json`;
let envData: EnvDataType = {
  baseUrl: ""
};
if (fs.existsSync(envPath)) {
  envData = JSON.parse(fs.readFileSync(envPath, "utf-8"));
}
export default defineConfig({
  e2e: {
    baseUrl: envData.baseUrl, // ๊ธฐ๋ณธ URL
    env: envData, // ํ™˜๊ฒฝ๋ณ€์ˆ˜
    viewportWidth: 1920 // ๋„ˆ๋น„ 1920
  }
});

 

 

๐Ÿช Cypress ์˜ˆ์ œ ์ฝ”๋“œ

๊ฐ„๋‹จํ•œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ์„ ํ•˜๊ณ ์ž ํ•œ๋‹ค.

๋‹จ์ˆœ ๋ฐฉ๋ฌธํ›„ "๋กœ๊ทธ์ธ"์ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ ์ž ํ•œ๋‹ค

describe("main view E2E testing", () => {
  it("๋กœ๊ทธ์ธ ํ…์ŠคํŠธ๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธํ•œ๋‹ค", () => {
    // ๋ฃจํŠธ ์ง„์ž…
    cy.visit("/");

    // ๋กœ๊ทธ์ธ ํ…์ŠคํŠธ๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธํ•œ๋‹ค
    cy.contains("๋กœ๊ทธ์ธ");
  });
});

export {};

 

๐Ÿšก ํšŒ์›๊ฐ€์ž… ํ™”๋ฉด ํ…Œ์ŠคํŠธ์ฝ”๋“œ ์ž‘์„ฑ

๊ฐ„๋‹จํ•œ ์ž…๋ ฅํผ์ด ์žˆ๋‹ค

์ด๋ฆ„,๋‚˜์ด,๋ฒˆํ˜ธ,์„ฑ๋ณ„,๋„์‹œ๊ฐ€ ์žˆ๊ณ 

๊ทธ๋ฆฌ๊ณ  submit ๋ฒ„ํŠผ์„ ํ†ตํ•ด ํ•ด๋‹น๊ฐ’์„ ์ดˆ๊ธฐํ™” ํ•˜๋Š” ๊ธฐ๋Šฅ์ด ์žˆ๋‹ค

 

  1. ์ด๋ฆ„,๋‚˜์ด,๋ฒˆํ˜ธ,์„ฑ๋ณ„,๋„์‹œ๋ฅผ ์ž…๋ ฅ ๋ฐ ์„ ํƒํ•œ๋‹ค
  2. submit์„ ํ†ตํ•ด ๊ฐ’์„ ์ดˆ๊ธฐํ™”ํ•œ๋‹ค
describe("ํšŒ์›๊ฐ€์ž… ํ…Œ์ŠคํŠธ", () => {
  it("ํšŒ์›๊ฐ€์ž… ํผ ์ž…๋ ฅ ", () => {
    cy.visit("/signup");

    // ์ด๋ฆ„ ์ž…๋ ฅ
    cy.get("input").eq(0).type("๊น€์•„๋ฌด๊ฐœ");
    // ๋‚˜์ด
    cy.get("input").eq(1).clear().type("33");
    // ๋ฒˆํ˜ธ
    cy.get("input").eq(2).clear().type("01022223333");
    // radio ์„ ํƒ
    cy.get("input[type='radio'][value='man']").check();
    // v-select ์„ ํƒ
    cy.get("[data-cy='city-select'] .v-field__input").click();
    cy.contains(".v-list-item", "California").click();
    // Submit ๋ฒ„ํŠผ ํด๋ฆญ
    cy.get("button[type='submit']").click();
  });
});
export {};

๐Ÿšž Homeํ™”๋ฉด ํ…Œ์ŠคํŠธ์ฝ”๋“œ ์ž‘์„ฑ

ํ™ˆ ํ™”๋ฉด์—์„œ๋Š” ๋„ค์ด๋ฒ„ ๋‰ด์Šค๋ฅผ ๊ฒ€์ƒ‰ํ•˜๋Š” ๊ธฐ๋Šฅ์ด๋‹ค

์—ฌ๊ธฐ์„œ๋Š” ํŠน๋ณ„ํ•˜๊ฒŒ cypress๋ฅผ ์ธํ„ฐ์…‰ํ„ฐ๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ๋ชจํ‚นํ•˜๊ณ ์ž ํ•œ๋‹ค

 

  1. ํ™ˆ ํ™”๋ฉด์— ์ง„์ž…ํ•˜๋‹ค
  2. ๋„ค์ด๋ฒ„ ๋‰ด์Šค๋ฅผ ์กฐํšŒํ•œ๋‹ค
  3. ๊ฒ€์ฆ์€ row ๊ฐœ์ˆ˜๋ฅผ ํ™•์ธํ•œ๋‹ค
describe("Home View Testing", () => {
  it("๋„คํŠธ์›Œํฌ ์š”์ฒญ (Intercept / Wait)", () => {
    // ๋„ค์ด๋ฒ„ api ์ธํ„ฐ์…‰ํ„ฐ
    cy.intercept("GET", "/api/navernews*", {
      total: 949,
      lastBuildDate: "Thu, 20 Nov 2025 08:21:37 +0900",
      display: 100,
      start: 1,
      items: [
        {
          title: "์„ธ์ƒ์˜ ๋ชจ๋“  ๊ณต๊ฐ„์„ PLAYํ•˜๋‹ค…<b>์–ดํ”Œ๋ ˆ์ด์ฆˆ</b>(APLAYZ) ๋ฐฐ์ •์ง„ ๋Œ€ํ‘œ",
          originallink: "https://www.venturesquare.net/1014661",
          link: "https://www.venturesquare.net/1014661",
          description: "ํ”Œ๋žซํผ, <b>์–ดํ”Œ๋ ˆ์ด์ฆˆ</b>(APLAYZ) ๋ฐฐ์ •์ง„ ๋Œ€ํ‘œ ์‹๋‹น, ์นดํŽ˜, ์ „์‹œ์žฅ, ๊ทธ๋ฆฌ๊ณ  ์ฐจ๋Ÿ‰๊นŒ์ง€. ์–ด๋””์„œ๋‚˜... ๋ฎค์งํ…Œํฌ ์Šคํƒ€ํŠธ์—… <b>์–ดํ”Œ๋ ˆ์ด์ฆˆ</b>(APLAYZ)๋Š” ๊ทธ ์ผ์ƒ์  ๋ฐฐ๊ฒฝ์Œ์„ ๋ฐ์ดํ„ฐ์™€ ์ธ๊ณต์ง€๋Šฅ์œผ๋กœ... ",
          pubDate: "Tue, 18 Nov 2025 09:09:00 +0900"
        },
        {
          title: "๊ฐ•๋‚จ๊ตฌ, ์ŠคํŽ˜์ธ ‘์Šค๋งˆํŠธ์‹œํ‹ฐ ๋ฐ•๋žŒํšŒ’ ์ฐธ๊ฐ€... 457๋งŒ๋ถˆ ๊ทœ๋ชจ ์ƒ๋‹ด ์„ฑ๊ณผ",
          originallink: "https://weeklytrade.co.kr/news/view.html?section=1&category=160&item=&no=97212",
          link: "https://weeklytrade.co.kr/news/view.html?section=1&category=160&item=&no=97212",
          description: "โ–ฒ‘<b>์–ดํ”Œ๋ ˆ์ด์ฆˆ</b>’๋Š” ์ธ๊ณต์ง€๋Šฅ์„ ํ™œ์šฉํ•ด ๊ณต๊ฐ„๋ณ„๋กœ ์–ด์šธ๋ฆฌ๋Š” ์Œ์•…์„ ์ž๋™์œผ๋กœ ์ถ”์ฒœํ•˜๋Š” ์‹œ์Šคํ…œ์„ ์„ ๋ณด์˜€๋‹ค. โ–ฒ‘ํ๋น…’์€ ๊ณต๊ณต ๋ฐ์ดํ„ฐ๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ฐœ์ธ์ •๋ณด ๋ณดํ˜ธ ๊ธฐ๋Šฅ์ด ๊ฐ•ํ™”๋œ ์–ธ์–ด์ฒ˜๋ฆฌ ๊ธฐ์ˆ ์„... ",
          pubDate: "Tue, 11 Nov 2025 01:50:00 +0900"
        }
      ]
    }).as("naverNews");
    cy.visit("/");
    // ์™„๋ฃŒ๋ฅผ ๋Œ€๊ธฐํžŒ๋‹ค
    cy.wait("@naverNews");

    // ๋ฐฉ๋ฌธ๊ฒ€์ฆ
    cy.url().should("include", "/");
    // ์‹ค์ œ Row ๊ฐœ์ˆ˜ ๊ฒ€์ฆ
    cy.get("table tbody tr").should("have.length", 2);
  });
});

export {};

 

 

์—ฌ๊ธฐ์„œ ์ฃผ๋ชฉํ• ์ ์€ intercept๋ฅผ ํ†ตํ•ด ๋„คํŠธ์›Œํฌ๋ฅผ ๊ฐ€์งœ๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์ด๋‹ค.

์—ฌ๊ธฐ์„œ๋Š” 2๊ฐœ์ •๋„ ๋ฆฌํ„ดํ•˜๊ฒŒ๋” ๊ฐ€์งœ๋กœ ๊ตฌํ˜„ํ•˜์˜€๊ณ ,

์‹ค์ œ ๋กœ์šฐ ๊ฐœ์ˆ˜๊ฐ€ 2๊ฐœ์ธ์ง€ ๊ฒ€์ฆํ•œ๋‹ค

// ์™ธ๋ถ€ ์˜์กด์„ฑ ์ž‡๋Š”๊ฒƒ๋“ค์„ ๊ฐ€์งœ๋กœ ๊ตฌํ˜„ํ•œ๋‹ค.
cy.intercept("GET", "/api/navernews*", {
      total: 949,
      lastBuildDate: "Thu, 20 Nov 2025 08:21:37 +0900",
      display: 100,
      start: 1,
      items: [
        {
          title: "์„ธ์ƒ์˜ ๋ชจ๋“  ๊ณต๊ฐ„์„ PLAYํ•˜๋‹ค…<b>์–ดํ”Œ๋ ˆ์ด์ฆˆ</b>(APLAYZ) ๋ฐฐ์ •์ง„ ๋Œ€ํ‘œ",
          originallink: "https://www.venturesquare.net/1014661",
          link: "https://www.venturesquare.net/1014661",
          description: "ํ”Œ๋žซํผ, <b>์–ดํ”Œ๋ ˆ์ด์ฆˆ</b>(APLAYZ) ๋ฐฐ์ •์ง„ ๋Œ€ํ‘œ ์‹๋‹น, ์นดํŽ˜, ์ „์‹œ์žฅ, ๊ทธ๋ฆฌ๊ณ  ์ฐจ๋Ÿ‰๊นŒ์ง€. ์–ด๋””์„œ๋‚˜... ๋ฎค์งํ…Œํฌ ์Šคํƒ€ํŠธ์—… <b>์–ดํ”Œ๋ ˆ์ด์ฆˆ</b>(APLAYZ)๋Š” ๊ทธ ์ผ์ƒ์  ๋ฐฐ๊ฒฝ์Œ์„ ๋ฐ์ดํ„ฐ์™€ ์ธ๊ณต์ง€๋Šฅ์œผ๋กœ... ",
          pubDate: "Tue, 18 Nov 2025 09:09:00 +0900"
        },
        {
          title: "๊ฐ•๋‚จ๊ตฌ, ์ŠคํŽ˜์ธ ‘์Šค๋งˆํŠธ์‹œํ‹ฐ ๋ฐ•๋žŒํšŒ’ ์ฐธ๊ฐ€... 457๋งŒ๋ถˆ ๊ทœ๋ชจ ์ƒ๋‹ด ์„ฑ๊ณผ",
          originallink: "https://weeklytrade.co.kr/news/view.html?section=1&category=160&item=&no=97212",
          link: "https://weeklytrade.co.kr/news/view.html?section=1&category=160&item=&no=97212",
          description: "โ–ฒ‘<b>์–ดํ”Œ๋ ˆ์ด์ฆˆ</b>’๋Š” ์ธ๊ณต์ง€๋Šฅ์„ ํ™œ์šฉํ•ด ๊ณต๊ฐ„๋ณ„๋กœ ์–ด์šธ๋ฆฌ๋Š” ์Œ์•…์„ ์ž๋™์œผ๋กœ ์ถ”์ฒœํ•˜๋Š” ์‹œ์Šคํ…œ์„ ์„ ๋ณด์˜€๋‹ค. โ–ฒ‘ํ๋น…’์€ ๊ณต๊ณต ๋ฐ์ดํ„ฐ๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ฐœ์ธ์ •๋ณด ๋ณดํ˜ธ ๊ธฐ๋Šฅ์ด ๊ฐ•ํ™”๋œ ์–ธ์–ด์ฒ˜๋ฆฌ ๊ธฐ์ˆ ์„... ",
          pubDate: "Tue, 11 Nov 2025 01:50:00 +0900"
        }
      ]
    }).as("naverNews");
    

 // ์‹ค์ œ Row ๊ฐœ์ˆ˜ ๊ฒ€์ฆ
 cy.get("table tbody tr").should("have.length", 2);

 

๐Ÿ›ต  CypressViewํ™”๋ฉด ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์ž‘์„ฑ

ํ•ด๋‹นํ™”๋ฉด์—์„œ๋Š”

* h1ํ…์ŠคํŠธ ๊ฒ€์ฆ

* ๋ฒ„ํŠผํ™œ์„ฑํ™” ์‹œ์— ์ƒ‰์ƒ๋ณ€๊ฒฝ ๊ฒ€์ฆ

* ์ฒดํฌ๋ฐ•์Šค ํด๋ฆญ์‹œ์— h3 visible/invisible ํ•˜๋Š”์ง€ ๊ฒ€์ฆ

* ํŽ˜์ด์ง€ title ๊ฒ€์ฆ

describe("Cypress View Testing", () => {
  it(" ๊ฒ€์ฆ (Assertions)", () => {
    cy.visit("/cypressview");

    // ๋ฐฉ๋ฌธ๊ฒ€์ฆ
    cy.url().should("include", "/cypressview");

    // h1 ํ…์ŠคํŠธ ๊ฒ€์ฆ
    cy.get("h1").contains("H1");
    // ๋ฒ„ํŠผ ํ™œ์„ฑํ™”
    cy.get("button").click().should("have.class", "bg-indigo-darken-3");

    // visible/invisible
    cy.get(".v-switch input[type='checkbox']").check({ force: true });
    cy.get("h3").should("be.visible");
    cy.get(".v-switch input[type='checkbox']").uncheck({ force: true });
    cy.get("h3").should("not.exist");

    // ํƒ€์ดํ‹€ ๊ฒ€์ฆ
    cy.title().should("eq", "MAXGUN");
  });
});
export {};

 

 

๐Ÿ“ˆ command.ts

๋ฐ˜๋ณต์ ์ธ ์ฝ”๋“œ์— ๋Œ€ํ•ด์„œ ๋ชจ๋“ˆํ™”ํ•˜์—ฌ ์žฌ์‚ฌ์šฉํ•˜๋Š”๋ฐ ์‚ฌ์šฉ

// cypress/support/commands.ts
/**
 * cypress login command
 */
export const login = () => {
  // ๋กœ๊ทธ์ธ ์ด๋™
  cy.visit("/login");
};
export {};
```
// cypress/e2e/spec.cy.ts
import { login } from "../support/commands";

describe("๋กœ๊ทธ์ธ ๋ฐฉ๋ฌธ ํ…Œ์ŠคํŠธ", () => {
  before(() => {
    // ๋ฐ˜๋ณต์ฝ”๋“œ ์ ์šฉ
    login();
  });

  it("๋กœ๊ทธ์ธ ์„ฑ๊ณต", () => {
    // ๋กœ๊ทธ์ธ ํผ ์ž…๋ ฅ
    cy.get("input").eq(0).type("cdg@aplayz.co.kr");
    cy.get("input").eq(1).type("chleorjs12@");
    // ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ ํด๋ฆญ
    cy.get("button").click();
    // main ํ™”๋ฉด ์ด๋™ ํ™•์ธ
    cy.url().should("include", "/main");
  });
});
export {};

 

๐Ÿ“ e2e.ts

e2e.ts๋Š” Cypress๊ฐ€ E2E ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•  ๋•Œ ๊ฐ€์žฅ ๋จผ์ € ๋กœ๋“œ๋˜๋Š” ์„ค์ • ํŒŒ์ผ์ž…๋‹ˆ๋‹ค. ์ฆ‰, ๋ชจ๋“  ํ…Œ์ŠคํŠธ(*.cy.ts ํŒŒ์ผ ๋“ฑ)๊ฐ€ ์‹คํ–‰๋˜๊ธฐ ์ „์— ๊ณตํ†ต์ ์œผ๋กœ ์ ์šฉํ•  ์„ค์ •, ํ›…, ํ”Œ๋Ÿฌ๊ทธ์ธ, ์ „์—ญ ๋ช…๋ น์–ด ๋“ฑ์„ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ๊ณณ์ž…๋‹ˆ๋‹ค.

 

์˜ˆ์‹œ๋กœ beforeAll,beforeEach์— ๋กœ๊ทธ๋ฅผ ์ ์šฉํ•ด ๋ณด์•˜๋‹ค

// ***********************************************************
// This example support/e2e.ts is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************

// Import commands.js using ES2015 syntax:
import "./commands";

// ๊ณตํ†ต ๋กœ์ง ์ถ”๊ฐ€
before(() => {
  cy.log("๐ŸŒŸ ๋ชจ๋“  ํ…Œ์ŠคํŠธ ์ „ ํ•œ ๋ฒˆ ์‹คํ–‰");
});

beforeEach(() => {
  cy.log("โžก๏ธ ๊ฐ ํ…Œ์ŠคํŠธ ์ „ ์‹คํ–‰");
});

 

 

๊ธฐ๋ณธ์ ์ธ Cypressํ™œ์šฉ๋ฒ•์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด์•˜๊ณ  

๋‹ค์Œ์—๋Š” cypress๋ฅผ ํ†ตํ•ด ์ปค๋ฒ„๋ฆฌ์ง€ ์ž๋™ํ™” N์‹œ๊ฐ„๋งˆ๋‹ค ๊ฒ€์ฆ ํ•˜๋Š”๊ฒƒ์„ ์•Œ์•„๋ณผ ์˜ˆ์ •์ด๋‹ค

๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€