일반 영어처럼 읽히고, 코드와 함께 Git에 저장되며, 모든 CI 파이프라인에서 실행되는 API 테스트를 원하신다면 Karate가 바로 그 목적을 위해 만들어졌습니다. Java 메서드 대신 Given / When / Then 단계로 테스트를 작성할 수 있도록 도메인 특정 언어(DSL)를 사용합니다. 이 가이드는 Karate가 무엇인지, 기능 파일이 어떻게 작동하는지, 그리고 실행 가능한 샘플을 안내합니다.
Karate란 무엇인가
Karate는 API를 위한 오픈 소스 Java 기반 테스트 자동화 프레임워크입니다. 행동 기반 개발(Behavior-Driven Development)에서 유래한 동일한 Given/When/Then 구조인 Gherkin을 사용하여 .feature 파일에 각 테스트를 시나리오로 기술합니다. Cucumber와 같은 도구와의 차이점은 단계 정의 글루 코드를 작성할 필요가 없다는 것입니다. Karate는 HTTP 단계, 어설션, JSON 처리를 내장하여 제공하므로, 작동하는 API 테스트에는 Java가 전혀 필요하지 않습니다.

이 프로젝트는 API 테스트 그 이상을 포함합니다. 저장소에는 목(mock), 성능 테스트(Gatling을 통해), UI 자동화를 위한 모듈이 포함되어 있습니다. 이 가이드에서는 대부분의 팀이 가장 먼저 찾는 API 테스트 코어에 중점을 둡니다.
테스트는 일반 텍스트 파일이므로 버전 관리가 잘 됩니다. 풀 리퀘스트 diff는 어떤 어설션이 변경되었는지 정확히 보여줍니다. 이는 코드 검토 및 Git-네이티브, 코드 기반 워크플로우와 잘 어울립니다.
Given/When/Then 스타일에 익숙하지 않다면, 행동 기반 개발에 대한 초급 가이드에서 그것이 어디에서 왔고 왜 팀에서 사용하는지 설명합니다.
작동 방식: 기능 파일 및 karate-config.js
Karate 테스트는 기능 파일로 시작합니다. 각 파일에는 하나의 Feature:와 하나 이상의 Scenario: 블록이 있습니다. 시나리오 내부에서는 Given으로 요청을 설정하고, When으로 요청을 실행하며, Then으로 어설션을 수행합니다.
Karate의 자체 빠른 시작이 보여주는 구조는 다음과 같습니다:
Feature: User API
Scenario: List all users
Given url 'https://jsonplaceholder.typicode.com'
And path 'users'
When method get
Then status 200
And match response == '#[10]'
위에서 아래로 읽어보세요. url은 기본 주소를 설정합니다. path는 리소스를 추가합니다. method get은 요청을 보냅니다. status 200은 HTTP 코드를 확인합니다. 마지막 줄은 응답이 정확히 10개의 항목을 가진 JSON 배열임을 어설션합니다. #[10]은 Karate 마커이며 JavaScript가 아닙니다. 어설션 섹션에서 이 마커에 대해 더 자세히 설명합니다.
여기 Gherkin은 표준 Given/When/Then입니다. 해당 구문에 대해 더 깊이 알고 싶다면 BDD 및 API 테스트를 위한 Gherkin 가이드를 참조하십시오.
대부분의 프로젝트는 환경별 값(개발 기본 URL, 스테이징 토큰, 프로드 엔드포인트)이 필요합니다. Karate는 karate-config.js라는 단일 파일로 이를 처리합니다. 이 파일은 테스트 실행 전에 한 번 실행되며, 모든 시나리오가 읽을 수 있는 구성 객체를 반환합니다.
function fn() {
var env = karate.env || 'dev';
var config = {
baseUrl: 'https://jsonplaceholder.typicode.com'
};
if (env === 'qa') {
config.baseUrl = 'https://qa.example.com';
}
return config;
}
karate.env는 런타임에 전달하는 시스템 속성에서 가져옵니다. 단일 기능 파일을 건드리지 않고 환경을 전환할 수 있습니다. 시나리오에서는 주소를 하드코딩하는 대신 Given url baseUrl을 작성합니다.
샘플 시나리오
요청 본문을 사용하여 무언가를 작성해 봅시다. 이 시나리오는 사용자를 생성하고, 상태를 확인하며, 응답 형식을 검증합니다.
Feature: Create user
Background:
* url baseUrl
Scenario: Create a new user returns 201
Given path 'users'
And request { name: 'Ada', job: 'engineer' }
When method post
Then status 201
And match response.name == 'Ada'
And match response.id == '#string'
몇 가지 주목할 점이 있습니다. Background: 블록은 파일의 각 시나리오 이전에 실행되므로, 기본 URL을 한 번만 설정합니다. *는 와일드카드 단계입니다. Karate는 *를 Given, When, Then과 동일하게 취급하므로, 문법에 신경 쓰지 않고 설정 단계를 작성할 수 있습니다. request 키워드는 JSON 페이로드를 직접 받습니다. 직렬 변환기(serializer)나 POJO가 필요 없습니다. 그리고 #string은 id 필드가 존재하고 문자열임을 어설션하지만, 특정 값에 고정하지 않는 퍼지 매처입니다.
어설션 및 JSON 매칭
어설션은 Karate가 제 역할을 하는 부분입니다. 핵심 키워드는 match입니다. 실제 값과 예상 값을 비교하고, 불일치가 있으면 테스트를 실패시킵니다.
정확한 일치는 동등성을 확인합니다:
And match response == { id: '#number', name: 'Ada', job: 'engineer' }
#number, #string, #boolean, #uuid 토큰은 퍼지 매처(fuzzy matcher)입니다. 이들은 리터럴 값을 요구하지 않고 타입과 존재 여부를 어설션하므로, 서버가 생성된 ID나 타임스탬프를 반환할 때 테스트가 안정적으로 유지됩니다.
필드의 일부만 신경 쓰는 경우 contains를 사용하십시오:
And match response contains { name: 'Ada' }
응답에 다른 필드가 10개 있더라도 name이 Ada와 같은 한 이 테스트는 통과합니다. Karate는 부분 매칭에 대한 더 세밀한 제어를 위해 !contains, contains only, contains any, contains deep도 지원합니다.
배열도 검증할 수 있습니다. match response == '#[10]'은 길이가 10인 배열임을 어설션합니다. each를 사용하여 모든 요소에 스키마를 적용할 수 있습니다:
And match each response == { id: '#number', name: '#string' }
이 한 줄은 배열의 모든 객체에 숫자 id와 문자열 name이 있는지 확인합니다. 이러한 종류의 형태 검증은 일반적인 테스트 프레임워크에서는 루프와 여러 어설션이 필요합니다. 응답 검증에 대한 더 넓은 그림을 원하시면, API 어설션에 대한 실용 가이드에서 도구 전반의 패턴을 다룹니다.
데이터 기반 테스트 및 CI
실제 테스트 스위트는 동일한 로직을 많은 입력에 대해 실행합니다. Karate는 Scenario Outline과 Examples 테이블로 이를 처리합니다. 꺾쇠괄호 안의 플레이스홀더는 각 행에서 채워집니다.
Scenario Outline: Create users from a table
Given url baseUrl
And path 'users'
And request { name: '<name>', job: '<job>' }
When method post
Then status 201
And match response.name == '<name>'
Examples:
| name | job |
| Ada | engineer |
| Grace | scientist |
| Alan | analyst |
이것은 시나리오를 각 행당 한 번씩 세 번 실행합니다. 인라인 테이블 대신 외부 파일에서 행을 읽을 수도 있으며, 이는 대량의 데이터 세트를 기능 파일에서 분리합니다.
Examples:
| read('classpath:test-data/users.json') |
Karate는 JSON 및 CSV 파일을 이러한 방식으로 읽으므로, 테스트 데이터는 팀이 관리하기 선호하는 어떤 곳에든 저장할 수 있습니다.
지속적 통합을 위해서는 두 가지 경로가 있습니다. Maven 또는 Gradle 프로젝트에서는 Karate가 JUnit 5를 통해 실행됩니다. karate-junit5 종속성을 추가하고 러너를 기능 파일에 연결하면 mvn test가 다른 유닛 테스트처럼 실행합니다. 이는 기존 CI 단계에 특별한 도구가 필요 없다는 것을 의미합니다.
두 번째 경로는 빌드 도구가 필요 없는 독립 실행형 jar입니다. 프로젝트의 릴리스에서 karate.jar를 다운로드하고 기능 파일을 직접 실행합니다. jar는 최신 Java 버전을 필요로 하므로, 최소 요구 사항은 릴리스 노트를 확인하십시오.
java -jar karate.jar src/test/java/features
태그로 필터링하고, 병렬로 실행하며, 출력 디렉토리를 선택할 수 있습니다:
java -jar karate.jar --tags @smoke --threads 4 --output reports src/test/java/features
시스템 속성으로 환경을 전달하면, 이는 karate-config.js 내의 karate.env로 흐릅니다:
java -jar karate.jar -Dkarate.env=qa src/test/java/features
Karate는 각 실행 후에 출력 디렉토리에 HTML 보고서를 작성하므로, 파이프라인 아티팩트에서 실패를 쉽게 검사할 수 있습니다. 더 넓은 CI 그림을 보려면 CI/CD에서 API 테스트를 자동화하는 방법을 참조하십시오.
장점과 단점
Karate는 분명한 장점을 가지고 있습니다. 테스트는 일반 영어에 가깝게 읽히므로, Java에 능숙하지 않은 사람들에게도 진입 장벽을 낮춥니다. 퍼지 매처와 each를 포함한 내장 JSON 매칭은 많은 어설션 상용구를 제거합니다. 모든 것이 Git 아래의 텍스트 파일에 존재하므로, 테스트는 소스 코드처럼 검토되고 차이점을 비교할 수 있습니다. 그리고 HTTP 이상을 다루므로, 팀은 나중에 도구를 전환하지 않고도 목(mock)이나 성능 테스트를 추가할 수 있습니다.
단점 또한 분명합니다. Karate는 JVM에서 실행되므로, 기본 사항 이상을 위해 Java가 설치되어 있어야 하고 JVM 생태계에 대한 숙련도가 필요합니다. DSL은 그 자체로 학습해야 할 것이며, 구문은 쉽게 읽히지만 올바른 매처와 재사용 패턴을 작성하는 데는 연습이 필요합니다. 재사용 가능한 로직, 사용자 정의 도우미 및 복잡한 설정은 종종 JavaScript 함수 또는 Java 상호 운용성으로 다시 이끌게 됩니다. 그리고 테스트가 코드이기 때문에, 팀의 비개발자들은 보통 도움 없이 이를 작성하거나 편집할 수 없습니다.
이것이 비난은 아닙니다. 코드 우선 프레임워크의 특징입니다. 문제는 그러한 특징이 팀이 일하고 싶어 하는 방식과 일치하는지 여부입니다.
Karate 대 코드 없는 접근 방식 (Apidog)
Karate는 코드 기반이며 Git-네이티브입니다. 기능 파일을 작성하고, 커밋하며, 빌드 도구 또는 jar에서 실행합니다. 이는 애플리케이션 옆의 버전 제어 시스템에 테스트를 두고 싶고 JVM에 익숙한 엔지니어에게 적합합니다.
Apidog은 동일한 목표를 시각적이고 코드 없는 방식으로 달성합니다. UI에서 테스트 시나리오를 구축하고, 요청을 연결하며, DSL을 작성하는 대신 클릭하여 어설션을 추가합니다. 전체 API 라이프사이클(설계, 디버깅, 목업, 문서화)이 한 곳에 있으므로, 테스트는 이미 정의한 엔드포인트와 스키마를 재사용할 수 있습니다. 이는 Java 프로젝트를 관리하고 싶지 않은 QA 엔지니어와 제품 담당자에게 진입 장벽을 낮춥니다.

