InfoGrab DocsInfoGrab Docs

테스트 레벨

요약

이 다이어그램은 GitLab에서 사용하는 각 테스트 유형의 상대적 우선순위를 나타냅니다. 안정성과 속도를 확보하면서 테스트 커버리지를 달성하기 위해 테스트 피라미드로 테스트 분포를 정합니다. 대부분의 테스트는 단위 레벨에 있어야 하고, 위쪽 계층으로 올라갈수록 테스트 수가 줄어들어야 합니다.

테스트 우선순위 삼각형

이 다이어그램은 GitLab에서 사용하는 각 테스트 유형의 상대적 우선순위를 나타냅니다. e2e는 엔드투엔드를 뜻합니다.

안정성과 속도를 확보하면서 테스트 커버리지를 달성하기 위해 테스트 피라미드로 테스트 분포를 정합니다.

대부분의 테스트는 단위 레벨에 있어야 하고, 위쪽 계층으로 올라갈수록 테스트 수가 줄어들어야 합니다. 맨 위의 엔드투엔드 테스트는 실행과 유지 관리 비용이 가장 큽니다. 그래서 전체 테스트에서 가장 작은 비중을 차지해야 합니다.

2025-02-03 기준으로 레벨별 테스트 분포는 다음과 같이 추정됩니다.

테스트 레벨 Community Edition Enterprise Edition Community + Enterprise Edition
시스템 레벨 블랙박스 테스트(엔드투엔드 또는 QA 테스트) 401 (0.14%) 303 (0.10%) 704 (0.24%)
시스템 레벨 화이트박스 테스트(시스템 또는 기능 테스트) 8,362 (2.90%) 4,082 (1.41%) 12,444 (4.31%)
통합 테스트 39,716 (13.76%) 17,411 (6.03%) 57,127 (19.79%)
단위 테스트 139,504 (48.32%) 78,955 (27.35%) 218,459 (75.66%)

단위 테스트#

공식 정의: https://en.wikipedia.org/wiki/Unit_testing

이 유형의 테스트는 코드 단위 하나(메서드 하나)가 기대한 대로 동작하는지 확인합니다(입력이 주어지면 예측 가능한 출력이 나옵니다). 이 테스트는 가능한 한 격리되어야 합니다. 예를 들어 데이터베이스와 아무 작업도 하지 않는 모델 메서드에는 데이터베이스(DB) 레코드가 필요하지 않습니다. 데이터베이스 레코드가 필요하지 않은 클래스는 가능한 한 스텁과 더블을 사용해야 합니다.

코드 경로 테스트 경로 테스트 엔진 참고
app/assets/javascripts/ spec/frontend/ Jest 자세한 내용은 프론트엔드 테스트 가이드 절에 있습니다.
app/finders/ spec/finders/ RSpec
app/graphql/ spec/graphql/ RSpec
app/helpers/ spec/helpers/ RSpec
app/models/ spec/models/ RSpec
app/policies/ spec/policies/ RSpec
app/presenters/ spec/presenters/ RSpec
app/serializers/ spec/serializers/ RSpec
app/services/ spec/services/ RSpec
app/uploaders/ spec/uploaders/ RSpec
app/validators/ spec/validators/ RSpec
app/views/ spec/views/ RSpec
app/workers/ spec/workers/ RSpec
bin/ spec/bin/ RSpec
config/ spec/config/ RSpec
config/initializers/ spec/initializers/ RSpec
config/routes.rb, config/routes/ spec/routing/ RSpec
config/puma.example.development.rb spec/rack_servers/ RSpec
db/ spec/db/ RSpec
db/{post_,}migrate/ spec/migrations/ RSpec 자세한 내용은 Rails 마이그레이션 테스트 가이드에 있습니다.
Gemfile spec/dependencies/, spec/sidekiq/ RSpec
lib/ spec/lib/ RSpec
lib/tasks/ spec/tasks/ RSpec
rubocop/ spec/rubocop/ RSpec
spec/support/ spec/support_specs/ RSpec

프론트엔드 단위 테스트#

단위 테스트는 추상화 수준이 가장 낮고, 보통 사용자가 직접 인지할 수 없는 기능을 테스트합니다.

Mermaid 다이어그램 (37줄)
소스 코드 보기
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph RL
    accTitle: Frontend unit tests
    accDescr: Diagram showing how frontend unit tests work and test functionality
plain[Plain JavaScript];
Vue[Vue Components];
feature-flags[Feature flags];
license-checks[License Checks];

plain---Vuex;
plain---GraphQL;
Vue---plain;
Vue---Vuex;
Vue---GraphQL;
browser---plain;
browser---Vue;
plain---backend;
Vuex---backend;
GraphQL---backend;
Vue---backend;
backend---database;
backend---feature-flags;
backend---license-checks;

class plain tested;
class Vuex tested;

classDef node stroke-width:2px
classDef label stroke-width:0;
classDef tested stroke-width:2px,stroke-dasharray: 5, 5;

subgraph " "
tested;
mocked;
class tested tested;
end</code></pre></details></div>

단위 테스트 사용 시점#

  • 내보낸 함수와 클래스: 내보낸 것은 무엇이든 통제할 수 없는 방식으로 여러 곳에서 재사용될 수 있습니다. 공개 인터페이스의 기대 동작을 테스트로 문서화해야 합니다.
  • Vuex 액션: 모든 Vuex 액션은 그것을 트리거한 컴포넌트와 무관하게 일관된 방식으로 동작해야 합니다.
  • Vuex 뮤테이션: 복잡한 Vuex 뮤테이션은 문제 해결을 단순하게 하기 위해 Vuex 스토어의 다른 부분과 테스트를 분리해야 합니다.

단위 테스트를 사용하지 않는 경우#

  • 내보내지 않은 함수나 클래스: 모듈에서 내보내지 않은 것은 비공개 또는 구현 세부 사항으로 볼 수 있으므로 테스트할 필요가 없습니다.
  • 상수: 상수의 값을 테스트하는 것은 그 값을 복사하는 일이며, 값이 올바르다는 확신은 더해 주지 않으면서 노력만 더 듭니다.
  • Vue 컴포넌트: 계산된 속성, 메서드, 라이프사이클 훅은 컴포넌트의 구현 세부 사항으로 볼 수 있고 컴포넌트 테스트로 암묵적으로 커버되므로 테스트할 필요가 없습니다. 자세한 내용은 Vue 공식 가이드라인을 참고합니다.

