TestNG를 이용할 때 테스트 실행 순서, 테스트 실행군 등의 결정을 비롯해서, 파라미터를 입력할때는 TestNG.xml
파일을 이용하게 됩니다.
이번 포스트에서는 간단하게 xml파일을 왜쓰는지에 대한 소개글을 작성해봅니다.
xml파일 얘기를 하기 전에, testNG는 Junit처럼 실행을 위한 별도의 main 메소드가 필요없습니다. 그냥 테스트코드를 실행해주면 됩니다.
실행방법은, 실행하고자 하는 메소드에 @Test
어노테이션을 달아주기만 하면 됩니다. TestNG의 기본 실행단위는, @Test
어노테이션이 달린 메소드 단위입니다.
@Test
public void Demo() {
System.out.println(“hello”);
}
그런데, TestNG도 그렇고 JUnit도 그렇고 main
메소드 없이 어떻게 코드를 실행할 수 있는 것일까요?
JVM은, 프로그램의 엔트리포인트로 main
메소드만 허용하고 있습니다. 이것은 다르게 말하면 테스트 프레임워크가 엄청 특출난 그런 것이 아니라는 얘기입니다.
TestNG를 예로 들어보면, TestNG.class
를 확인하게 하면 내부에 main
메소드를 가지고 있습니다.
즉, TestNG 자체에 main
메소드가 있어서, 테스트코드를 실행하게 되면 자동으로 TestNG의 main
을 실행하게 되는 것입니다.
//TestNG.class
public static void main(String[] argv) {
TestNG testng = privateMain(argv, (ITestListener)null);
System.exit(testng.getStatus());
}
그런데 프로그램을 만들어나가다 보면 자연스럽게 테스트코드도 수십개 혹은 수백개, 수천개 단위로 늘어나게 되며 관리 코스트가 발생하게 됩니다.
테스트를 하다보면 특정 테스트만 실행하고 싶을 때도 있고, 혹은 특정 데이터 파라미터를 이용하여 실행하고 싶을 수도 있습니다. 같은 코드를 병렬적으로 동시실행해야할 때도 있습니다.
TestNG는 이러한 것을 설정해주기 위해, xml파일을 이용합니다.
하나의 xml파일은 하나 이상의 TestSuite를 의미합니다. 실행하고자 하는 테스트들에 대한 정보를 이 xml파일에 기재하고, TestNG는 이것을 읽어들이고 테스트를 수행하게 됩니다.
A suite is represented by one XML file. It can contain one or more tests and is defined by the tag.
A test is represented by and can contain one or more TestNG classes.
A TestNG class is a Java class that contains at least one TestNG annotation. It is represented by the tag and can contain one or more test methods.
A test method is a Java method annotated by @Test in your source.
이 xml파일을 이용해서, 특정 케이스들을 한 번에 실행시켜줄 수도 있고, 특정 테스트케이스에 특정 파라미터를 넘겨줄 수도 있으며, 병렬적으로 실행도 가능합니다.
아래는 하나의 예시입니다.
<?xml version=“1.0” encoding=“UTF-8”?>
<!DOCTYPE suite SYSTEM “http://testng.org/testng-1.0.dtd”>
<suite name="All Test Suite">
<test verbose="2" preserve-order="true" name="TestNG1">
<classes> <!-- module -->
<class name=“testNG.RunningTestcases”> </class>
</classes> <!-- module -->
</test>
</suite>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="All Test Suite">
<test verbose="2" preserve-order="true"
name="AppWebLogin">
<classes>
<class name="priorityExecute.AppLoginTest"/>
<class name="priorityExecute.WebLoginTest"/>
</classes>
</test>
<test name="APILogin">
<classes>
<class name="priorityExecute.APILoginTest"/>
</classes>
</test>
</suite>
xml파일은 프로젝트 폴더의 최상단 루트위치에 생성해줍니다.
각 태그들에 대한 계층은 아래와 같습니다.
classes
태그를 사용하고, 그 내부에 class 태그를 여러개 사용하여 생성합니다.@Test
어노테이션을 포함하는 하나의 자바 클래스파일 단위입니다.@Test
어노테이션을 직접적으로 사용하는 자바의 메소드 단위입니다.메소드의 하위 태그로는 exclude
와 include
를 사용할 수 있습니다.
예를 들어, 아래의 xml이 있다고 가정합시다.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="All Test Suite">
<test verbose="2" preserve-order="true"
name="AppWebLogin">
<classes>
<class name="priorityExecute.AppLoginTest"/>
<class name="priorityExecute.WebLoginTest"/>
</classes>
</test>
<test name="APILogin">
<classes>
<class name="priorityExecute.APILoginTest">
<methods>
<exclude name="internalApiLogin"/>
</methods>
</class>
</classes>
</test>
</suite>
2번째 테스트인 APILogin
테스트에서, internalApiLogin
테스트메소드를 제외(exclude
) 하고 있습니다. exclude
는 선언된 메소드를 제외한 나머지 메소드들만 실행합니다.
<exclude name="internalApiLogin"/>
사용 전
사용 후
include
는 반대로, 해당 메소드만 실행하고 나머지 메소드는 실행하지 않습니다.
어느 특정 패키지 내부에 있는 모든 테스트케이스 메소드들에 대해 실행하고 싶다면, 그렇게 지정할 수 있습니다.
<test>
<packages>
<package name=“package”/>
</packages>
</test>
테스트케이스에 대해 선언할 때 정규표현식으로 지정할 수도 있습니다. 어떠한 일정한 패턴을 가지고 있다면, methods
나 package
태그에서 정규표현식으로 지정할 수 있습니다.
<class name="priorityExecute.AppLoginTest">
<methods>
<include name="android.*"/>
</methods>
</class>
여러가지 시나리오, 기능들을 하나의 xml파일 내에서 관리하기란 쉬운일은 아닐 것입니다. 때문에 xml파일을 여러개 만들고, 파라미터를 통해서 지정하여 실행할 수도 있습니다.
mvn clean test -DsuiteXmlFile=testng.xml
-DsuiteXmlFile=
에 실행하고자하는 xml파일 명을 기재합니다.
그래들의 경우는 조금 번거롭습니다.
def suite1 = project.hasProperty("suite1")
def suite2 = project.hasProperty("suite2")
test {
useTestNG() {
dependsOn cleanTest
useDefaultListeners = true
if(suite1) {
suites "src/test/resources/simpleSuite.xml"
}
if(suite2) {
suites "src/test/resources/advancedSuite.xml"
}
}
}
gradlew test -Psuite1
gradlew test -Psuite2
gradlew test -Psuite1 -Psuite2
위와 같은 형태로 실행해볼 수 있습니다.
위 순서에 대해서는 TestNG의 어노테이션을 사용할 때, 어노테이션의 실행 순서에도 영향이 있는만큼, 숙지해야할 내용이기도 합니다.
다음 포스트에서는 테스트케이스의 실행 우선순위에 대해서 같이 기재해봅니다.
ref