코드 커버리지는 개발 과정에서 흔히 사용되는 소프트웨어 품질 메트릭으로, 테스트된(또는 실행된) 코드의 정도를 결정할 수 있게 해줍니다. 최적의 코드 커버리지를 달성하기 위해서는 테스트 구현(또는 테스트 케이스)이 구현된 코드의 대부분을 테스트하는 것이 중요합니다.
자바, C#, 자바스크립트 등과 같은 언어를 위한 다양한 코드 커버리지 도구가 있습니다. 적합한 코드 커버리지 도구를 사용하는 것은 테스트된 코드의 백분율을 이해하고, 이상적인 코드 커버리지를 달성하기 위한 적절한 조치를 취하는 데 중요합니다.
최적의 코드 테스트를 위해 많은 회사들이 자코코-마벤 플러그인을 사용합니다. 자코코-마벤 플러그인은 자세한 코드 커버리지 보고서를 생성하는 데 도움이 되는 무료 코드 커버리지 라이브러리입니다. 이는 EclEmma 팀이 만든 기존 통합 라이브러리 연구에 기반하고 있습니다. 코드 커버리지는 제품 품질의 간단한 개요를 제공하는 데 큰 역할을 하며, 커버리지가 높을수록 테스트되지 않은 코드가 배포 주기에 들어가는 확률이 낮아집니다.
이 글에서는 자코코-마벤 플러그인에 대해 더 알아보고, 마벤을 사용하여 이 플러그인을 구현하는 방법을 배우겠습니다. 또한, Selenium을 통해 테스트에 대한 자세한 코드 커버리지 보고서를 생성하는 방법을 설명합니다.
코드 커버리지는 무엇인가?
소프트웨어 개발에서 코드 커버리지는 테스트 케이스가 실행될 때 애플리케이션의 소스 코드가 실행된 정도를 설명하는 측정입니다. 코드 커버리지 보고서가 생성되어 소프트웨어 애플리케이션의 코드 커버리지를 확인하고 분석할 수 있습니다. 이 코드 커버리지 보고서는 코드 품질을 보장하는 데 사용될 수 있습니다.
자코코-마베ン 플러그인은 코드 커버리지 보고서를 생성하는 데 사용됩니다. 높은 코드 커버리지를 가진 소스 코드는 테스트 중 더 많은 코드가 실행됩니다. 예를 들어, 테스트하는 소프트웨어가 100줄의 코드를 포함하고 소프트웨어에서 검증된 코드 줄 수가 90줄이라면, 해당 소프트웨어 애플리케이션의 코드 커버리지 비율은 90%가 됩니다.
코드 커버리지의 이점
코드 커버리지는 개발자, 테스터, 품질 보증 엔지니어에게 매우 유용한 지표입니다. 다음은 코드 커버리지의 주요 이점입니다:
- 코드 커버리지 보고서는 사용하지 않는 코드를 탐지하고 제거하는 데 유용한 통찰을 제공합니다. 이를 실装 최선의 실천을 따르면, 코드 유지보수성 향상과 더 나은 제품 품질로 이어집니다.
- 품질 보증은 테스트 실装을 사용하여 커버리지되지 않은 코드를 탐지할 수 있습니다.
- 개발자는 소프트웨어 개발 프로세스를 더 빠르게 마치고, 생산성, 확장성, 효율성을 높일 수 있습니다. 이는 시장 진입 시간(TTM)을 줄이는 데 기여합니다.
우리가 알고 있듯이, 코드 커버리지는 모든 소프트웨어 제품에 매우 중요합니다. 이제 코드 커버리지의 중요한 측면에 대한 빠른 복습을 마친 후, 자코코-마베ン 플러그인을 사용하여 코드 커버리지 보고서를 생성하는 핵심 주제에 깊이 다루겠습니다.
자코코-마베ン 플러그인이란?
자코코-마베ン(자바 코드 커버리지의 약자) 플러그인은 자바를 위한 오픈 소스 코드 커버리지 도구입니다. 이 도구는 코드 커버리지 보고서를 생성하고, 이클립스 IDE와 같은 통합 개발 환경(IDE)과 잘 통합됩니다.
또한 CI/CD 도구(예: Jenkins, Circle CI 등)와 프로젝트 관리 도구(예: SonarQube 등)와 원활하게 통합됩니다. 이는 Eclipse 재단의 일부이며 Eclipse에서 EclEmma 코드 커버리지 도구를 대체했습니다.
JaCoCo-Maven 플러그인은 어떻게 작동합니까?
- JaCoCo-Maven 플러그인은 런타임 에이전트를 통해 Java 코드를 계측하여 커버리지를 실행합니다. 간단히 말해, JVM(Java Virtual Machine)이 시작될 때 이 에이전트를 연결합니다. 이 에이전트는 JaCoCo 에이전트라고 합니다. 첫 번째 실행 start-agent는 이 JaCoCo 런타임 에이전트를 시작합니다.
- 클래스가 로드될 때마다 JaCoCo는 클래스가 테스트 프로세스 중에 호출될 때와 어떤 줄(코드)이 호출되는지 볼 수 있도록 클래스를 계측할 수 있습니다. 이 추적을 유지하면 두 번째 실행(즉, generate-report) 중에 코드 커버리지 통계를 실시간으로 작성합니다.
- 기본적으로 파일은 JVM이 종료되자마자 생성되지만 에이전트를 서버 모드로 실행하여 결과를 덤프하고 종료 전에 보고서를 생성하도록 트리거할 수도 있습니다. 아래는 JaCoCo 플러그인의 내부를 보여줍니다.
- JaCoCo-Maven 플러그인의 구성에서 목표와 규칙을 정의할 수 있습니다. 이를 통해 한도를 설정하고 코드 커버리지의 양을 확인하는 데 도움이 됩니다.
- Maven-surefire 플러그인은 기본 Maven 플러그인입니다. 이것은 JVM에서 테스트를 실행하고 커버리지 보고서를 제공합니다. JaCoCo 플러그인은 이미 플러그인(예: Surefire 플러그인)에 의해 실행된 코드를 계측합니다. 따라서 maven-surefire 플러그인의 종속성을 확인하는 것이 좋은 방법입니다.
JaCoCo-Maven 플러그인이 코드 커버리지에 왜 좋은가?
JaCoCo-Maven 플러그인이 코드 커버리지에 적합한 이유는 다음과 같습니다:
- 어떤 프로젝트를 작업할 때라도 개발자들은 대부분 IDE를 선호하는데, 이는 코딩과 테스팅 경험을 단순화시켜주기 때문입니다. JaCoCo는 Eclipse IDE에 EclEmma라는 이름으로 설치할 수 있으며, EclEmma를 마켓플레이스에서 다운로드하여 설치할 수 있습니다.
- JaCoCo 플러그인은 ANT, Maven, Gradle을 포함한 모든 유형의 빌드에 쉽게 추가할 수 있습니다. 또한 Jenkins, Circle CI 등과 같은 CI/CD 도구들과도 통합할 수 있어 다양한 사용 사례에 적합합니다.
- JaCoCo에 의해 생성된 코드 커버리지 보고서는 브라우저나 IDE에서 볼 수 있는 간단하면서도 유용한 HTML 파일입니다.
- JaCoCo는 오프라인 인스트루먼테이션도 제공합니다(즉, 모든 클래스가 어떤 테스트를 실행하기 전에 인스트루먼테이션됩니다).
- 보고서의 분석도 매우 쉽습니다. 색상 기반으로 구성되어 있으며 코드 커버리지의 정확한 백분율을 제공합니다.
Maven과 JaCoCo 플러그인을 설정하는 방법
Maven 프로젝트에서 코드 커버리지 보고서를 얻으려면 먼저 해당 프로젝트에 JaCoCo Maven 플러그인을 설정해야 합니다. JaCoCo 플러그인을 통합하면 코드 커버리지 분석 결과를 HTML 보고서로 검토할 수 있습니다. JaCoCo-Maven 플러그인의 현재 버전은 MVN 저장소에서 다운로드할 수 있습니다.
Maven 프로젝트에 JaCoCo Maven 플러그인을 통합하는 단계는 다음과 같습니다:
1. 모든 Maven 프로젝트에는 모든 의존성과 플러그인을 선언하는 데 사용되는 pom.xml
파일이 있습니다. JaCoCo-Maven 플러그인은 동일한 POM.xml
파일에 선언됩니다. 이에 대한 XML 코드는:
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.6</version>
</plugin>
이는 Maven 기반 프로젝트에서 JaCoCo 플러그인을 지정하기 위해 build 태그 아래에 추가된 기본 XML 코드입니다. 실행 태그에서 목표와 규칙을 지정함으로써 기능을 개선할 수 있습니다(예: 언제 보고서를 생성해야 하는지 언급 등).
2. 버전 태그 다음에 실행 태그를 추가합니다. 이 태그는 JaCoCo 에이전트를 가리키는 속성 또는 실행을 준비하고 VM(이 경우 JVM) 인수로 전달합니다.
3. 간단한 단위 테스트를 실행하려면 실행 태그에 설정된 두 개의 목표가 작동합니다. 최소한 prepare-agent 및 report 목표를 설정하는 것입니다.
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.6</version>
<executions>
<execution>
<id>prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
- Prepare-agent 목표: prepare-agent 목표는 JaCoCo 런타임 에이전트를 준비하여 실행 데이터를 기록합니다. 실행된 줄 수, 역추적 등을 기록합니다. 기본적으로 실행 데이터는
target/jacoco-ut.exec
파일에 기록됩니다. - Report 목표: report 목표는 JaCoCo 런타임 에이전트가 기록한 실행 데이터에서 코드 커버리지 보고서를 생성합니다. 단계 속성을 지정했으므로 테스트 단계 컴파일 후에 보고서가 생성됩니다. 기본적으로 실행 데이터는
target/jacoco-ut.exec
파일에서 읽고 코드 커버리지 보고서는target/site/jacoco/index.html
디렉토리에 기록됩니다.
4. 간단한 단위 테스트를 실행하기 위해 위의 설정은 잘 작동합니다. 그러나 코드 커버리지 보고서에 제약 조건을 적용해야 합니다(예: 대상 디렉토리 지정 등). 이는 구성 태그를 통해 수행할 수 있습니다:
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.6</version>
<executions>
<execution>
<id>prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<destFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</destFile>
<propertyName>surefireArgLine</propertyName>
</configuration>
</execution>
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
<configuration>
<dataFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</dataFile>
<outputDirectory>${project.reporting.outputDirectory}/jacoco-ut</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
첫 번째 실행 구성
위의 코드에서 볼 수 있듯이 destFile
와 같은 태그가 지정되어 있습니다. 태그에 대한 간단한 설명은 다음과 같습니다:
destFile
태그:destFile
태그는 실행 데이터가 포함된 파일의 경로를 설정하는 데 사용됩니다.propertyName-surefireArgLine
태그: 이 태그는 JaCoCo 런타임 에이전트의 설정을 포함하는 속성의 이름을 설정합니다. 또한 단위 테스트가 실행될 때 VM 인수 라인을 설정합니다.
두 번째 실행 구성
위의 코드에서 dataFile
와 같은 태그가 지정되어 있음을 알 수 있습니다. 태그에 대한 간단한 설명은 다음과 같습니다:
dataFile
태그:dataFile
태그는 실행 데이터가 포함된 파일의 경로를 설정하는 데 사용됩니다.outputDirectory
태그: 이 태그는 코드 커버리지 보고서의 출력 디렉토리를 설정합니다.
5. 또한 코드 커버리지 비율을 점검하기 위한 규칙을 구성 태그에 추가할 수 있습니다. 아래와 같이 수행할 수 있습니다:
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.6</version>
<executions>
<execution>
<id>prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<destFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</destFile>
<propertyName>surefireArgLine</propertyName>
</configuration>
</execution>
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
<configuration>
<dataFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</dataFile>
<outputDirectory>${project.reporting.outputDirectory}/jacoco-ut</outputDirectory>
</configuration>
</execution>
<execution>
<id>jacoco-check</id>
<goals>
<goal>check</goal>
</goals>
<configuration>
<rules>
<rule>
<element>PACKAGE</element>
<limits>
<limit>
<counter>LINE</counter>
<value>COVEREDRATIO</value>
<minimum>0.50</minimum>
</limit>
</limits>
</rule>
</rules>
</configuration>
</execution>
</executions>
</plugin>
세 번째 실행 구성
여기서 새로운 목표 검사가 정의됩니다. jacoco:check
목표는 규칙을 확인하기 위해 검증에 바인딩되며, 규칙은 rule 태그에 지정됩니다. 하나 이상의 규칙을 지정할 수 있는 유연성이 있습니다.
- Element 태그: 이 태그는 규칙이 적용되어야 하는 요소를 지정합니다.
- Limit 태그: counter, value, minimum 등의 태그는 코드 커버리지 백분율을 제한하는 데 사용됩니다. mvn clean verify와 같은 명령을 사용하여 규칙이 준수되었는지 확인할 수 있습니다.
6. JaCoCo-Maven 플러그인 구성에 정의할 수 있는 다양한 목표와 규칙이 있습니다.
Maven 및 JaCoCo 플러그인을 사용한 코드 커버리지 보고서
이 섹션에서는 JaCoCo Maven 플러그인을 사용하여 코드 커버리지 보고서를 생성하는 단계를 보여줍니다. 매우 간단한 테스트 시나리오를 사용하여 데모를 진행합니다. 그럼 시작하겠습니다.
사전 요구 사항
- Maven 3.0 이상: Maven은 프로젝트 개발 관리 및 이해 도구입니다. 최신 버전을 공식 Apache Maven 웹사이트에서 설치할 수 있습니다.
- Java 1.5 이상: 컴퓨터에 Java가 설치되어 있는지 확인해야 합니다. Java가 설치되어 있지 않은 경우 공식 Java 웹사이트에서 Java의 최신 버전을 다운로드하세요.
- Eclipse IDE for Java Developers: 선호하는 IDE를 사용할 수 있지만 이 데모에서는 Eclipse IDE를 사용했습니다.
간단한 Maven 프로젝트 생성 단계
- Eclipse IDE에서 파일 > 새로 만들기 > Maven 프로젝트로 이동합니다.
2. 새로운 대화 상자가 나타납니다. “기본 작업 공간 위치 사용” 체크박스가 선택되어 있는지 확인하고 “다음”을 클릭하세요.
3. 프로젝트에서 아카이브를 선택하려면 필터 옆에 있는 텍스트 상자에 org.apache.maven
을 입력하세요. maven-archetype-quickstart
를 선택하고 “다음”을 클릭하세요.
4. 이제 “그룹 ID”를 com.example
로 지정하고 “아티팩트 ID”를 jacoco-example로 지정하세요. “아티팩트 ID”는 우리 프로젝트의 이름입니다. 마지막으로 “완료” 버튼을 클릭하세요.
5. “프로젝트 탐색기”에서 프로젝트 파일 및 폴더 계층을 볼 수 있습니다.
JaCoCo Maven 플러그인을 POM.xml에 지정하는 방법
1. POM.xml
을 열고 태그로 스크롤하세요. 우리는 Maven 플러그인 목록에 있는 섹션에 JaCoCo-Maven 플러그인을 지정할 것입니다. 아래 코드를 복사하여 위의 태그에 붙여넣으세요:
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.6</version>
<executions>
<!--first execution : for preparing JaCoCo runtime agent-->
<execution>
<id>prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<!--second execution : for creating code coverage reports-->
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
2. 자동화된 웹 테스팅을 위한 JUnit의 보고서 생성을 보여주고 있으므로, POM.xml
에서 JUnit 의존성도 선언하겠습니다.
POM.xml
의 전체 내용은 다음과 같습니다:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>jacoco-example</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>jacoco-example</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<!-- JUnit dependencies added to run test cases -->
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Maven plugin for Project Management -->
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.0.0</version>
</plugin>
<!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.6</version>
<executions>
<execution>
<id>prepare-agent</id>
<goals><goal>prepare-agent</goal></goals>
</execution>
<execution>
<id>report</id>
<phase>test</phase>
<goals><goal>report</goal></goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
3. 프로젝트 디렉토리에서 src/main/java
에 있는 com.example.jacoco_lambdatest 패키지
로 이동하세요. 새로운 Java 클래스인 LambdaTest.java
를 생성하세요. 여기에 Selenium Grid의 원하는 기능을 제공하는 간단한 setUp()
함수를 작성할 것입니다.
package com.example.Jacoco_lambdatest;
import java.net.MalformedURLException;
import java.net.URL;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
public class LambdaTest {
public static String username = "<LambdaTest_Username>";
public static String accessKey = "<LambdaTest_AccessKey>";
public static DesiredCapabilities setUp() throws Exception {
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability("platform", "Windows 10");
capabilities.setCapability("browserName", "Chrome");
capabilities.setCapability("version", "87.0"); // If this cap isn't specified, it will just get the any available one
capabilities.setCapability("resolution","1024x768");
capabilities.setCapability("build", "First Test");
capabilities.setCapability("name", "Sample Test");
capabilities.setCapability("network", true); // To enable network logs
capabilities.setCapability("visual", true); // To enable step by step screenshot
capabilities.setCapability("video", true); // To enable video recording
capabilities.setCapability("console", true); // To capture console logs
return capabilities;
}
}
프로젝트에 JUnit 테스트 케이스 추가하기
1. 우리는 AppTest.java
에서 간단한 JUnit 테스트 케이스를 작성할 것입니다. 이것은 기본적으로 src/test/java
아래의 패키지 이름 com.example.jacoco_lambdatest
에 제공됩니다.
package com.example.Jacoco_lambdatest;
import java.net.MalformedURLException;
import java.net.URL;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import com.example.Jacoco_lambdatest.*;
public class AppTest {
public static RemoteWebDriver driver;
@Test
public void testScript1() throws Exception {
try {
DesiredCapabilities capabilities = LambdaTest.setUp();
String username =LambdaTest.username;
String accessKey = LambdaTest.accessKey;
RemoteWebDriver driver = new RemoteWebDriver(new URL("https://"+username+":"+accessKey+"@hub.lambdatest.com/wd/hub"),capabilities); driver.get("https://lambdatest.github.io/sample-todo-app/");
driver.findElement(By.name("li1")).click();
driver.findElement(By.name("li2")).click(); driver.findElement(By.id("sampletodotext")).clear(); driver.findElement(By.id("sampletodotext")).sendKeys("Yey, Let's add it to list");
driver.findElement(By.id("addbutton")).click();
driver.quit();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
코드 커버리지 보고서 생성
1. “Run As” 버튼을 클릭하고 구성을 Maven Test로 설정하십시오.
2. 대신 cmd(명령 줄)을 열고 프로젝트 폴더로 이동한 다음 maven 명령 “mvn test”를 실행할 수 있습니다.
3. JUnit 테스트를 실행하면 JaCoCo 에이전트가 자동으로 작동하게 됩니다. 이는 대상 디렉토리에 이진 형식으로 보고서를 생성하며 경로는 target/jacoco.exec
입니다. jacoco.exec
의 출력은 단독으로 해석할 수 없지만 SonarQube 및 플러그인과 같은 다른 도구는 이를 해석할 수 있습니다. 앞서 언급한대로 jacoco:report
목표는 HTML, CSV 및 XML과 같은 인기 있는 형식으로 읽기 쉬운 코드 커버리지 보고서를 생성합니다.
4. 빌드가 성공적이므로 대상 폴더로 이동한 다음 site > jacoco 폴더로 이동하십시오. 코드 커버리지 보고서(즉, index.html
)는 target/site/jacoco/index.html
에 있습니다. 보고서는 다음과 같습니다:
5. 보고서에서 com.example.jacoco_lambdatest>LambdaTest
를 클릭하여 미세한 수준으로 드릴다운할 수 있습니다.
6. 특정 함수를 클릭하면 LambdaTest.java
에서 보다 자세한 보기를 얻게 됩니다.
7. 여기에서 여러 가지 색상의 다이아몬드를 많이 볼 수 있습니다. 녹색, 노란색, 빨간색 등이 있습니다. 이는 보고서에서 어떤 코드 줄이 실행되었고 언제 실행되었는지를 상징하는 데 사용되는 사양입니다. 보고서 분석의 다음 절에서 이에 대해 더 배울 것입니다. 이제 Jacoco Maven 플러그인을 통해 코드 커버리지 보고서를 성공적으로 생성했습니다.
코드 커버리지 보고서 분석
우리의 코드 커버리지 보고서는 94%의 명령어 커버리지와 100%의 분기 커버리지를 보여주며, 이는 훌륭한 코드 커버리지 점수입니다. 나중에는 더 많은 테스트 케이스를 추가하여 100% 코드 커버리지 점수를 달성하려고 시도할 것입니다.
JaCoCo가 보고서에서 보여주는 38개의 명령어는 자바 코드 명령어가 아니라 바이트코드 명령어를 가리킵니다. JaCoCo 보고서는 분기에 색상이 다른 다이아몬드와 코드 줄에 배경 하이라이트 색상을 사용하여 코드 커버리지를 시각적으로 분석하는 데 도움을 줍니다. 코드 커버리지 보고서에서 볼 수 있는 다이아몬드에 대한 간단한 설명은 다음과 같습니다:
- 빨간 다이아몬드; 테스트 단계에서 어떤 분기도 실행되지 않았음을 나타냅니다.
- 노란 다이아몬드: 코드가 부분적으로 커버됨(즉, 일부 분기가 실행되지 않음)을 나타냅니다.
- 녹색 다이아몬드: 모든 분기가 테스트에서 실행되었음을 나타냅니다.
동일한 색상 코드는 코드 줄 커버리지에 대한 배경 하이라이트 색상에도 적용됩니다.
보고서는 주로 세 가지 중요한 지표를 제공합니다:
- 줄 커버리지: 이는 테스트에 의해 호출된 자바 바이트코드 명령어의 수에 따라 코드가 실행된 양을 반영합니다.
- 분기 커버리지: 이는 소스 코드에서 실행된 분기의 백분율을 보여줍니다. 일반적으로 if/else 또는 switch 문입니다.
- 순환 복잡성: 이는 코드 내에서 모든 가능한 경로를 커버하기 위해 필요한 경로 수를 통해 코드 복잡성을 반영합니다. 또한 전체 코드를 커버하기 위해 구현해야 하는 테스트 케이스의 수를 나타냅니다. 코드에 switch 또는 문이 없으므로 순환 복잡성은 하나가 됩니다. 전체 코드를 커버하기에 충분한 하나의 실행 경로만 있습니다.
코드 커버리지 개선을 위해 더 많은 테스트 케이스 소개
1. 더 나은 코드 커버리지를 달성하려면 이전에 테스트 구현을 통해 커버되지 않은 코드를 테스트하는 더 많은 테스트가 필요합니다.
2. src/test/java
에서 AppTest.java
로 이동하여 더 많은 테스트 케이스를 추가하세요.
3. AppTest.java
에 추가된 새 테스트 케이스는 다음과 같습니다.
@Test
public void testScript2() throws Exception {
try {
DesiredCapabilities capabilities = LambdaTest.setUp();
String username = LambdaTest.username;
String accessKey = LambdaTest.accessKey;
RemoteWebDriver driver = new RemoteWebDriver(new URL("https://"+username+":"+accessKey+"@hub.lambdatest.com/wd/hub"),capabilities); driver.get("https://lambdatest.github.io/sample-todo-app/"); driver.findElement(By.name("li2")).click();
driver.findElement(By.name("li3")).click();
driver.findElement(By.id("sampletodotext")).clear(); driver.findElement(By.id("sampletodotext")).sendKeys("Yes, Let's add it to list"); driver.findElement(By.id("addbutton")).click();
driver.quit();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
@Test
public void testScript3() throws Exception {
try {
DesiredCapabilities capabilities = LambdaTest.setUp();
String username = LambdaTest.username;
String accessKey = LambdaTest.accessKey;
RemoteWebDriver driver = new RemoteWebDriver(new URL("https://"+username+":"+accessKey+"@hub.lambdatest.com/wd/hub"),capabilities); driver.get("https://lambdatest.github.io/sample-todo-app/"); driver.findElement(By.name("li4")).click();
driver.findElement(By.id("sampletodotext")).clear(); driver.findElement(By.id("sampletodotext")).sendKeys("Yes, Let's add it!");
driver.findElement(By.id("addbutton")).click();
driver.quit();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
4. Maven JaCoCo 보고서를 실행하여 새 커버리지 보고서를 게시하겠습니다.
5. JaCoCo는 최소 요구 사항을 선언함으로써 코드 커버리지 점수를 추적하는 간단하고 쉬운 방법을 제공합니다. 이러한 요구 사항을 충족하지 못하면 빌드가 실패하고, 그렇지 않으면 빌드가 성공합니다.
6. 이러한 요구 사항은 POM.xml
에서 규칙으로 지정할 수 있습니다. POM.xml
의 두 번째 <execution>
태그 뒤에 ‘check’ 목표를 지정하여 새 실행을 지정하십시오.
<!--Third execution : used to put a check on the entire package-->
<execution>
<id>jacoco-check</id>
<goals>
<goal>check</goal>
</goals>
<configuration>
<rules>
<rule>
<element>PACKAGE</element>
<limits>
<limit>
<counter>LINE</counter>
<value>COVEREDRATIO</value>
<minimum>0.50</minimum>
</limit>
</limits>
</rule>
</rules>
</configuration>
</execution>
7. 이를 통해 커버리지 비율을 50%로 제한하고 있습니다. 이는 테스트 단계에서 코드의 최소 50%가 커버되어야 함을 의미합니다.
8. Maven clean verify 명령어를 실행하여 jacoco:check
목적에 설정된 규칙들이 충족되었는지 확인할 수 있습니다.
9. 로그에는 “모든 커버리지 체크가 충족되었습니다”라고 표시되어 있으며, 우리의 코드 커버리지 점수가 94%로, 최소 50%를 상회하고 있습니다.
람다테스트 시큐리티 그리드의 자동화 테스팅
JaCoCo 플러그인을 사용한 Maven 프로젝트
클라우드에서의 Selenium 테스팅은 더 나은 브라우저 커버리지, 높은 테스트 커버리지, 그리고 시장 진입 시간을 가속화하는 데 도움을 줍니다. Selenium에서의 병렬 테스팅은 위에서 언급한 요구 사항들을 달성하는 데 도움을 줍니다.
LambdaTest 클라우드 Selenium 그리드는 2000개 이상의 다양한 브라우저와 운영 체제에서 자동화 스크립트를 실행할 수 있는 클라우드 기반의 확장 가능한 Selenium 테스팅 플랫폼입니다.
사전 준비
JUnit과 Selenium을 사용하여 테스트 스크립트를 실행하려면 환경을 설정해야 합니다. 먼저 LambdaTest에 계정을 생성해야 합니다. 사용자 이름과 액세스 키를 프로필 섹션에서 확인해 두세요.
Java Selenium 테스팅을 위해 이 샘플 프로젝트를 사용할 것입니다.
Eclipse IDE에 프로젝트 가져오기
GitHub에서 junit-selenium-sample
프로젝트의 zip 파일을 다운로드한 후, 아래 언급된 단계에 따라 Eclipse IDE에 가져옵니다:
1. 이클립스 IDE로 이동하여 “파일” 메뉴를 클릭하고 “가져오기”를 선택합니다. 새 대화 상자가 나타납니다.
2. 텍스트 상자에 Maven을 입력하고 “기존 Maven 프로젝트”를 선택한 후 “다음”을 클릭합니다.
3. 다음 대화 상자에서 “찾아보기”를 클릭하고 프로젝트 폴더로 이동합니다. 또한 POM.xml 파일의 경로를 제공하는 체크박스를 선택한 후 “완료”를 클릭합니다.
4. 프로젝트가 이클립스 IDE에 성공적으로 로드됩니다.
POM.xml 파일에 종속성 추가
1. POM.xml
을 열고, JUnit, Selenium, JaCoCo Maven 플러그인의 종속성을 추가합니다. 종속성을 추가한 후 POM.xml
의 코드는 다음과 같아야 합니다:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.lambdatest</groupId>
<artifactId>lambdatest-junit-sample</artifactId>
<version>1.0-SNAPSHOT</version>
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<surefire.version>2.19.1</surefire.version>
<config.file>default</config.file>
</properties>
<dependencies>
<!--JUnit dependency-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
<scope>test</scope>
</dependency>
<!--Selenium dependency-->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>2.52.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!--Apache Maven Plugins-->
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
</plugin>
<!--JaCoCo Maven Plugin-->
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.6</version>
<executions>
<execution>
<id>prepare-agent</id>
<goals><goal>prepare-agent</goal></goals>
</execution>
<execution>
<id>report</id>
<phase>test</phase>
<goals><goal>report</goal></goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
<em><a href="https://github.com/rachnaagrawal/junit-selenium-sample/blob/master/pom.xml" target="_blank" rel="nofollow">Github</a></em>
JUnit 자동화 테스트를 위한 원하는 기능 구성
1. LambdaTest Selenium Automation Grid에 연결하기 위해 첫 번째로 수행하는 작업은 원격 웹 드라이버를 호출하는 것입니다. 이 원격 드라이버는 브라우저, 브라우저 버전, 운영 체제 등과 같은 기능을 요구하여 환경을 구축합니다. 그 코드는 다음과 같습니다:
WebDriver driver = new RemoteWebDriver(new URL("https://" + username + ":" + accesskey + "@hub.lambdatest.com/wd/hub"),
DesiredCapabilities.firefox()); //A class named DesiredCapabilities is used to create an environment as a Firefox browser.
2. JUnit 자동화 테스트 코드에서 브라우저, 브라우저 버전, 운영 체제 정보 등과 같은 기능을 사용자 정의하여 기능 객체를 통해 전달할 수 있습니다.
3. LambdaTest는 이 프로세스를 매우 쉽게 만들어 놓았습니다. 내장된 기능 생성기를 제공하여 입력에 따라 원하는 기능에 대한 코드를 자동으로 생성합니다. 예를 들어, 우리의 구성은 다음과 같습니다:
필드 |
선택한 값 |
운영 체제 |
Windows 10 |
브라우저 |
Chrome |
브라우저 버전 |
62.0 |
해상도 |
1024×768 |
Selenium 버전 |
3.13.0 |
4. 위에서 지정한 구성을 기능 생성기에서 선택하고 LambdaTestBaseTest.java
에 붙여넣습니다.
LambdaTest 사용자 이름과 액세스 키를 필수 Java 클래스에 지정
1. 프로젝트 탐색기에서 세 개의 Java 클래스를 볼 수 있습니다:
LambdaTestBaseTest
.java (Java Selenium 테스팅을 위한 설정이 포함되어 있음).Parallelized.java
(LambdaTest Selenium 그리드에서 병렬 테스팅을 위한 Junit 테스트가 포함되어 있음).SimpleTest.java
(간단한 단위 테스트가 포함되어 있음).
2. LambdaTestBaseTest.java
는 필요한 데이터를 가져옵니다. 예를 들어 원하는 기능, 사용자 이름 및 액세스 키를 src/test/resources
에 제공된 config.json
에서 가져옵니다.
3. config.json
에 원하는 기능, 사용자 이름 및 액세스 키를 지정합니다. 이 JSON 파일은 여러 구성을 제공하여 Selenium를 사용한 병렬 테스팅을 실현하는 데 사용됩니다.
[ { "tunnelName":"LambdaTest tunnel",
"buildName":"running Java Selenium Tests",
"testName":"Jacoco JUnit Test",
"username": "user-name",
"access_key":"access-key",
"operatingSystem" : "win10",
"browserName" : "chrome",
"browserVersion" : "62.0",
"resolution" : "1024x768" }]
JUnit을 사용한 Selenium로의 단위 테스팅:
1. SimpleTest.java
는 JaCoCo Maven 플러그인을 사용하여 단위 테스트 케이스를 지정하고 테스트 및 코드 커버리지를 수행하기 위한 Java 클래스입니다.
package com.lambdatest;
import com.lambdatest.LambdaTestBaseTest;
import org.junit.Test;
import org.openqa.selenium.By;
import static org.junit.Assert.assertEquals;
public class SimpleTest extends LambdaTestBaseTest {
/**
* Simple Test case annotation for JUnit Test
* @throws Exception
*/
@Test
public void validateUser() throws Exception {
driver.get("https://lambdatest.github.io/sample-todo-app/");
driver.findElement(By.name("li1")).click();
driver.findElement(By.name("li2")).click();
driver.findElement(By.id("sampletodotext")).clear();
driver.findElement(By.id("sampletodotext")).sendKeys("Yey, Let's add it to list");
driver.findElement(By.id("addbutton")).click();
}
}
2. 다음 작업을 수행할 샘플 할 일 애플리케이션을 여는 간단한 Selenium WebDriver 테스트입니다.
- 처음 두 항목을 “완료.”로 표시합니다.
- 목록에 새 항목을 추가합니다.
- 추가된 항목을 반환합니다.
3. 터미널에서 mvn test 명령을 실행하여 테스트 케이스를 빌드하고 실행합니다.
4. 이제 LambdaTest 계정에 로그인하고 “Automation”으로 이동하십시오. 빌드 이름 “JUnit JaCoCo Tests” 아래에서 실행한 테스트를 찾을 수 있습니다.
5. “JUnit JaCoCo Tests”를 클릭하고 자세히 검토하십시오. LambdaTest는 비디오를 녹화했으므로 시각적으로도 볼 수 있습니다.
JaCoCo Maven 플러그인을 통한 코드 커버리지 보고서 생성:
- 이제 LambdaTest Selenium Grid에서 JUnit 테스트 케이스를 실행했으므로 JaCoCo Maven 플러그인을 통해 코드 커버리지 보고서가 생성되어야 합니다.
- 대상 폴더로 이동하면
jacoco.exec
로 보고서의 이진 형식을 찾을 수 있습니다. - 코드 커버리지 보고서의 HTML, CSV 및 XML 형식은
target/site/jacoco
폴더에서 각각index.html, jacoco.csv
및jacoco.xml
로 볼 수 있습니다. - 이제 코드 커버리지 점수를 개선하고 생성된 코드 커버리지 보고서를 분석해 볼 수도 있습니다.
결론
이 글에서는 Java 프로젝트에 대한 코드 커버리지 보고서를 생성하기 위해 JaCoCo-Maven 플러그인을 사용하는 방법을 살펴보았습니다. 또한 LambdaTest Selenium Grid 클라우드의 민첩성과 확장성을 활용하여 테스트 프로세스를 자동화하였습니다. 하지만, 100% 코드 커버리지는 효과적인 테스팅을 반영하지 않는다는 점을 기억하세요. 이는 테스트 중에 실행되는 코드의 양만 보여줍니다.
그러나 이는 버그의 수를 줄이고 소프트웨어 릴리스 품질을 향상시키는 데 도움이 됩니다. 또한 빌드 프로세스에 최소한의 오버헤드를 추가하고 개발 팀이 에지 케이스를 추가하거나 방어적 프로그래밍을 구현할 때 특정 임계값을 유지하도록 합니다.
Source:
https://dzone.com/articles/how-to-generate-code-coverage-report-jacoco-maven