단위 테스트에서 목으로 처리할 대상#

  • 테스트 대상 클래스의 상태: 클래스의 메서드를 사용하는 대신 테스트 대상 클래스의 상태를 직접 수정하면 테스트 설정에서 부수 효과를 피할 수 있습니다.
  • 다른 내보낸 클래스: 테스트 시나리오가 기하급수적으로 늘어나지 않도록 모든 클래스는 격리해 테스트해야 합니다.
  • 파라미터로 전달되는 단일 DOM 요소: 전체 페이지가 아니라 단일 DOM 요소만 다루는 테스트에서는 이런 요소를 만드는 것이 HTML 픽스처 전체를 로드하는 것보다 비용이 적습니다.
  • 모든 서버 요청: 프론트엔드 단위 테스트를 실행할 때는 백엔드에 접근할 수 없을 수 있으므로, 나가는 요청을 모두 목으로 처리해야 합니다.
  • 비동기 백그라운드 작업: 백그라운드 작업은 중지하거나 기다릴 수 없으므로 이후 테스트에서도 계속 실행되며 부수 효과를 일으킵니다.

단위 테스트에서 목으로 처리하지 않을 대상#

  • 내보내지 않은 함수나 클래스: 내보내지 않은 모든 것은 모듈 내부의 비공개 요소로 볼 수 있고, 내보낸 클래스와 함수를 통해 암묵적으로 테스트됩니다.
  • 테스트 대상 클래스의 메서드: 테스트 대상 클래스의 메서드를 목으로 처리하면 실제 메서드가 아니라 목이 테스트됩니다.
  • 유틸리티 함수(순수 함수 또는 파라미터만 수정하는 함수): 함수에 상태가 없어 부수 효과도 없다면 테스트에서 목으로 처리하지 않아도 안전합니다.
  • 전체 HTML 페이지: 단위 테스트에서 전체 페이지의 HTML을 로드하면 테스트가 느려지므로 피합니다.

프론트엔드 컴포넌트 테스트#

컴포넌트 테스트는 사용자 입력, 다른 컴포넌트에서 발생한 이벤트, 애플리케이션 상태 같은 외부 신호에 따라 사용자가 인지할 수 있는 단일 컴포넌트의 상태를 다룹니다.

Mermaid 다이어그램 (36줄)
소스 코드 보기
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph RL
    accTitle: Frontend component tests
    accDescr: Diagram showing how component tests work
plain[Plain JavaScript];
Vue[Vue Components];
feature-flags[Feature flags];
license-checks[License Checks];

plain---Vuex;
plain---GraphQL;
Vue---plain;
Vue---Vuex;
Vue---GraphQL;
browser---plain;
browser---Vue;
plain---backend;
Vuex---backend;
GraphQL---backend;
Vue---backend;
backend---database;
backend---feature-flags;
backend---license-checks;

class Vue tested;

classDef node stroke-width:2px
classDef label stroke-width:0;
classDef tested stroke-width:2px,stroke-dasharray: 5, 5;

subgraph " "
tested;
mocked;
class tested tested;
end</code></pre></details></div>

컴포넌트 테스트 사용 시점#

  • Vue 컴포넌트

컴포넌트 테스트를 사용하지 않는 경우#

  • Vue 애플리케이션: Vue 애플리케이션에는 컴포넌트가 많이 들어 있을 수 있습니다. 컴포넌트 레벨에서 테스트하려면 노력이 너무 많이 듭니다. 그래서 프론트엔드 통합 레벨에서 테스트합니다.
  • HAML 템플릿: HAML 템플릿에는 마크업만 있고 프론트엔드 측 로직이 없습니다. 그래서 완전한 컴포넌트가 아닙니다.

컴포넌트 테스트에서 목으로 처리할 대상#

  • 부수 효과: 외부 상태를 바꿀 수 있는 것(예: 네트워크 요청)은 목으로 처리해야 합니다.
  • 자식 컴포넌트: 모든 컴포넌트는 개별적으로 테스트하므로 자식 컴포넌트는 목으로 처리합니다. shallowMount()도 참고합니다

컴포넌트 테스트에서 목으로 처리하지 않을 대상#

  • 테스트 대상 컴포넌트의 메서드나 계산된 속성: 테스트 대상 컴포넌트의 일부를 목으로 처리하면 실제 컴포넌트가 아니라 목이 테스트됩니다.
  • Vuex: 깨지기 쉽고 거짓 양성이 나오는 테스트를 피하기 위해 Vuex는 목으로 처리하지 않습니다. 뮤테이션으로 Vuex를 적절한 상태로 설정합니다. Vuex 액션이 아니라 부수 효과를 목으로 처리합니다.

통합 테스트#

공식 정의: https://en.wikipedia.org/wiki/Integration_testing

이 유형의 테스트는 애플리케이션의 개별 부분이 실제 앱 환경(브라우저 등)의 부담 없이 서로 잘 동작하는지 확인합니다. 이 테스트는 요청/응답 수준에서 단정해야 합니다. 상태 코드, 헤더, 본문이 그 대상입니다. 예를 들어 권한, 리디렉션, API 엔드포인트, 어떤 뷰가 렌더링되는지 등을 테스트할 때 유용합니다.

코드 경로 테스트 경로 테스트 엔진 참고
app/controllers/ spec/requests/, spec/controllers RSpec 레거시 컨트롤러 스펙보다 요청 스펙이 선호됩니다. API 엔드포인트에는 요청 스펙을 권장합니다.
app/mailers/ spec/mailers/ RSpec
lib/api/ spec/requests/api/ RSpec
app/assets/javascripts/ spec/frontend/ Jest 자세한 내용은 아래에 있습니다

프론트엔드 통합 테스트#

통합 테스트는 한 페이지의 모든 컴포넌트 사이의 상호 작용을 다룹니다. 추상화 수준은 사용자가 UI와 상호 작용하는 방식과 비슷합니다.

MSW jest 통합 테스트와 그 사용법에 대한 자세한 내용은 MSW 통합 테스트 페이지를 참고합니다

Mermaid 다이어그램 (41줄)
소스 코드 보기
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph RL
    accTitle: Frontend integration tests
    accDescr: Diagram showing how integration tests work
plain[Plain JavaScript];
Vue[Vue Components];
feature-flags[Feature flags];
license-checks[License Checks];

plain---Vuex;
plain---GraphQL;
Vue---plain;
Vue---Vuex;
Vue---GraphQL;
browser---plain;
browser---Vue;
plain---backend;
Vuex---backend;
GraphQL---backend;
Vue---backend;
backend---database;
backend---feature-flags;
backend---license-checks;

