사전 인수 테스트
개념

인수 테스트

gabury1고친 사람 github-actions[bot]

인수 테스트는 다 만든 소프트웨어를 넘겨받아도 되는지 가립니다. 코드가 어떻게 짜였는지는 보지 않습니다. 쓸 사람이 바란 일을 해내는지를 봅니다. 그 결과를 보고 받아들일지 정합니다.

쉽고 빠른 이해

무슨 일을 하나 — 받는 쪽의 기준으로 「이게 되면 다 된 것」을 따져 봅니다. 낱말 맞히기 게임이라면 「출제자가 다섯 글자 정답으로 게임을 열고 참가자가 들어오면, 참가자는 다섯 글자 단어를 맞혀야 한다」를 직접 해 봅니다.

왜 하나 — 개발자가 요구를 잘못 알아들으면 개발자가 쓴 테스트도 같이 틀립니다. 그 테스트를 다 통과해도 받는 쪽에는 쓸모가 없을 수 있습니다. 받는 쪽의 기준으로 따로 따져야 이 어긋남이 드러납니다.

어떻게 도나

  1. 「무엇이 되면 받아들이나」를 받는 쪽과 함께 미리 문장으로 적습니다
  2. 다 만든 시스템을 그 문장대로 써 봅니다. 사람이 손으로 하기도 합니다. 코드로 짜서 기계가 돌리기도 합니다
  3. 전부 통과하면 받아들입니다. 실패하면 무엇이 틀렸는지 찾습니다

대가 — 기계가 돌리게 짜는 데 품이 많이 든다고 말하는 팀이 많습니다. 때로는 테스트가 깨지기 쉬워 유지가 짐이 됩니다. 구현 세부에 매인 테스트는 화면 글자 하나만 바뀌어도 실패할 수 있습니다.

상세

새 집 열쇠를 받기 전에 수도꼭지를 틀어 보고 창문을 여닫아 봅니다. 벽 속 배관이 어떻게 깔렸는지는 묻지 않습니다. 계약한 대로 살 수 있으면 열쇠를 받습니다.

인수 테스트는 시스템을 받아들일지 정하는 데 초점을 둔 테스트입니다. 낱말 맞히기 게임을 주문했다면 출제자가 단어를 내고 참가자가 맞히는 흐름이 약속대로 되는지 따져 보고 받아들일지 정합니다. 이름의 「인수」는 함수에 넘기는 인수(argument)가 아닙니다. 물건을 넘겨받는다는 뜻의 인수(引受)입니다.

인수 테스트는 테스트 레벨(test level) 하나입니다. 테스트 레벨은 개발의 어느 단계에서 무엇을 놓고 보느냐로 묶은 테스트 활동입니다. 다섯으로 나누면 아래와 같습니다.

테스트 레벨 무엇을 보나
컴포넌트 테스트 부품 하나를 떼어 놓고 봅니다. 단위 테스트라고도 부릅니다
컴포넌트 통합 테스트 부품끼리 맞붙는 인터페이스와 그 사이의 주고받기를 봅니다
시스템 테스트 시스템이나 제품 전체의 동작과 능력을 봅니다
시스템 통합 테스트 이 시스템이 다른 시스템·외부 서비스와 붙는 인터페이스를 봅니다
인수 테스트 시스템이 사용자의 업무에 필요한 것을 채워 내보낼 준비가 됐는지 봅니다

단계를 차례로 밟는 개발 방식에서는 앞 레벨을 끝내는 조건이 흔히 다음 레벨을 시작하는 조건에 들어갑니다. 반복해서 조금씩 만드는 방식에서는 그렇지 않을 수도 있습니다.

레벨끼리는 무엇을 테스트하나, 무엇을 노리나, 무엇을 근거로 테스트를 짜나, 누가 맡나 같은 속성으로 갈립니다. 인수 테스트가 무게를 두는 것은 확인(validation)입니다. 확인은 만든 것이 이해관계자가 바라는 것과 맞는지 따져 보는 일입니다.

