THE DEVLOG

scribbly.

자주쓰는 라이브러리

2025.06.25 01:07:43

예제 : 링크 이동 테스트

cypress.config.ts

import { defineConfig } from "cypress";

export default defineConfig({
  e2e: {
    baseUrl: "http://localhost:3000", // 기본 주소 추가
    setupNodeEvents(on, config) {},
  },
  component: {
    devServer: {
      framework: "next",
      bundler: "webpack",
    },
  },
});

 localhost를 기본 url로 e2e config에 추가하고

npm run dev를 실행해 서버를 켜준다.

 

테스트 코드 작성

cypress/e2e/pages.cy.ts

 describe("Navigation", () => {
  it("should navigate to the about page", () => {
    cy.visit("/");
    cy.get('a[href*="about"]').click();
    cy.url().should("include", "/about");
  });
});
  1. /에 접속한다
  2. about으로 가는 링크 태그를 찾아 클릭한다
  3. /about에 접속된다.

컴포넌트 작성

app/page.tsx

import Link from "next/link";

export default function Home() {
  return (
    <div>
      <Link href="/about">
        <h2>더 알아보기</h2>
      </Link>
    </div>
  );
}

app/about/page.tsx

import Link from "next/link";

export default function About() {
  return (
    <div>
      알아보는 페이지
    </div>
  );
}

테스팅

npm run cypress:open으로 E2E 테스트를 클릭하고,

spec에서 pages.cy.ts를 실행하면 테스트가 통과된다.

 

Cypress 테스트 코드 작성

 Cypress는 크게 '선택', '행동', '검증'의 세 단계를 거친다.

선택

cy.get(선택자)의 구조를 띄며 선택자는 document.querySelector()와 같은 css 선택자를 사용한다.

cy.get('input[name="email"]') // name="email"인 input 태그 선택
선택자의미예시
태그특정 태그cy.get('button')
클래스.클래스명cy.get('.submit-btn')
ID#아이디명cy.get('#login-form')
속성[속성=값]cy.get('[name="email"]')
복합div.class#idcy.get('form.login-form')
포함 텍스트cy.contains() 사용cy.contains('로그인')

cy.contains(매처)는 요소의 text가 특정 값인 첫번째 태그를 찾는다.

<div>
  <button class="login-button">로그인</button>
  <a href="/signup">회원가입</a>
</div>
cy.get('button') // 버튼이 하나뿐일 땐 가능
cy.get('.login-button') // 클래스 기준
cy.get('button.login-button') // 태그 + 클래스
cy.get('a[href="/signup"]') // 태그 + 속성
cy.contains('로그인') // <button>로그인</button> 찾음
cy.contains('회원가입') // <a>회원가입</a> 찾음
cy.contains('button', '로그인') // 태그가 button인 요소 중 '로그인' 찾음
cy.contains('.login-button', '로그인') // 클래스가 login-button인 요소 중 '로그인' 포함된 것 찾음

 

행동 명령어

명령어설명
.click()클릭
.type()텍스트 입력
.clear()입력값 제거
.check() / .uncheck()체크박스 조작
.select()드롭다운 선택
.focus() / .blur()포커스/포커스 해제
.scrollIntoView()스크롤 이동
.trigger()이벤트 직접 실행

1. .click()

클릭
cy.get('button').click()

  • 일반적인 클릭
  • 좌표 클릭도 가능: .click(50, 20)
  • force 클릭도 가능: .click({ force: true }) (숨겨진 버튼 강제 클릭)

2. .type()

텍스트 입력
cy.get('input[name="email"]').type('hello@example.com')

  • 기본적으로 실제 사람이 타이핑하듯 입력됨
  • 빠르게 입력: .type('hello', { delay: 0 })
  • 특수 키 지원: {enter}, {esc}, {backspace}
cy.get('input').type('비밀번호123{enter}')

3. .clear()

입력된 텍스트 지우기
cy.get('input[name="search"]').clear()

  • .type() 전에 호출하면 항상 초기화 가능

4. .check(), .uncheck()

체크박스 선택/해제
cy.get('input[type="checkbox"]').check()
cy.get('input[type="checkbox"]').uncheck()

  • value 기반으로도 선택 가능
cy.get('[type="checkbox"]').check(['A', 'B']) // 여러 개 체크

5. .select()

드롭다운에서 옵션 선택
cy.get('select').select('남자')
cy.get('select').select('male') // value 속성 기반

6. .focus() / .blur()

포커스 주기 / 포커스 해제
cy.get('input').focus()
cy.get('input').blur()

  • .blur()는 유효성 검사 등 포커스 해제 이벤트 트리거할 때 사용

7. .scrollIntoView()

요소로 스크롤 이동
cy.get('#target').scrollIntoView()

  • 안 보이는 요소를 클릭하기 전에 스크롤해 올려야 할 때 유용

8. .trigger('event')

강제로 이벤트 발생시키기
cy.get('input').trigger('mouseover')
cy.get('form').trigger('submit')

  • 마우스 hover, submit, keydown 등 직접 이벤트 트리거 가능

9. .dblclick() / .rightclick()

마우스 추가 동작
cy.get('button').dblclick()
cy.get('button').rightclick()

10. .check() / .select() 조건

동작설명
.check()체크박스 또는 라디오 버튼
.select()<select><option> 구조
.click()거의 모든 요소 클릭 가능
.type()<input>, <textarea> 등 입력 요소만 가능

예시 시나리오

cy.visit('/login')

cy.get('input[name="email"]').type('abc@example.com')
cy.get('input[name="password"]').type('123456{enter}') // enter로 로그인

cy.url().should('include', '/dashboard')

cy.get('button.logout').click()
cy.url().should('include', '/login')

 

검증

선택한 요소에 대해 should로 검증 조건을 추가하고,
해당 조건을 통해 테스트 Pass, Fail이 결정된다.

  • .should()는 기본적으로 500ms 간격으로 4초 동안 재시도
  • 기본 문법
    cy.get('선택자').should('검사조건', '기대값')
    
  • .and로 체이닝 가능
    cy.get('input').should('have.value', 'hello').and('be.visible')
    

자주 쓰는 검사 조건

검사 조건설명예시
exist요소가 존재함cy.get('input').should('exist')
be.visible화면에 보임 (숨김 요소 아님)cy.get('button').should('be.visible')
have.text정확한 텍스트cy.get('h1').should('have.text', '로그인')
contain.text포함된 텍스트cy.get('h1').should('contain.text', '로그')
have.value<input>의 값cy.get('input').should('have.value', 'abc')
have.attr특정 속성 존재 여부cy.get('a').should('have.attr', 'href', '/home')
have.class특정 클래스 존재cy.get('div').should('have.class', 'active')
have.length요소 개수 확인cy.get('.item').should('have.length', 3)
be.checked체크박스/라디오가 체크됨cy.get('input[type="checkbox"]').should('be.checked')
not.be.checked체크 안 되어 있음cy.get('input').should('not.be.checked')
includeURL, 배열 등에 포함됨cy.url().should('include', '/dashboard')

예시 시나리오

cy.url().should('include', '/dashboard')
cy.get('button').should('exist').and('be.visible') // 버튼이 보이는지 확인
cy.get('input[name="email"]').should('have.value', 'abc@example.com') // 입력값 확인
cy.get('h1').should('contain.text', '환영합니다') // 텍스트 포함 여부