class plain tested;
class Vue tested;
class Vuex tested;
class GraphQL tested;
class browser tested;
linkStyle 0,1,2,3,4,5,6 stroke-width:2px,stroke-dasharray: 5, 5;

classDef node stroke-width:2px
classDef label stroke-width:0;
classDef tested stroke-width:2px,stroke-dasharray: 5, 5;

subgraph " "
tested;
mocked;
class tested tested;
end</code></pre></details></div>

통합 테스트 사용 시점#

  • 페이지 번들(app/assets/javascripts/pages/의 index.js 파일): 페이지 번들을 테스트하면 해당 프론트엔드 컴포넌트들이 잘 통합되는지 확인할 수 있습니다.
  • 페이지 번들 밖의 Vue 애플리케이션: Vue 애플리케이션을 전체로 테스트하면 해당 프론트엔드 컴포넌트들이 잘 통합되는지 확인할 수 있습니다.

통합 테스트에서 목으로 처리할 대상#

  • HAML 뷰(대신 픽스처를 사용합니다): HAML 뷰를 렌더링하려면 실행 중인 데이터베이스를 포함한 Rails 환경이 필요한데, 프론트엔드 테스트에서는 이를 기대할 수 없습니다.
  • 모든 서버 요청: 단위 테스트와 컴포넌트 테스트와 마찬가지로, 컴포넌트 테스트를 실행할 때는 백엔드에 접근할 수 없을 수 있으므로 나가는 요청을 모두 목으로 처리해야 합니다.
  • 페이지에서 인지할 수 없는 비동기 백그라운드 작업: 페이지에 영향을 주는 백그라운드 작업은 이 레벨에서 테스트해야 합니다. 그 외 백그라운드 작업은 중지하거나 기다릴 수 없으므로 이후 테스트에서도 계속 실행되며 부수 효과를 일으킵니다.

통합 테스트에서 목으로 처리하지 않을 대상#

  • DOM: 실제 DOM에서 테스트하면 컴포넌트가 의도한 환경에서 동작하는지 확인할 수 있습니다. DOM 테스트의 일부는 크로스 브라우저 테스트에 위임합니다.
  • 컴포넌트의 속성이나 상태: 이 레벨에서 모든 테스트는 사용자가 할 수 있는 동작만 수행할 수 있습니다. 예를 들어 컴포넌트의 상태를 바꾸려면 클릭 이벤트를 발생시킵니다.
  • Vuex 스토어: 페이지의 프론트엔드 코드를 전체로 테스트하면 Vue 컴포넌트와 Vuex 스토어 사이의 상호 작용도 함께 다뤄집니다.

컨트롤러 테스트에 대하여#

GitLab은 컨트롤러 스펙에서 요청 스펙으로 전환하고 있습니다.

이상적으로는 컨트롤러가 얇아야 합니다. 그러나 그렇지 않은 경우에는 컨트롤러 테스트 대신 JavaScript 없는 시스템 테스트나 기능 테스트를 작성해도 됩니다. 두꺼운 컨트롤러를 테스트하려면 보통 다음과 같은 스터빙이 많이 필요합니다.

controller.instance_variable_set(:@user, user)

또한 Rails 5에서 더 이상 사용되지 않는 메서드를 사용합니다.

시스템 레벨 화이트박스 테스트(이전의 시스템/기능 테스트)#

공식 정의는 다음과 같습니다.

이 유형의 테스트는 GitLab Rails 애플리케이션(예: gitlab-foss/gitlab)이 브라우저 관점에서 기대한 대로 동작하는지 확인합니다.

다음에 유의합니다.

  • 애플리케이션 내부 구조에 대한 지식이 여전히 필요합니다
  • 테스트에 필요한 데이터는 보통 RSpec 팩토리로 직접 생성합니다
  • 기대값은 대부분 데이터베이스나 객체 상태를 대상으로 설정합니다

이 테스트는 다음 경우에만 사용해야 합니다.

  • 테스트하는 기능이나 컴포넌트가 작습니다
  • 객체나 데이터베이스의 내부 상태를 테스트해야 합니다
  • 더 낮은 레벨에서 테스트할 수 없습니다

예를 들어 특정 페이지의 브레드크럼을 테스트할 때는 작은 컴포넌트이면서 단위나 컨트롤러 레벨에서 테스트할 수 없으므로 시스템 테스트를 작성하는 것이 합리적입니다.

해피 패스만 테스트하되, 더 나은 테스트로도 낮은 레벨에서 잡을 수 없었던 회귀에 대해서는 반드시 테스트 케이스를 추가합니다(예를 들어 회귀를 발견했다면 가능한 가장 낮은 레벨에 회귀 테스트를 추가해야 합니다).

테스트 경로 테스트 엔진 참고
spec/features/ Capybara + RSpec 테스트에 :js 메타데이터가 있으면 브라우저 드라이버는 Selenium이고, 그렇지 않으면 RackTest를 사용합니다.

프론트엔드 기능 테스트#

프론트엔드 통합 테스트와 달리 기능 테스트는 픽스처를 사용하지 않고 실제 백엔드에 요청을 보냅니다. 따라서 데이터베이스 쿼리도 실행되므로 이 범주는 훨씬 더 느립니다.

다음도 참고합니다.

Mermaid 다이어그램 (42줄)
소스 코드 보기
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph RL
    accTitle: Frontend feature tests
    accDescr: Diagram showing how feature tests work
plain[Plain JavaScript];
Vue[Vue Components];
feature-flags[Feature flags];
license-checks[License Checks];

plain---Vuex;
plain---GraphQL;
Vue---plain;
Vue---Vuex;
Vue---GraphQL;
browser---plain;
browser---Vue;
plain---backend;
Vuex---backend;
GraphQL---backend;
Vue---backend;
backend---database;
backend---feature-flags;
backend---license-checks;

class backend tested;
class plain tested;
class Vue tested;
class Vuex tested;
class GraphQL tested;
class browser tested;
linkStyle 0,1,2,3,4,5,6,7,8,9,10 stroke-width:2px,stroke-dasharray: 5, 5;

classDef node stroke-width:2px
classDef label stroke-width:0;
classDef tested stroke-width:2px,stroke-dasharray: 5, 5;

subgraph " "
tested;
mocked;
class tested tested;
end</code></pre></details></div>

기능 테스트 사용 시점#

  • 백엔드가 필요하고 픽스처로는 테스트할 수 없는 사용 사례.
  • 페이지 번들에 속하지 않고 전역으로 정의된 동작.

관련 참고 사항#