이해관계자는 그 소프트웨어를 쓰거나 돈을 내거나 운영하는 사람들입니다. 이 글에서 「받는 쪽」이라 하면 이들을 가리킵니다.

인수 테스트는 되도록 그 시스템을 쓸 사람이 직접 맡습니다. 흔히 시스템 속을 모르는 채로 바깥에서 입력을 넣고 결과만 보는 블랙박스 테스트로 합니다.

인수 조건

무엇을 보고 받아들일지는 미리 정해 둡니다. 받아들여지려면 만든 것이 채워야 하는 조건을 인수 조건(acceptance criteria)이라고 합니다. 「출제자가 silky 로 게임을 열고 참가자가 들어오면, 참가자는 다섯 글자 단어를 맞혀야 한다」가 인수 조건 하나입니다.

인수 조건을 적는 꼴은 흔히 둘입니다. 하나는 시나리오형입니다. 처음 상황, 일어나는 일, 기대하는 결과의 세 토막으로 적습니다. 영어로는 세 토막 앞에 Given·When·Then 을 붙입니다. 행위 주도 개발(Behavior-Driven Development, BDD)에서 쓰는 꼴입니다.

다른 하나는 규칙형입니다. 따질 항목을 목록으로 늘어놓습니다. 입력과 출력을 표로 맞대어 적기도 합니다. 꼴은 팀이 따로 정해도 됩니다. 조건이 분명하고 두 가지로 읽히지 않으면 됩니다.

인수 조건은 받는 쪽이 읽을 수 있는 말로 적습니다. 구현 세부가 섞이면 고객과 업무 담당자가 읽고 검토하기 어려워합니다. 받는 쪽이 「내가 바란 것이 이것이 맞다」고 말해 줄 수 있어야 기준이 됩니다.

인수 조건을 기능보다 먼저 테스트 케이스로 옮겨 두는 방식도 있습니다. 고객·개발자·테스터처럼 보는 눈이 다른 사람들이 함께 테스트 케이스를 만듭니다. 이 방식이 인수 테스트 주도 개발(Acceptance Test-Driven Development, ATDD)입니다. 이렇게 만든 테스트 케이스는 손으로 돌릴 수도 있고 자동으로 돌릴 수도 있습니다.

손으로 하는 인수 테스트와 자동 인수 테스트

인수 테스트는 사람이 손으로 하기도 합니다. 코드로 짜서 기계가 돌리기도 합니다. 시스템을 쓸 사람이 직접 써 보는 사용자 인수 테스트는 흔히 손으로 합니다. 인수 조건을 하나씩 따지는 테스트는 손으로도 자동으로도 할 수 있습니다.

애자일은 짧은 주기로 조금씩 만들어 내보내는 개발 방식입니다. 애자일 개발에서 인수 테스트는 소프트웨어가 어떻게 움직여야 하는지를 적은 것입니다. 대개 예시나 사용 시나리오로 적습니다. 많은 경우 도구가 이 시나리오를 자동으로 실행하게 하는 것이 목표입니다.

익스트림 프로그래밍(Extreme Programming, XP)에서는 고객이 사용자 스토리마다 테스트할 시나리오를 정합니다. 사용자 스토리는 사용자가 원하는 기능 하나를 짧은 문장으로 적은 것입니다. 스토리는 그 인수 테스트를 통과해야 끝난 것으로 칩니다. 인수 테스트는 자주 돌릴 수 있게 자동으로 짜 두어야 합니다.

XP 에서는 통과한 인수 테스트를 운영에 내보내기 전에 회귀 테스트로도 씁니다. 회귀 테스트는 전에 되던 기능이 여전히 되는지 다시 돌려 보는 테스트입니다.

자동 인수 테스트의 결과는 대개 통과 아니면 실패입니다. 실패는 제품에 결함이 있다는 신호입니다. 결함이 있다는 증명은 아닙니다.