시각적 스위트는 UI에 고정되어 있지 않습니다. Apidog은 Apidog CLI를 통해 CI에서 헤드리스로 실행하므로, 코드 없는 스위트도 자동화된 파이프라인에 적합합니다. Node로 설치합니다:
npm install -g apidog-cli
그런 다음 저장된 시나리오 또는 스위트를 ID로 트리거하고, 환경을 지정하며, 보고서 형식을 선택합니다:
apidog run --access-token "$APIDOG_ACCESS_TOKEN" -t <scenarioOrSuiteId> -e <environmentId> -r cli,html,junit
-t 플래그는 시나리오, 폴더 또는 스위트를 대상으로 합니다. -e는 환경을 선택합니다. -r은 하나 이상의 리포터(cli, html, json, junit)를 선택합니다. 데이터 기반 실행의 경우 -d (또는 --iteration-data)는 데이터 파일 경로 또는 테스트 데이터 ID를 사용합니다. CLI는 헤드리스이며 Node를 실행할 수 있는 모든 CI 단계에서 실행됩니다. 저장된 Apidog 시나리오를 실행하며, 대화형 요청 발송기나 로드 생성기는 아닙니다. CI/CD를 위한 Apidog CLI에서 전체 워크스루를, Apidog CLI 대 Newman에서 다른 러너와의 비교를 참조하십시오.
두 접근 방식 모두 CI에서 헤드리스로 실행되는 자동화된 API 테스트를 생성합니다. 차이점은 작성 스타일입니다. Karate는 Git에 DSL을 작성하는 것을 선호하고, Apidog은 파이프라인으로 내보낼 수도 있는 UI에서 클릭하는 것을 선호합니다.
선택 방법
팀이 개발자 중심이고 JVM에 익숙하며, 애플리케이션 바로 옆에 코드로서 테스트 버전을 관리하고 싶다면 Karate를 선택하십시오. 일반 텍스트 기능 파일과 내장 JSON 매칭은 엔지니어가 테스트 스위트를 처음부터 끝까지 소유할 때 효과를 발휘합니다.
QA 및 제품 담당자가 작성자에 포함될 때, 기존 설계 및 문서화 워크플로우에 테스트를 연결하고 싶을 때, 또는 API 검사를 실행하기 위해 Java 빌드를 유지 관리하고 싶지 않을 때는 Apidog과 같은 코드 없는 도구를 선택하십시오. CLI를 통해 여전히 CI 적용 범위를 얻을 수 있습니다.
일부 팀은 두 가지를 모두 사용합니다. 깊이 있고 코드 중심의 회귀 스위트에는 Karate를 사용하고, 비개발자도 확장할 수 있는 광범위하고 빠른 커버리지에는 시각적 도구를 사용합니다. 여전히 옵션을 고려 중이라면, API 자동화 테스트 프레임워크를 선택하는 방법에 대한 개요에서 의사 결정 기준을 제시합니다.
자주 묻는 질문
Karate를 사용하려면 Java를 알아야 하나요? 아니요, 기본적인 API 테스트를 작성하는 데는 필요하지 않습니다. 기능 파일은 Gherkin DSL을 사용하며, Karate는 내장된 HTTP 및 어설션 단계를 제공합니다. 테스트를 실행하려면 Java가 설치되어 있어야 하며, 사용자 정의 도우미나 복잡한 재사용이 필요할 때는 약간의 Java 또는 JavaScript 지식이 도움이 됩니다.
Karate는 Cucumber와 어떻게 다른가요? 둘 다 Gherkin의 Given/When/Then 구문을 사용합니다. Cucumber는 각 단계를 지원하기 위해 단계 정의 코드를 작성해야 합니다. Karate는 API 테스트 단계를 직접 제공하므로, 표준 HTTP 테스트를 위해 유지 관리해야 할 글루 코드가 없습니다.
Karate는 Maven이나 Gradle 없이 실행될 수 있나요? 예. 프로젝트 릴리스에서 독립 실행형 karate.jar를 다운로드하고 java -jar karate.jar <path>로 기능 파일을 실행할 수 있습니다. 어떤 빌드 도구 없이도 태그, 병렬 스레드 및 사용자 정의 출력 디렉토리를 지원합니다.
#string 또는 #[10] 구문은 무엇을 의미하나요? 이것들은 Karate의 퍼지 매처(fuzzy matcher)입니다. #string은 필드가 어떤 값이든 문자열임을 어설션하고, #number는 숫자임을, #[10]은 길이가 10인 JSON 배열임을 어설션합니다. 이를 통해 생성된 값을 하드코딩하지 않고 응답 형식을 검증할 수 있습니다.
코드 없는 API 테스트도 CI에서 실행될 수 있나요? 예. Apidog과 같은 시각적 도구는 저장된 시나리오를 Apidog CLI로 내보냅니다. Apidog CLI는 헤드리스이며 Node를 사용하여 모든 CI 단계에서 실행될 수 있습니다. 따라서 UI에서 테스트를 작성하고 자동화된 파이프라인 실행을 여전히 얻을 수 있습니다.