전체 환경이 로드되도록 테스트에 :js 플래그를 추가합니다.

scenario 'successfully', :js do
  sign_in(create(:admin))
end

각 테스트의 단계는 다음과 같이 (capybara 메서드)로 작성합니다.

find('.form-control').native.send_keys(:enter)

expect(page).to have_selector('.card')

시스템 테스트를 작성하지 않는 방안 고려#

저수준 컴포넌트가 잘 동작한다고 확신한다면(단위 테스트와 통합 테스트가 충분하다면 그래야 합니다) 시스템 테스트 레벨에서 그 철저한 테스트를 중복할 필요가 없습니다.

테스트를 추가하는 것은 매우 쉽지만 테스트를 제거하거나 개선하는 것은 훨씬 어렵기 때문에, 느리고 중복된 테스트를 너무 많이 들이지 않도록 주의해야 합니다.

이러한 모범 사례를 따라야 하는 이유는 다음과 같습니다.

  • 시스템 테스트는 헤드리스 브라우저에서 애플리케이션 스택 전체를 띄우기 때문에 실행이 느리고, JS 드라이버까지 통합하면 더 느립니다
  • 시스템 테스트를 JavaScript 드라이버로 실행하면 테스트가 애플리케이션과 다른 스레드에서 실행됩니다. 즉 데이터베이스 연결을 공유하지 않으므로, 실행 중인 애플리케이션이 데이터를 볼 수 있게 하려면 테스트가 트랜잭션을 커밋해야 합니다(그 반대도 마찬가지입니다). 그런 경우에는 트랜잭션을 롤백하는 대신 각 스펙 뒤에 데이터베이스를 잘라내야 합니다(롤백은 다른 종류의 테스트에서 사용하는 더 빠른 전략입니다). 다만 이 방식은 트랜잭션보다 느리므로 잘라내기는 필요할 때만 사용합니다.

시스템 레벨 블랙박스 테스트, 즉 엔드투엔드 테스트#

공식 정의는 다음과 같습니다.

GitLab은 GitLab Shell, GitLab Workhorse, Gitaly, GitLab Pages, GitLab Runner, GitLab Rails 같은 여러 조각으로 이루어집니다. 이 모든 조각은 Omnibus GitLab이 구성하고 패키징합니다.

QA 프레임워크와 인스턴스 레벨 시나리오는 GitLab Rails의 일부이므로 코드베이스(특히 뷰)와 항상 동기화됩니다.

다음에 유의합니다.

  • 애플리케이션 내부 구조에 대한 지식은 필요하지 않습니다
  • 테스트에 필요한 데이터는 GUI 또는 API로만 생성할 수 있습니다
  • 기대값은 브라우저 페이지와 API 응답을 대상으로만 설정할 수 있습니다

모든 새 기능에는 테스트 계획이 있어야 합니다.

테스트 경로 테스트 엔진 참고
qa/qa/specs/features/ Capybara + RSpec + 자체 QA 프레임워크 테스트는 해당하는 제품 카테고리 아래에 배치해야 합니다

자세한 내용은 엔드투엔드 테스트를 참고합니다.

qa/spec에는 QA 프레임워크 자체의 단위 테스트가 들어 있으며, 애플리케이션의 단위 테스트나 엔드투엔드 테스트와 혼동하지 않아야 합니다.

스모크 테스트#

스모크 테스트는 언제든(특히 배포 전 마이그레이션 뒤에) 실행할 수 있는 빠른 테스트입니다.

이 테스트는 UI를 대상으로 실행되며 기본 기능이 동작하는지 확인합니다.

자세한 내용은 스모크 테스트를 참고합니다.

GitLab QA 오케스트레이터#

GitLab QA 오케스트레이터는 특정 GitLab Rails 버전의 Docker 이미지를 빌드하고 그 이미지를 대상으로 엔드투엔드 테스트를(Capybara로) 실행해, 이 모든 조각이 잘 통합되는지 테스트할 수 있게 해 주는 도구입니다.

자세한 내용은 GitLab QA 오케스트레이터 README에서 확인할 수 있습니다.

EE 전용 테스트#

EE 전용 테스트는 같은 구성을 따르지만 ee/spec 폴더 아래에 있습니다.

스펙 파일에 EE 미러가 있으면 CE/EE 공유 예제 관례를 사용해 핵심 동작 테스트가 중복되지 않게 합니다. 자세한 내용은 CE/EE 공유 예제 관례를 참고합니다.

올바른 레벨에서 테스트하는 방법#

인생의 많은 일과 마찬가지로, 각 테스트 레벨에서 무엇을 테스트할지 정하는 일은 트레이드오프입니다.

  • 단위 테스트는 보통 비용이 낮으며, 집의 지하실처럼 생각하면 됩니다. 코드가 올바르게 동작한다고 확신하려면 단위 테스트가 필요합니다. 그러나 통합 테스트와 시스템 테스트 없이 단위 테스트만 실행하면 큰 / 그림을 놓칠 수 있습니다 !
  • 통합 테스트는 비용이 조금 더 들지만 남용하지 않습니다. 내부 구조를 많이 스텁으로 대체하는 통합 테스트보다 시스템 테스트가 더 나은 경우가 많습니다.
  • 시스템 테스트는 (단위 테스트와 비교해) 비용이 크고, JavaScript 드라이버가 필요하면 더 큽니다. 속도 절의 가이드라인을 반드시 따릅니다.

이를 보는 또 다른 방법은 "테스트의 비용"을 생각하는 것입니다. 이는 이 글에 잘 설명되어 있으며, 기본 발상은 테스트의 비용에 다음이 포함된다는 것입니다.

  • 테스트를 작성하는 데 걸리는 시간
  • 스위트를 실행할 때마다 그 테스트를 실행하는 데 걸리는 시간
  • 테스트를 이해하는 데 걸리는 시간
  • 테스트가 깨졌지만 기반 코드에는 문제가 없을 때 테스트를 고치는 데 걸리는 시간
  • 경우에 따라, 코드를 테스트 가능하게 만들기 위해 코드를 바꾸는 데 걸리는 시간.

프론트엔드 관련 테스트#

테스트하려는 동작이 애플리케이션 전체를 실행하는 시간을 들일 만한 가치가 없는 경우도 있습니다. 예를 들어 스타일링, 애니메이션, 엣지 케이스, 또는 백엔드가 관여하지 않는 작은 동작을 테스트한다면 프론트엔드 통합 테스트로 통합 테스트를 작성해야 합니다.


테스트 문서로 돌아가기