자동 인수 테스트가 언제나 남는 장사로 여겨지지는 않습니다. 짜는 데 품이 많이 든다고 말하는 팀이 많습니다. 때로는 테스트가 깨지기 쉬워 유지가 짐이 된다고도 합니다. 이 비용이 얻는 것보다 큰지를 두고 전문가들 사이에 논쟁도 있었습니다.

구현 세부에 매인 인수 테스트는 동작과 상관없는 작은 변경에도 실패할 위험이 있습니다. 화면 입력 칸의 이름표를 가리키는 테스트라면 이름표 글자가 바뀌기만 해도 실패합니다. 제품의 동작은 하나도 안 바뀌었습니다.

배포 파이프라인 속 자동 인수 테스트

지속적 전달(continuous delivery)은 코드 변경을 언제든 내보낼 수 있는 상태로 유지하는 개발 방식입니다. 지속적 전달에서는 자동 인수 테스트를 배포 파이프라인의 한 단계로 둡니다. 배포 파이프라인은 변경 하나가 빌드부터 릴리스까지 거치는 단계를 차례로 이어 둔 것입니다.

파이프라인에 들어온 변경은 하나하나가 릴리스 후보입니다. 파이프라인은 알려진 문제를 걸러 내는 일을 맡습니다.

flowchart TD
    A["변경 하나"] --> B["빌드 · 패키지 만들기 · 단위 테스트"]
    B --> C["자동 인수 테스트"]
    C --> D["사람이 테스트할 환경에 배포"]
    D --> E["탐색적 테스트 · 사용성 테스트"]
    E --> F["릴리스"]
    C -.->|"결함이 나오면 단위 테스트 보강"| B

변경이 들어올 때마다 빌드가 돕니다. 빌드는 소스 코드를 어느 환경에나 배포할 수 있는 패키지로 묶습니다. 단위 테스트도 이때 돌립니다. 개발자는 몇 분 안에 결과를 받습니다.

이 단계를 통과한 패키지에 더 폭넓은 자동 인수 테스트를 돌립니다. 자동 테스트를 전부 통과한 패키지는 필요한 사람이 직접 골라 다른 환경에 배포할 수 있습니다. 다른 환경이란 사람이 테스트를 하는 환경과 마지막에 릴리스하는 환경 같은 것입니다.

사람이 하는 테스트로는 탐색적 테스트와 사용성 테스트 같은 것이 있습니다. 탐색적 테스트는 정해 둔 절차 없이 써 보며 문제를 찾습니다. 사용성 테스트는 쓰기 편한지 알아봅니다.

인수 테스트에서 결함이 나오면 단위 테스트를 보강할 곳을 찾아야 합니다. 결함 대부분은 단위 테스트에서 걸러져야 한다고 보기 때문입니다. 그림의 점선 화살표가 이 되돌이입니다.

인수 테스트와 종단 간 테스트

인수 테스트라고 해서 꼭 시스템 전체를 처음부터 끝까지 도는 테스트인 것은 아닙니다. 두 이름은 붙은 기준이 다릅니다.

인수 테스트는 테스트 레벨의 이름입니다. 위에서 본 대로 개발의 어느 단계에서 무엇을 놓고 보느냐로 나눈 이름입니다.

종단 간 테스트(end-to-end testing)는 업무 흐름을 처음부터 끝까지 운영과 비슷한 조건에서 테스트합니다. 종단 간 테스트는 테스트 레벨이 아니라 테스트 유형(test type)으로 묶입니다. 테스트 유형은 레벨과는 다른 기준으로 테스트를 묶는 이름입니다.

종단 간으로 도는 테스트, 화면을 거치는 테스트, 고객이 읽는 꼴로 적은 테스트를 팀들이 흔히 한데 섞어 부릅니다. 그러나 셋은 서로 따로 고르는 성질입니다. 업무 규칙이 복잡하면 테스트를 고객이 읽는 꼴로 적어 둘 수 있습니다. 그 테스트를 그 규칙을 맡은 모듈 하나에만 단위 테스트처럼 돌릴 수도 있습니다.

