TestNG
1. 개요
1. 개요
TestNG는 자바 프로그래밍 언어를 위한 테스트 프레임워크이다. 이 프레임워크는 단위 테스트부터 통합 테스트, 엔드투엔드 테스트에 이르기까지 다양한 수준의 소프트웨어 테스트를 지원하도록 설계되었다. 개발자 세드릭 비스트에 의해 창안되어 2004년에 최초로 등장하였다.
TestNG라는 이름은 "Next Generation"을 의미하며, 기존의 JUnit과 같은 테스트 프레임워크의 한계를 넘어 더 강력하고 유연한 기능을 제공하는 차세대 도구를 지향한다. 이는 애너테이션을 적극 활용하고, 테스트 그룹화, 의존성 관리, 매개변수화된 테스트 실행 등 복잡한 테스트 시나리오를 구성할 수 있는 풍부한 기능 세트를 특징으로 한다.
2. 주요 특징
2. 주요 특징
TestNG는 JUnit과 NUnit의 장점을 수용하면서도 더 강력하고 유연한 기능을 제공하기 위해 설계되었다. 이 프레임워크는 단순한 단위 테스트를 넘어 통합 테스트와 엔드투엔드 테스트와 같은 더 복잡한 테스트 시나리오를 지원하는 데 중점을 둔다. 애너테이션을 광범위하게 활용하여 테스트 메서드의 실행 순서, 그룹화, 의존성 설정을 직관적으로 정의할 수 있다는 점이 핵심 특징이다.
테스트 구성 측면에서 TestNG는 테스트 그룹 개념을 도입하여 관련 테스트들을 논리적으로 묶고 선택적으로 실행할 수 있게 한다. 또한 의존성 테스트 기능을 통해 특정 테스트 메서드가 다른 테스트의 성공 여부에 의존하도록 설정할 수 있어 테스트 간의 관계를 명시적으로 관리할 수 있다. 매개변수화 테스트를 지원하여 동일한 테스트 로직을 다양한 입력 데이터 세트로 반복 실행하는 것이 용이하다.
실행 및 관리 측면에서는 XML 기반의 설정 파일을 사용하여 테스트 스위트를 유연하게 구성할 수 있다. 이를 통해 패키지, 클래스, 메서드, 그룹 단위로 테스트를 포함하거나 제외시키고, 병렬 실행을 설정하는 등 복잡한 실행 정책을 정의할 수 있다. 또한 HTML 리포트를 비롯한 다양한 형태의 상세한 테스트 실행 리포트를 자동으로 생성하여 결과 분석을 돕는다.
3. 기본 애너테이션
3. 기본 애너테이션
3.1. 테스트 메서드 애너테이션
3.1. 테스트 메서드 애너테이션
TestNG에서 테스트 메서드를 정의하고 구성하는 데 사용되는 주요 애너테이션은 @Test이다. 이 애너테이션은 메서드가 테스트 케이스임을 프레임워크에 알리는 역할을 한다. @Test 애너테이션은 단순히 테스트 메서드를 표시하는 것을 넘어, 다양한 속성을 통해 테스트의 동작을 세밀하게 제어할 수 있다. 예를 들어, enabled 속성으로 테스트의 활성화 여부를 설정하거나, timeOut 속성으로 테스트의 최대 실행 시간을 제한할 수 있다.
테스트 메서드의 실행 순서를 지정하거나 특정 조건에서만 테스트를 실행하도록 하는 애너테이션도 제공된다. @BeforeMethod와 @AfterMethod 애너테이션은 각 테스트 메서드가 실행되기 전과 후에 반드시 실행되어야 하는 설정 및 정리 코드를 담는 메서드에 사용된다. 이는 단위 테스트의 격리성을 보장하는 데 중요한 역할을 한다. 또한, @Test 애너테이션의 dependsOnMethods 속성을 사용하면 특정 테스트 메서드 간의 의존 관계를 선언할 수 있어, 테스트 실행 순서를 논리적으로 구성하는 데 도움이 된다.
보다 복잡한 테스트 시나리오를 위해 데이터 제공자와 연동하는 기능도 지원된다. @DataProvider 애너테이션이 붙은 메서드는 테스트 데이터를 생성하여, @Test 애너테이션에서 dataProvider 속성으로 이를 참조하는 매개변수화 테스트를 작성할 수 있게 한다. 이를 통해 동일한 테스트 로직을 다양한 입력값으로 반복 실행할 수 있다. 이러한 애너테이션들의 조합은 JUnit 같은 다른 프레임워크에 비해 더 풍부한 테스트 구성 옵션을 제공한다.
3.2. 설정 메서드 애너테이션
3.2. 설정 메서드 애너테이션
TestNG는 테스트 실행의 생명주기를 세밀하게 제어하기 위해 다양한 설정 메서드 애너테이션을 제공한다. 이 애너테이션들은 테스트 클래스나 테스트 스위트의 초기화 및 정리 작업을 특정 시점에 실행되도록 설정하는 데 사용된다. 주요 설정 메서드로는 @BeforeSuite, @AfterSuite, @BeforeTest, @AfterTest, @BeforeGroups, @AfterGroups, @BeforeClass, @AfterClass, @BeforeMethod, @AfterMethod 등이 있다.
@BeforeMethod와 @AfterMethod 애너테이션은 각 테스트 메서드가 실행되기 전과 후에 한 번씩 호출되어, 테스트마다 필요한 공통 준비 및 정리 작업(예: 데이터베이스 연결 설정/해제, 테스트 데이터 초기화)을 수행한다. 반면, @BeforeClass와 @AfterClass는 테스트 클래스 전체의 수명주기에서 딱 한 번씩만 실행되며, 클래스 레벨의 비용이 큰 리소스를 관리하는 데 적합하다.
보다 넓은 범위의 설정을 위해 @BeforeSuite/@AfterSuite는 전체 테스트 스위트의 시작과 끝에서 실행되고, @BeforeTest/@AfterTest는 XML 설정 파일 내의 <test> 태그 단위로 실행을 제어한다. 또한 @BeforeGroups와 @AfterGroups를 사용하면 특정 테스트 그룹의 테스트들이 실행되기 전후에만 코드를 실행할 수 있어, 그룹별로 다른 설정 환경을 구성하는 데 유용하다. 이러한 계층적 구조를 통해 개발자는 테스트의 각 단계(스위트, 테스트, 클래스, 메서드)에 맞춰 효율적으로 리소스를 관리하고 테스트의 격리성을 보장할 수 있다.
4. 테스트 구성
4. 테스트 구성
4.1. 테스트 그룹
4.1. 테스트 그룹
TestNG의 테스트 그룹 기능은 테스트 케이스를 논리적으로 분류하고 선택적으로 실행할 수 있게 해주는 핵심 기능이다. 개발자는 @Test 애너테이션의 groups 속성을 사용하여 특정 테스트 메서드를 하나 이상의 그룹에 할당할 수 있다. 이렇게 그룹화된 테스트는 전체 테스트 스위트 중에서 특정 기능 영역(예: 단위 테스트, 통합 테스트, 회귀 테스트)이나 모듈별로 묶어서 관리할 수 있으며, 테스트 실행 시 특정 그룹만 포함하거나 제외하는 방식으로 유연하게 제어가 가능하다.
테스트 그룹의 주요 장점은 테스트의 구성과 실행 정책을 세밀하게 정의할 수 있다는 점이다. 예를 들어, 실행 시간이 긴 엔드투엔드 테스트를 'slow' 그룹으로 지정하고, 빠른 단위 테스트는 'fast' 그룹으로 분리할 수 있다. 일상적인 빌드에서는 'fast' 그룹만 실행하고, 야간 빌드 시에만 'slow' 그룹을 포함하는 방식으로 지속적 통합 파이프라인을 최적화할 수 있다. 또한, 그룹 간에 계층 구조를 정의하는 메타그룹 기능을 지원하여 복잡한 포함 관계를 설정할 수 있다.
테스트 그룹은 XML 설정 파일을 통해서도 관리된다. 실행 설정 파일(testng.xml) 내에서 <groups> 태그를 사용하면, 어떤 그룹을 실행할지(<run>) 또는 제외할지(<exclude>)를 선언적으로 정의할 수 있다. 이는 특정 환경(예: 개발 환경, 스테이징 환경)에서만 필요한 테스트나, 특정 버그와 연관된 테스트를 분리하여 실행하는 데 유용하다. 테스트 그룹을 효과적으로 활용하면 대규모 테스트 코드베이스를 체계적으로 운영하고, 테스트 실행 시간을 단축하며, 테스트 목적에 맞는 다양한 실행 시나리오를 구성할 수 있다.
4.2. 의존성 테스트
4.2. 의존성 테스트
TestNG는 테스트 메서드 간의 의존성을 명시적으로 정의하고 관리할 수 있는 기능을 제공한다. 이는 특정 테스트가 다른 테스트의 성공 여부에 따라 실행 여부가 결정되어야 하는 복잡한 테스트 시나리오를 구성할 때 유용하다. @Test 애너테이션의 dependsOnMethods 또는 dependsOnGroups 속성을 사용하여 의존 관계를 설정할 수 있다.
의존성 테스트의 주요 동작 방식은 다음과 같다. 의존된 테스트 메서드가 성공적으로 실행되어야만 의존하는 테스트가 실행된다. 만약 의존된 테스트가 실패하거나 스킵되면, 의존하는 모든 테스트는 실행되지 않고 자동으로 스킵(skip) 처리된다. 이는 불필요한 테스트 실행을 방지하고 테스트 실패의 원인을 더 명확하게 추적할 수 있게 한다. 또한 alwaysRun 속성을 true로 설정하면 의존된 테스트의 결과와 상관없이 항상 실행되도록 할 수 있다.
의존성은 메서드 이름이나 테스트 그룹 이름을 기준으로 지정할 수 있다. dependsOnMethods는 같은 클래스나 다른 클래스에 있는 특정 테스트 메서드에 의존할 때 사용하며, dependsOnGroups는 하나 이상의 그룹에 속한 모든 테스트에 의존성을 설정할 때 사용한다. 이를 통해 로그인 기능 테스트에 성공한 후에만 장바구니 추가나 결제 흐름 테스트를 실행하는 것과 같은 통합 테스트 시나리오를 쉽게 구성할 수 있다.
이러한 의존성 관리 기능은 테스트 스위트의 논리적 구조를 명확히 하고, 테스트 실행 순서를 제어하며, 초기 조건이 실패한 경우의 불필요한 테스트 실행과 에러 로그 축적을 방지한다. 이는 JUnit 4까지는 공식적으로 지원하지 않았던 기능으로, TestNG의 차별화된 장점 중 하나로 꼽힌다.
4.3. 매개변수화 테스트
4.3. 매개변수화 테스트
매개변수화 테스트는 동일한 테스트 로직을 서로 다른 입력값과 예상 결과값으로 반복 실행할 수 있는 기능이다. 이를 통해 유사한 테스트 케이스를 여러 번 작성하는 번거로움을 줄이고, 테스트 데이터와 테스트 로직을 분리하여 유지보수성을 높일 수 있다.
TestNG에서는 @DataProvider 애너테이션을 사용하여 매개변수화 테스트를 구현한다. @DataProvider가 붙은 메서드는 Object[][] 형태의 데이터를 반환해야 하며, 각 행이 하나의 테스트 실행에 사용될 매개변수 집합을 나타낸다. 테스트 메서드는 @Test(dataProvider = "데이터제공자이름") 형식으로 특정 데이터 제공자를 지정하여 호출된다.
애너테이션 | 역할 | 반환 타입 |
|---|---|---|
| 테스트에 필요한 데이터를 제공하는 메서드를 정의 |
|
| 특정 데이터 제공자로부터 데이터를 받아 테스트를 실행 | - |
매개변수화 테스트는 데이터베이스 쿼리 결과, CSV 파일, 엑셀 시트 등 외부 데이터 소스를 테스트에 활용할 때 특히 유용하다. 또한 단위 테스트에서 경계값 분석이나 다양한 입력 조합을 체계적으로 검증하는 데 효과적이다. TestNG의 이 기능은 JUnit 4의 @Parameterized 테스트와 유사한 목적을 가지지만, 더 유연한 데이터 제공 방식을 지원한다는 차이점이 있다.
5. 실행 및 구성
5. 실행 및 구성
5.1. XML 설정 파일
5.1. XML 설정 파일
TestNG는 XML 설정 파일을 통해 테스트 실행을 유연하게 구성할 수 있다. 이 파일은 테스트 스위트의 구조를 정의하며, 실행할 테스트 클래스, 테스트 메서드, 테스트 그룹, 그리고 실행 순서나 의존성과 같은 다양한 파라미터를 지정할 수 있다. XML 설정을 사용함으로써 코드를 수정하지 않고도 테스트 범위를 쉽게 변경하거나, 서로 다른 환경(예: 개발, 스테이징, 운영)에 맞춘 테스트 세트를 구성할 수 있다.
XML 설정 파일의 기본 구조는 <suite> 루트 요소로 시작하며, 그 안에 하나 이상의 <test> 섹션을 포함한다. 각 <test> 섹션은 실행할 클래스나 메서드를 <classes> 및 <methods> 요소로 정의한다. 또한 <groups> 요소를 사용하여 특정 그룹에 속한 테스트만을 포함하거나 제외할 수 있어, 통합 테스트나 단위 테스트와 같은 범주별 실행이 가능하다.
이 구성 파일의 강력한 기능 중 하나는 매개변수 전달이다. <parameter> 태그를 사용하여 테스트 메서드에 이름-값 쌍 형태의 데이터를 제공할 수 있으며, 이는 데이터 드리븐 테스트를 구현하는 데 핵심적이다. 또한, 테스트 실행 전후에 특정 메서드를 실행시키는 리스너(TestNG 리스너)를 XML에서 직접 등록할 수 있어, 로그 기록이나 환경 설정 같은 공통 작업을 중앙에서 관리할 수 있다.
XML 설정은 복잡한 테스트 시나리오를 관리하는 데 필수적이다. 여러 개의 XML 파일을 만들어 각각 다른 테스트 목적(예: 빠른 스모크 테스트, 전체 회귀 테스트)에 사용하거나, <!DOCTYPE> 선언을 통해 다른 설정 파일을 포함(include)하여 설정을 모듈화할 수 있다. 이렇게 함으로써 대규모 자바 프로젝트에서도 테스트 자동화와 유지보수성을 크게 향상시킬 수 있다.
5.2. 리포트 생성
5.2. 리포트 생성
TestNG는 테스트 실행 결과를 다양한 형식으로 자동 생성하는 리포트 기능을 제공한다. 기본적으로 HTML 리포트를 생성하며, 이는 테스트 스위트의 실행 요약, 성공 및 실패한 테스트 메서드 목록, 실행 시간, 예외 스택 트레이스 등 상세한 정보를 포함한다. 이러한 리포트는 테스트 결과를 시각적으로 확인하고 분석하는 데 유용하다.
리포트의 생성 위치와 형식은 XML 설정 파일을 통해 사용자가 지정할 수 있다. 기본 출력 디렉토리는 test-output이며, 이 디렉토리 내에 index.html 파일이 메인 리포트 페이지 역할을 한다. 리포트에는 테스트를 그룹별로 필터링하여 볼 수 있는 기능도 포함되어 있어, 대규모 테스트 스위트를 관리할 때 효율적이다.
또한 TestNG는 엑셀 파일이나 JUnit 형식의 XML 리포트 생성도 지원한다. 이를 통해 지속적 통합 서버나 다른 테스트 리포트 도구와의 연동이 용이해진다. 사용자는 필요에 따라 커스텀 리스너를 구현하여 자신만의 리포트 형식을 생성할 수도 있다.
리포트 생성 기능은 테스트의 신뢰성을 높이고, 디버깅 과정을 가속화하며, 팀 내에서 테스트 결과를 공유하는 표준화된 방법을 제공한다. 이는 소프트웨어 테스트의 필수적인 부분으로, TestNG가 자바 개발 환경에서 선호되는 테스트 프레임워크 중 하나가 되는 이유를 보여준다.
6. JUnit과의 비교
6. JUnit과의 비교
TestNG는 JUnit과 함께 자바 개발에서 가장 널리 사용되는 테스트 프레임워크 중 하나이다. 두 프레임워크 모두 단위 테스트 작성에 필수적인 도구이지만, 설계 철학과 제공하는 기능 면에서 뚜렷한 차이점을 보인다. 가장 근본적인 차이는 JUnit이 테스트 주도 개발 철학에 기반하여 단순함과 명확함을 강조하는 반면, TestNG는 보다 포괄적이고 유연한 테스트 요구사항, 특히 통합 테스트나 엔드투엔드 테스트와 같은 더 복잡한 시나리오를 지원하기 위해 설계되었다는 점이다.
주요 기능적 차이점은 다음과 같다. TestNG는 @BeforeSuite, @AfterTest와 같은 풍부한 설정 메서드 애너테이션을 제공하여 테스트 생명주기를 세밀하게 제어할 수 있다. 또한 테스트 그룹 기능을 통해 테스트 케이스를 논리적으로 분류하고 선택적으로 실행하는 것이 가능하며, dependsOnMethods 속성을 통한 의존성 테스트를 명시적으로 지원한다. 반면 JUnit은 각 테스트의 독립성을 중시하여 의존성 테스트를 공식적으로 지원하지 않는 경향이 있다. 매개변수화 테스트의 구현 방식도 다르며, TestNG는 데이터 제공자 방식을 사용하는 데 비해 JUnit은 @ParameterizedTest 애너테이션 등을 활용한다.
실행 및 구성 측면에서 TestNG는 XML 설정 파일을 통한 중앙 집중식 테스트 스위트 구성이 핵심 강점이다. 이를 통해 다양한 테스트 클래스, 그룹, 패키지를 조합하고 병렬 실행 전략을 정의하는 등 복잡한 테스트 계획을 수립할 수 있다. JUnit 5 이전의 JUnit은 이러한 유연한 스위트 구성에 한계가 있었으나, JUnit 5에서는 @Suite 애너테이션 등의 도입으로 개선되었다. 요약하면, JUnit은 단위 테스트에 최적화된 간결하고 견고한 표준이라면, TestNG는 대규모이고 복잡한 테스트 요구사항을 가진 엔터프라이즈 애플리케이션 테스트에 더 적합한 강력하고 확장성 있는 프레임워크라고 볼 수 있다.
7. 여담
7. 여담
TestNG는 JUnit의 한계를 극복하고자 개발된 프레임워크로, 특히 대규모 통합 테스트와 엔드투엔드 테스트에 적합한 강력한 기능을 제공한다는 평가를 받는다. 애너테이션 기반의 선언적 스타일과 XML 설정 파일을 통한 유연한 테스트 구성은 복잡한 소프트웨어 테스트 시나리오를 관리하는 데 큰 장점으로 작용한다.
이 프레임워크는 자바 개발 커뮤니티 내에서 단위 테스트를 넘어선 광범위한 테스트 요구를 충족시키는 도구로 자리 잡았다. 개발자 세드릭 비스트에 의해 2004년에 처음 소개된 이후, 지속적인 개선을 통해 의존성 주입, 테스트 그룹, 병렬 실행 같은 현대적인 테스트 패러다임을 적극적으로 수용해 왔다.
TestNG의 설계 철학은 유연성과 확장성에 중점을 두고 있으며, 이는 다양한 플러그인과 통합 개발 환경 지원을 통해 구현된다. 이러한 특징들은 TestNG가 지속적 통합 파이프라인에서 중요한 역할을 수행할 수 있게 하는 기반이 된다.