테스트 레벨

GitLab v19.4
원문 보기

요약

이 다이어그램은 GitLab에서 사용하는 각 테스트 유형의 상대적 우선순위를 나타냅니다. 안정성과 속도를 확보하면서 테스트 커버리지를 달성하기 위해 테스트 피라미드로 테스트 분포를 정합니다. 대부분의 테스트는 단위 레벨에 있어야 하고, 위쪽 계층으로 올라갈수록 테스트 수가 줄어들어야 합니다.

테스트 우선순위 삼각형

이 다이어그램은 GitLab에서 사용하는 각 테스트 유형의 상대적 우선순위를 나타냅니다. e2e는 엔드투엔드를 뜻합니다.

안정성과 속도를 확보하면서 테스트 커버리지를 달성하기 위해 테스트 피라미드로 테스트 분포를 정합니다.

대부분의 테스트는 단위 레벨에 있어야 하고, 위쪽 계층으로 올라갈수록 테스트 수가 줄어들어야 합니다. 맨 위의 엔드투엔드 테스트는 실행과 유지 관리 비용이 가장 큽니다. 그래서 전체 테스트에서 가장 작은 비중을 차지해야 합니다.

2025-02-03 기준으로 레벨별 테스트 분포는 다음과 같이 추정됩니다.

테스트 레벨 Community Edition Enterprise Edition Community + Enterprise Edition
시스템 레벨 블랙박스 테스트(엔드투엔드 또는 QA 테스트) 401 (0.14%) 303 (0.10%) 704 (0.24%)
시스템 레벨 화이트박스 테스트(시스템 또는 기능 테스트) 8,362 (2.90%) 4,082 (1.41%) 12,444 (4.31%)
통합 테스트 39,716 (13.76%) 17,411 (6.03%) 57,127 (19.79%)
단위 테스트 139,504 (48.32%) 78,955 (27.35%) 218,459 (75.66%)

단위 테스트#

공식 정의: https://en.wikipedia.org/wiki/Unit_testing

이 유형의 테스트는 코드 단위 하나(메서드 하나)가 기대한 대로 동작하는지 확인합니다(입력이 주어지면 예측 가능한 출력이 나옵니다). 이 테스트는 가능한 한 격리되어야 합니다. 예를 들어 데이터베이스와 아무 작업도 하지 않는 모델 메서드에는 데이터베이스(DB) 레코드가 필요하지 않습니다. 데이터베이스 레코드가 필요하지 않은 클래스는 가능한 한 스텁과 더블을 사용해야 합니다.

코드 경로 테스트 경로 테스트 엔진 참고
app/assets/javascripts/ spec/frontend/ Jest 자세한 내용은 프론트엔드 테스트 가이드 절에 있습니다.
app/finders/ spec/finders/ RSpec
app/graphql/ spec/graphql/ RSpec
app/helpers/ spec/helpers/ RSpec
app/models/ spec/models/ RSpec
app/policies/ spec/policies/ RSpec
app/presenters/ spec/presenters/ RSpec
app/serializers/ spec/serializers/ RSpec
app/services/ spec/services/ RSpec
app/uploaders/ spec/uploaders/ RSpec
app/validators/ spec/validators/ RSpec
app/views/ spec/views/ RSpec
app/workers/ spec/workers/ RSpec
bin/ spec/bin/ RSpec
config/ spec/config/ RSpec
config/initializers/ spec/initializers/ RSpec
config/routes.rb, config/routes/ spec/routing/ RSpec
config/puma.example.development.rb spec/rack_servers/ RSpec
db/ spec/db/ RSpec
db/{post_,}migrate/ spec/migrations/ RSpec 자세한 내용은 Rails 마이그레이션 테스트 가이드에 있습니다.
Gemfile spec/dependencies/, spec/sidekiq/ RSpec
lib/ spec/lib/ RSpec
lib/tasks/ spec/tasks/ RSpec
rubocop/ spec/rubocop/ RSpec
spec/support/ spec/support_specs/ RSpec

프론트엔드 단위 테스트#

단위 테스트는 추상화 수준이 가장 낮고, 보통 사용자가 직접 인지할 수 없는 기능을 테스트합니다.

Mermaid 다이어그램 (37줄)
소스 코드 보기
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph RL
    accTitle: Frontend unit tests
    accDescr: Diagram showing how frontend unit tests work and test functionality
plain[Plain JavaScript];
Vue[Vue Components];
feature-flags[Feature flags];
license-checks[License Checks];

plain---Vuex;
plain---GraphQL;
Vue---plain;
Vue---Vuex;
Vue---GraphQL;
browser---plain;
browser---Vue;
plain---backend;
Vuex---backend;
GraphQL---backend;
Vue---backend;
backend---database;
backend---feature-flags;
backend---license-checks;

class plain tested;
class Vuex tested;

classDef node stroke-width:2px
classDef label stroke-width:0;
classDef tested stroke-width:2px,stroke-dasharray: 5, 5;

subgraph " "
tested;
mocked;
class tested tested;
end</code></pre></details></div>

단위 테스트 사용 시점#

  • 내보낸 함수와 클래스: 내보낸 것은 무엇이든 통제할 수 없는 방식으로 여러 곳에서 재사용될 수 있습니다. 공개 인터페이스의 기대 동작을 테스트로 문서화해야 합니다.
  • Vuex 액션: 모든 Vuex 액션은 그것을 트리거한 컴포넌트와 무관하게 일관된 방식으로 동작해야 합니다.
  • Vuex 뮤테이션: 복잡한 Vuex 뮤테이션은 문제 해결을 단순하게 하기 위해 Vuex 스토어의 다른 부분과 테스트를 분리해야 합니다.

단위 테스트를 사용하지 않는 경우#

  • 내보내지 않은 함수나 클래스: 모듈에서 내보내지 않은 것은 비공개 또는 구현 세부 사항으로 볼 수 있으므로 테스트할 필요가 없습니다.
  • 상수: 상수의 값을 테스트하는 것은 그 값을 복사하는 일이며, 값이 올바르다는 확신은 더해 주지 않으면서 노력만 더 듭니다.
  • Vue 컴포넌트: 계산된 속성, 메서드, 라이프사이클 훅은 컴포넌트의 구현 세부 사항으로 볼 수 있고 컴포넌트 테스트로 암묵적으로 커버되므로 테스트할 필요가 없습니다. 자세한 내용은 Vue 공식 가이드라인을 참고합니다.