배경

개발자가 쓰는 단위 테스트는 개발자가 이해한 대로 코드가 도는지를 봅니다. 개발자가 요구를 잘못 알아들었다면 코드와 테스트가 같이 틀립니다. 요구를 정하는 과정이 망가진 팀은 단위 테스트를 꼼꼼히 써도 사업에 쓸모없는 코드를 만들기 쉽습니다. 코드가 튼튼하고 잘 다듬어져 있어도 그렇습니다.

그래서 받는 쪽의 기준으로 따로 따지는 테스트가 필요했습니다. 단위 테스트가 「코드를 바르게 만들었나」를 본다면 인수 테스트는 「바른 코드를 만들었나」를 봅니다. 고객과 개발자가 기준을 함께 적어 두면 둘 사이에 모호하지 않은 계약이 생깁니다. 그 테스트를 통과한 제품은 충분한 것으로 칩니다. 필요하면 둘이 테스트를 다듬거나 새로 더할 수는 있습니다.

납품받는 물건이 명세나 계약에 적은 대로인지 시험해 보고 받는 일은 소프트웨어 밖의 공학 분야에도 있습니다. 소프트웨어의 인수 테스트도 같은 말을 씁니다. XP 에서는 이 테스트를 처음에 기능 테스트(functional test)라고 불렀다가 인수 테스트로 이름을 바꿨습니다. 고객의 요구가 채워졌고 시스템을 받아들일 만하다는 것을 보장한다는 뜻이 더 잘 드러나서입니다.

예시

Gherkin 으로 적은 낱말 맞히기 게임

Gherkin 은 실행할 수 있는 명세를 적는 문법입니다. Cucumber 라는 테스트 도구가 이 문법으로 적은 파일을 읽어 실행합니다. 아래는 낱말 맞히기 게임 「Guess the word」 를 Gherkin 으로 적은 것입니다.

gherkin
Feature: Guess the word

  # The first example has two steps
  Scenario: Maker starts a game
    When the Maker starts a game
    Then the Maker waits for a Breaker to join

  # The second example has three steps
  Scenario: Breaker joins a game
    Given the Maker has started a game with the word "silky"
    When the Breaker joins the Maker's game
    Then the Breaker must guess a word with 5 characters

Maker 는 단어를 내는 출제자입니다. Breaker 는 그 단어를 맞히는 참가자입니다. 두 번째 시나리오가 세 토막을 다 씁니다.

Given 은 처음 상황인 「출제자가 silky 로 게임을 열었다」입니다. When 은 일어나는 일인 「참가자가 그 게임에 들어온다」입니다. Then 은 기대하는 결과인 「참가자는 다섯 글자 단어를 맞혀야 한다」입니다.

문장 어디에도 화면이나 데이터베이스 이야기가 없습니다. 시나리오는 기술이나 화면을 가정하지 않게 적어야 합니다. 컴퓨터가 없던 시절이라고 생각해도 말이 되어야 합니다.

Feature 아래에는 설명란을 둘 수 있습니다. 이 예시에는 없습니다. 설명란을 두면 기능에 대한 짧은 설명이나 업무 규칙, 곧 큰 틀의 인수 조건 같은 것을 적습니다.

flowchart TD
    A["시나리오의 스텝 문장"] --> B["스텝 정의 · 문장에 맞춰진 코드"]
    B --> C["시스템"]
    C --> D["시스템 밖으로 나온 결과 · 화면 · 보고서 · 메시지"]
    D --> E{"Then 의 기대 결과와 같은가"}
    E -->|같다| F["통과"]
    E -->|다르다| G["실패"]

스텝 문장 하나하나는 스텝 정의라는 코드 조각에 맞춰집니다. 기술 세부는 이 스텝 정의 안에 숨겨야 합니다. Then 의 스텝 정의는 시스템이 실제로 낸 결과를 문장이 말한 기대 결과와 견주어야 합니다.