단위 테스트에서 목으로 처리할 대상#

  • 테스트 대상 클래스의 상태: 클래스의 메서드를 사용하는 대신 테스트 대상 클래스의 상태를 직접 수정하면 테스트 설정에서 부수 효과를 피할 수 있습니다.
  • 다른 내보낸 클래스: 테스트 시나리오가 기하급수적으로 늘어나지 않도록 모든 클래스는 격리해 테스트해야 합니다.
  • 파라미터로 전달되는 단일 DOM 요소: 전체 페이지가 아니라 단일 DOM 요소만 다루는 테스트에서는 이런 요소를 만드는 것이 HTML 픽스처 전체를 로드하는 것보다 비용이 적습니다.
  • 모든 서버 요청: 프론트엔드 단위 테스트를 실행할 때는 백엔드에 접근할 수 없을 수 있으므로, 나가는 요청을 모두 목으로 처리해야 합니다.
  • 비동기 백그라운드 작업: 백그라운드 작업은 중지하거나 기다릴 수 없으므로 이후 테스트에서도 계속 실행되며 부수 효과를 일으킵니다.

단위 테스트에서 목으로 처리하지 않을 대상#

  • 내보내지 않은 함수나 클래스: 내보내지 않은 모든 것은 모듈 내부의 비공개 요소로 볼 수 있고, 내보낸 클래스와 함수를 통해 암묵적으로 테스트됩니다.
  • 테스트 대상 클래스의 메서드: 테스트 대상 클래스의 메서드를 목으로 처리하면 실제 메서드가 아니라 목이 테스트됩니다.
  • 유틸리티 함수(순수 함수 또는 파라미터만 수정하는 함수): 함수에 상태가 없어 부수 효과도 없다면 테스트에서 목으로 처리하지 않아도 안전합니다.
  • 전체 HTML 페이지: 단위 테스트에서 전체 페이지의 HTML을 로드하면 테스트가 느려지므로 피합니다.

프론트엔드 컴포넌트 테스트#

컴포넌트 테스트는 사용자 입력, 다른 컴포넌트에서 발생한 이벤트, 애플리케이션 상태 같은 외부 신호에 따라 사용자가 인지할 수 있는 단일 컴포넌트의 상태를 다룹니다.

Mermaid 다이어그램 (36줄)
소스 코드 보기
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph RL
    accTitle: Frontend component tests
    accDescr: Diagram showing how component tests work
plain[Plain JavaScript];
Vue[Vue Components];
feature-flags[Feature flags];
license-checks[License Checks];

plain---Vuex;
plain---GraphQL;
Vue---plain;
Vue---Vuex;
Vue---GraphQL;
browser---plain;
browser---Vue;
plain---backend;
Vuex---backend;
GraphQL---backend;
Vue---backend;
backend---database;
backend---feature-flags;
backend---license-checks;

class Vue tested;

classDef node stroke-width:2px
classDef label stroke-width:0;
classDef tested stroke-width:2px,stroke-dasharray: 5, 5;

subgraph " "
tested;
mocked;
class tested tested;
end</code></pre></details></div>

컴포넌트 테스트 사용 시점#

  • Vue 컴포넌트

컴포넌트 테스트를 사용하지 않는 경우#

  • Vue 애플리케이션: Vue 애플리케이션에는 컴포넌트가 많이 들어 있을 수 있습니다. 컴포넌트 레벨에서 테스트하려면 노력이 너무 많이 듭니다. 그래서 프론트엔드 통합 레벨에서 테스트합니다.
  • HAML 템플릿: HAML 템플릿에는 마크업만 있고 프론트엔드 측 로직이 없습니다. 그래서 완전한 컴포넌트가 아닙니다.

컴포넌트 테스트에서 목으로 처리할 대상#

  • 부수 효과: 외부 상태를 바꿀 수 있는 것(예: 네트워크 요청)은 목으로 처리해야 합니다.
  • 자식 컴포넌트: 모든 컴포넌트는 개별적으로 테스트하므로 자식 컴포넌트는 목으로 처리합니다. shallowMount()도 참고합니다

컴포넌트 테스트에서 목으로 처리하지 않을 대상#

  • 테스트 대상 컴포넌트의 메서드나 계산된 속성: 테스트 대상 컴포넌트의 일부를 목으로 처리하면 실제 컴포넌트가 아니라 목이 테스트됩니다.
  • Vuex: 깨지기 쉽고 거짓 양성이 나오는 테스트를 피하기 위해 Vuex는 목으로 처리하지 않습니다. 뮤테이션으로 Vuex를 적절한 상태로 설정합니다. Vuex 액션이 아니라 부수 효과를 목으로 처리합니다.

통합 테스트#

공식 정의: https://en.wikipedia.org/wiki/Integration_testing

이 유형의 테스트는 애플리케이션의 개별 부분이 실제 앱 환경(브라우저 등)의 부담 없이 서로 잘 동작하는지 확인합니다. 이 테스트는 요청/응답 수준에서 단정해야 합니다. 상태 코드, 헤더, 본문이 그 대상입니다. 예를 들어 권한, 리디렉션, API 엔드포인트, 어떤 뷰가 렌더링되는지 등을 테스트할 때 유용합니다.

코드 경로 테스트 경로 테스트 엔진 참고
app/controllers/ spec/requests/, spec/controllers RSpec 레거시 컨트롤러 스펙보다 요청 스펙이 선호됩니다. API 엔드포인트에는 요청 스펙을 권장합니다.
app/mailers/ spec/mailers/ RSpec
lib/api/ spec/requests/api/ RSpec
app/assets/javascripts/ spec/frontend/ Jest 자세한 내용은 아래에 있습니다

프론트엔드 통합 테스트#

통합 테스트는 한 페이지의 모든 컴포넌트 사이의 상호 작용을 다룹니다. 추상화 수준은 사용자가 UI와 상호 작용하는 방식과 비슷합니다.

MSW jest 통합 테스트와 그 사용법에 대한 자세한 내용은 MSW 통합 테스트 페이지를 참고합니다

Mermaid 다이어그램 (41줄)
소스 코드 보기
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph RL
    accTitle: Frontend integration tests
    accDescr: Diagram showing how integration tests work
plain[Plain JavaScript];
Vue[Vue Components];
feature-flags[Feature flags];
license-checks[License Checks];

plain---Vuex;
plain---GraphQL;
Vue---plain;
Vue---Vuex;
Vue---GraphQL;
browser---plain;
browser---Vue;
plain---backend;
Vuex---backend;
GraphQL---backend;
Vue---backend;
backend---database;
backend---feature-flags;
backend---license-checks;

class plain tested;
class Vue tested;
class Vuex tested;
class GraphQL tested;
class browser tested;
linkStyle 0,1,2,3,4,5,6 stroke-width:2px,stroke-dasharray: 5, 5;

classDef node stroke-width:2px
classDef label stroke-width:0;
classDef tested stroke-width:2px,stroke-dasharray: 5, 5;

subgraph " "
tested;
mocked;
class tested tested;
end</code></pre></details></div>

통합 테스트 사용 시점#

  • 페이지 번들(app/assets/javascripts/pages/의 index.js 파일): 페이지 번들을 테스트하면 해당 프론트엔드 컴포넌트들이 잘 통합되는지 확인할 수 있습니다.
  • 페이지 번들 밖의 Vue 애플리케이션: Vue 애플리케이션을 전체로 테스트하면 해당 프론트엔드 컴포넌트들이 잘 통합되는지 확인할 수 있습니다.

통합 테스트에서 목으로 처리할 대상#

  • HAML 뷰(대신 픽스처를 사용합니다): HAML 뷰를 렌더링하려면 실행 중인 데이터베이스를 포함한 Rails 환경이 필요한데, 프론트엔드 테스트에서는 이를 기대할 수 없습니다.
  • 모든 서버 요청: 단위 테스트와 컴포넌트 테스트와 마찬가지로, 컴포넌트 테스트를 실행할 때는 백엔드에 접근할 수 없을 수 있으므로 나가는 요청을 모두 목으로 처리해야 합니다.
  • 페이지에서 인지할 수 없는 비동기 백그라운드 작업: 페이지에 영향을 주는 백그라운드 작업은 이 레벨에서 테스트해야 합니다. 그 외 백그라운드 작업은 중지하거나 기다릴 수 없으므로 이후 테스트에서도 계속 실행되며 부수 효과를 일으킵니다.

통합 테스트에서 목으로 처리하지 않을 대상#

  • DOM: 실제 DOM에서 테스트하면 컴포넌트가 의도한 환경에서 동작하는지 확인할 수 있습니다. DOM 테스트의 일부는 크로스 브라우저 테스트에 위임합니다.
  • 컴포넌트의 속성이나 상태: 이 레벨에서 모든 테스트는 사용자가 할 수 있는 동작만 수행할 수 있습니다. 예를 들어 컴포넌트의 상태를 바꾸려면 클릭 이벤트를 발생시킵니다.
  • Vuex 스토어: 페이지의 프론트엔드 코드를 전체로 테스트하면 Vue 컴포넌트와 Vuex 스토어 사이의 상호 작용도 함께 다뤄집니다.

컨트롤러 테스트에 대하여#

GitLab은 컨트롤러 스펙에서 요청 스펙으로 전환하고 있습니다.

이상적으로는 컨트롤러가 얇아야 합니다. 그러나 그렇지 않은 경우에는 컨트롤러 테스트 대신 JavaScript 없는 시스템 테스트나 기능 테스트를 작성해도 됩니다. 두꺼운 컨트롤러를 테스트하려면 보통 다음과 같은 스터빙이 많이 필요합니다.

controller.instance_variable_set(:@user, user)

또한 Rails 5에서 더 이상 사용되지 않는 메서드를 사용합니다.

시스템 레벨 화이트박스 테스트(이전의 시스템/기능 테스트)#

공식 정의는 다음과 같습니다.

이 유형의 테스트는 GitLab Rails 애플리케이션(예: gitlab-foss/gitlab)이 브라우저 관점에서 기대한 대로 동작하는지 확인합니다.

다음에 유의합니다.

  • 애플리케이션 내부 구조에 대한 지식이 여전히 필요합니다
  • 테스트에 필요한 데이터는 보통 RSpec 팩토리로 직접 생성합니다
  • 기대값은 대부분 데이터베이스나 객체 상태를 대상으로 설정합니다

이 테스트는 다음 경우에만 사용해야 합니다.

  • 테스트하는 기능이나 컴포넌트가 작습니다
  • 객체나 데이터베이스의 내부 상태를 테스트해야 합니다
  • 더 낮은 레벨에서 테스트할 수 없습니다

예를 들어 특정 페이지의 브레드크럼을 테스트할 때는 작은 컴포넌트이면서 단위나 컨트롤러 레벨에서 테스트할 수 없으므로 시스템 테스트를 작성하는 것이 합리적입니다.

해피 패스만 테스트하되, 더 나은 테스트로도 낮은 레벨에서 잡을 수 없었던 회귀에 대해서는 반드시 테스트 케이스를 추가합니다(예를 들어 회귀를 발견했다면 가능한 가장 낮은 레벨에 회귀 테스트를 추가해야 합니다).

테스트 경로 테스트 엔진 참고
spec/features/ Capybara + RSpec 테스트에 :js 메타데이터가 있으면 브라우저 드라이버는 Selenium이고, 그렇지 않으면 RackTest를 사용합니다.

프론트엔드 기능 테스트#

프론트엔드 통합 테스트와 달리 기능 테스트는 픽스처를 사용하지 않고 실제 백엔드에 요청을 보냅니다. 따라서 데이터베이스 쿼리도 실행되므로 이 범주는 훨씬 더 느립니다.

다음도 참고합니다.

Mermaid 다이어그램 (42줄)
소스 코드 보기
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph RL
    accTitle: Frontend feature tests
    accDescr: Diagram showing how feature tests work
plain[Plain JavaScript];
Vue[Vue Components];
feature-flags[Feature flags];
license-checks[License Checks];

plain---Vuex;
plain---GraphQL;
Vue---plain;
Vue---Vuex;
Vue---GraphQL;
browser---plain;
browser---Vue;
plain---backend;
Vuex---backend;
GraphQL---backend;
Vue---backend;
backend---database;
backend---feature-flags;
backend---license-checks;

class backend tested;
class plain tested;
class Vue tested;
class Vuex tested;
class GraphQL tested;
class browser tested;
linkStyle 0,1,2,3,4,5,6,7,8,9,10 stroke-width:2px,stroke-dasharray: 5, 5;

classDef node stroke-width:2px
classDef label stroke-width:0;
classDef tested stroke-width:2px,stroke-dasharray: 5, 5;

subgraph " "
tested;
mocked;
class tested tested;
end</code></pre></details></div>

기능 테스트 사용 시점#

  • 백엔드가 필요하고 픽스처로는 테스트할 수 없는 사용 사례.
  • 페이지 번들에 속하지 않고 전역으로 정의된 동작.

관련 참고 사항#