견줄 결과는 시스템 밖으로 나오는 것이어야 합니다. 화면·보고서·메시지가 그렇습니다. 데이터베이스 안의 행처럼 시스템 깊이 묻힌 동작이어서는 안 됩니다.

FitNesse 결정 테이블로 적은 나눗셈

FitNesse 는 테스트를 입력 데이터와 기대 출력 데이터의 표로 적는 테스트 도구입니다. 아래는 계산기 앱의 나눗셈 기능을 시험하는 표 eg.Division 입니다.

numerator denominator quotient?
10 2 5.0
12.6 3 4.2
22 7 ~=3.14
9 3 <5
11 2 4<_<6
100 4 33

이런 표를 결정 테이블(Decision Table)이라고 합니다. 한 줄이 입력과 출력을 갖춘 시나리오 하나입니다. numerator(나뉠 수)와 denominator(나누는 수)가 입력 칸입니다. 물음표가 붙은 quotient?(몫) 칸이 기대 출력입니다.

첫 줄은 「10 을 2 로 나누면 5 가 나오나」라는 물음으로 읽습니다. 기대값 칸에는 비교도 적습니다. ~=3.14 는 3.14 와 거의 같다, <5 는 5 보다 작다, 4<_<6 은 4 와 6 사이라는 뜻입니다.

표를 돌리면 기대대로 나온 칸은 초록, 다르게 나온 칸은 빨강이 됩니다. 마지막 줄은 33 을 기대했습니다. 코드는 25 를 내놓아 그 칸이 빨갛게 됩니다. 틀린 것은 나눗셈 코드가 아니라 테스트 표입니다. 인수 테스트의 실패가 결함을 증명하지 않는다는 것이 이런 경우입니다.

갈래

인수 테스트는 누가 받아들일지 정하느냐, 무엇을 기준으로 정하느냐, 어디서 하느냐에 따라 형태가 갈립니다. 주된 형태로 흔히 아래 여섯을 꼽습니다.

사용자 인수 테스트

사용자 인수 테스트(User Acceptance Testing, UAT)는 그 시스템을 쓰려는 사용자가 받아들이는지를 가립니다. 사용자가 직접 써 보는 테스트라 흔히 손으로 합니다.

운영 인수 테스트

운영 인수 테스트(Operational Acceptance Testing, OAT)는 시스템 운영을 맡을 조직이 받아들일 수 있는지를 가립니다. 프로덕션 인수 테스트라고도 부릅니다. 백업 설비, 재해 복구 절차, 유지보수 절차, 보안 절차처럼 시스템을 굴리고 지키는 데 필요한 것을 점검하기도 합니다.

계약 인수 테스트

계약 인수 테스트는 계약서에 적어 둔 인수 조건을 기준으로 시스템을 테스트합니다. 시스템을 받아들이기 전에 합니다.

규정 인수 테스트

규정 인수 테스트는 시스템이 지켜야 할 규정을 지키는지 가립니다. 정부 규정, 법, 안전 기준 같은 것이 기준입니다.

알파 테스트

알파 테스트는 개발 조직 밖의 사람이 개발 쪽 테스트 환경에서 합니다. 만든 곳 안으로 바깥 사람을 불러 써 보게 하는 셈입니다.

베타 테스트

베타 테스트도 개발 조직 밖의 사람이 합니다. 알파 테스트와 갈리는 것은 장소입니다. 개발 쪽 테스트 환경이 아닌 바깥 현장에서 합니다.

경계

시스템 테스트를 통과했으면 인수 테스트도 끝난 걸까요? 아닙니다.

시스템 테스트도 시스템 전체를 놓고 봅니다. 처음부터 끝까지 이어지는 작업의 기능도 흔히 테스트합니다. 겉으로는 인수 테스트와 비슷해 보입니다. 둘을 가르는 것은 기준과 맡는 사람입니다.