전체 환경이 로드되도록 테스트에 :js 플래그를 추가합니다.

scenario 'successfully', :js do
  sign_in(create(:admin))
end

각 테스트의 단계는 다음과 같이 (capybara 메서드)로 작성합니다.

find('.form-control').native.send_keys(:enter)

expect(page).to have_selector('.card')

시스템 테스트를 작성하지 않는 방안 고려#

저수준 컴포넌트가 잘 동작한다고 확신한다면(단위 테스트와 통합 테스트가 충분하다면 그래야 합니다) 시스템 테스트 레벨에서 그 철저한 테스트를 중복할 필요가 없습니다.

테스트를 추가하는 것은 매우 쉽지만 테스트를 제거하거나 개선하는 것은 훨씬 어렵기 때문에, 느리고 중복된 테스트를 너무 많이 들이지 않도록 주의해야 합니다.

이러한 모범 사례를 따라야 하는 이유는 다음과 같습니다.

  • 시스템 테스트는 헤드리스 브라우저에서 애플리케이션 스택 전체를 띄우기 때문에 실행이 느리고, JS 드라이버까지 통합하면 더 느립니다
  • 시스템 테스트를 JavaScript 드라이버로 실행하면 테스트가 애플리케이션과 다른 스레드에서 실행됩니다. 즉 데이터베이스 연결을 공유하지 않으므로, 실행 중인 애플리케이션이 데이터를 볼 수 있게 하려면 테스트가 트랜잭션을 커밋해야 합니다(그 반대도 마찬가지입니다). 그런 경우에는 트랜잭션을 롤백하는 대신 각 스펙 뒤에 데이터베이스를 잘라내야 합니다(롤백은 다른 종류의 테스트에서 사용하는 더 빠른 전략입니다). 다만 이 방식은 트랜잭션보다 느리므로 잘라내기는 필요할 때만 사용합니다.

시스템 레벨 블랙박스 테스트, 즉 엔드투엔드 테스트#

공식 정의는 다음과 같습니다.

GitLab은 GitLab Shell, GitLab Workhorse, Gitaly, GitLab Pages, GitLab Runner, GitLab Rails 같은 여러 조각으로 이루어집니다. 이 모든 조각은 Omnibus GitLab이 구성하고 패키징합니다.

QA 프레임워크와 인스턴스 레벨 시나리오는 GitLab Rails의 일부이므로 코드베이스(특히 뷰)와 항상 동기화됩니다.

다음에 유의합니다.

  • 애플리케이션 내부 구조에 대한 지식은 필요하지 않습니다
  • 테스트에 필요한 데이터는 GUI 또는 API로만 생성할 수 있습니다
  • 기대값은 브라우저 페이지와 API 응답을 대상으로만 설정할 수 있습니다

모든 새 기능에는 테스트 계획이 있어야 합니다.

테스트 경로 테스트 엔진 참고
qa/qa/specs/features/ Capybara + RSpec + 자체 QA 프레임워크 테스트는 해당하는 제품 카테고리 아래에 배치해야 합니다

자세한 내용은 엔드투엔드 테스트를 참고합니다.

qa/spec에는 QA 프레임워크 자체의 단위 테스트가 들어 있으며, 애플리케이션의 단위 테스트나 엔드투엔드 테스트와 혼동하지 않아야 합니다.

스모크 테스트#

스모크 테스트는 언제든(특히 배포 전 마이그레이션 뒤에) 실행할 수 있는 빠른 테스트입니다.

이 테스트는 UI를 대상으로 실행되며 기본 기능이 동작하는지 확인합니다.

자세한 내용은 스모크 테스트를 참고합니다.

GitLab QA 오케스트레이터#

GitLab QA 오케스트레이터는 특정 GitLab Rails 버전의 Docker 이미지를 빌드하고 그 이미지를 대상으로 엔드투엔드 테스트를(Capybara로) 실행해, 이 모든 조각이 잘 통합되는지 테스트할 수 있게 해 주는 도구입니다.

자세한 내용은 GitLab QA 오케스트레이터 README에서 확인할 수 있습니다.

EE 전용 테스트#

EE 전용 테스트는 같은 구성을 따르지만 ee/spec 폴더 아래에 있습니다.

스펙 파일에 EE 미러가 있으면 CE/EE 공유 예제 관례를 사용해 핵심 동작 테스트가 중복되지 않게 합니다. 자세한 내용은 CE/EE 공유 예제 관례를 참고합니다.

올바른 레벨에서 테스트하는 방법#

인생의 많은 일과 마찬가지로, 각 테스트 레벨에서 무엇을 테스트할지 정하는 일은 트레이드오프입니다.

  • 단위 테스트는 보통 비용이 낮으며, 집의 지하실처럼 생각하면 됩니다. 코드가 올바르게 동작한다고 확신하려면 단위 테스트가 필요합니다. 그러나 통합 테스트와 시스템 테스트 없이 단위 테스트만 실행하면 큰 / 그림을 놓칠 수 있습니다 !
  • 통합 테스트는 비용이 조금 더 들지만 남용하지 않습니다. 내부 구조를 많이 스텁으로 대체하는 통합 테스트보다 시스템 테스트가 더 나은 경우가 많습니다.
  • 시스템 테스트는 (단위 테스트와 비교해) 비용이 크고, JavaScript 드라이버가 필요하면 더 큽니다. 속도 절의 가이드라인을 반드시 따릅니다.

이를 보는 또 다른 방법은 "테스트의 비용"을 생각하는 것입니다. 이는 이 글에 잘 설명되어 있으며, 기본 발상은 테스트의 비용에 다음이 포함된다는 것입니다.

  • 테스트를 작성하는 데 걸리는 시간
  • 스위트를 실행할 때마다 그 테스트를 실행하는 데 걸리는 시간
  • 테스트를 이해하는 데 걸리는 시간
  • 테스트가 깨졌지만 기반 코드에는 문제가 없을 때 테스트를 고치는 데 걸리는 시간
  • 경우에 따라, 코드를 테스트 가능하게 만들기 위해 코드를 바꾸는 데 걸리는 시간.

프론트엔드 관련 테스트#

테스트하려는 동작이 애플리케이션 전체를 실행하는 시간을 들일 만한 가치가 없는 경우도 있습니다. 예를 들어 스타일링, 애니메이션, 엣지 케이스, 또는 백엔드가 관여하지 않는 작은 동작을 테스트한다면 프론트엔드 통합 테스트로 통합 테스트를 작성해야 합니다.


테스트 문서로 돌아가기