시스템 테스트의 기준은 시스템의 명세입니다. 시스템 전체가 거기 적은 요구를 채우는지 봅니다. 이렇게 적어 둔 요구를 채웠는지 따지는 일을 검증(verification)이라고 합니다. 시스템 테스트는 독립된 테스트 팀이 맡을 수 있습니다.

인수 테스트의 기준은 사용자의 업무에 필요한 것입니다. 인수 테스트는 확인(validation)에 무게를 둡니다. 확인은 만든 것이 이해관계자, 곧 받는 쪽이 바라는 것과 맞는지 따지는 일입니다. 인수 테스트는 되도록 그 시스템을 쓸 사람이 맡습니다.

인수 테스트가 검증을 아예 안 하는 것은 아닙니다. 계약 인수 테스트처럼 계약서에 적어 둔 조건을 하나씩 따지는 갈래도 있습니다. 다만 무게는 확인에 있습니다.

flowchart TD
    N["사용자의 업무에 필요한 것"] -->|옮겨 적음| S["시스템의 명세"]
    S -->|명세대로 만듦| Y["시스템"]
    Y --> ST["시스템 테스트 · 시스템을 명세에 견줌 · 검증"]
    Y --> AT["인수 테스트 · 시스템을 업무에 필요한 것에 견줌 · 확인"]
    ST -.-> S
    AT -.-> N

그림에서 두 테스트는 견주는 곳이 다릅니다. 명세를 다 채운 시스템도 인수 테스트에서 떨어질 수 있습니다. 명세가 사용자의 바람을 잘못 옮겼다면 시스템 테스트는 통과합니다. 그 시스템을 받아들일지는 인수 테스트가 따로 정합니다.

관련 항목

인수 테스트와 나란히 놓이는 테스트 레벨

단위 테스트 · 컴포넌트 테스트 · 통합 테스트 · 컴포넌트 통합 테스트 · 시스템 테스트 · 시스템 통합 테스트

인수 테스트의 하위 종류

사용자 인수 테스트 · 운영 인수 테스트 · 계약 인수 테스트 · 규정 인수 테스트 · 베타 테스트 · 공장 인수 시험 · 현장 인수 시험

인수 테스트를 다른 테스트와 가르는 기준

테스트 레벨 · 테스트 유형 · 테스트 베이시스 · 검증 · 테스트 피라미드 · 테스트 4분면

인수 테스트가 확인할 기준을 적는 방식

인수 조건 · 사용자 스토리 · 요구사항 · Given-When-Then · 결정 테이블 · 실행 가능한 명세 · 완료의 정의

인수 테스트를 코드보다 먼저 쓰는 개발 방식

인수 테스트 주도 개발 · 행위 주도 개발 · 테스트 주도 개발 · 예제에 의한 명세 · 익스트림 프로그래밍

인수 테스트를 적고 돌리는 도구

Gherkin · Cucumber · FitNesse · 스텝 정의 · JUnit · Selenium · Playwright · REST Assured

인수 테스트가 한 단계를 맡는 배포 흐름

배포 파이프라인 · 지속적 통합 · 지속적 전달 · 지속적 배포 · 스테이징 환경 · 빌드 · 릴리스

인수 테스트와 함께 릴리스 전에 도는 테스트

회귀 테스트 · 탐색적 테스트 · 사용성 테스트 · 스모크 테스트 · 종단 간 테스트

인수 테스트가 시스템을 들여다보는 방식

블랙박스 테스트 · 화이트박스 테스트 · 그레이박스 테스트

인수 테스트에서 자주 나는 문제

불안정한 테스트 · 깨지기 쉬운 테스트 · 테스트 순서 의존성

인수 테스트가 속하는 상위 분류

QA와 테스트 · 소프트웨어 테스트 · 자동 테스트

다른 이름: acceptance test · acceptance testing · 인수 시험 · 승인 테스트 · 수용 테스트 · customer test · 고객 테스트