Gradle이 뭐야?

이성민·2025년 11월 7일

woowacourse

목록 보기
4/11
post-thumbnail

Gradle, 태스크(Task), 테스트 정리

이번 우테코 8기 프리코스에 새로 생긴 오픈 미션을 진행하면서 Gradle 관련 오류가 일어나서 그 과정에 공부한 내용을 정리하려고 한다.
Gradle은 단순히 의존성을 주입하는 도구가 아니라 빌드 전체의 실행 흐름을 제어하는 시스템이다.
이번 포스트에서는 Gradle의 핵심 개념인 태스크(Task) 와 테스트 설정(test {} vs tasks.named('test') {}) 차이에 대해 정리했다.

Gradle이란?

컴파일, 테스트, 패키징, 실행, 배포의 작업을 모두 자동화 시켜주는 Groovy 언어 기반 오픈소스 빌드 도구이다.

Build란?

Build는 소스코드를 실행 가능한 어플리케이션으로 준비시키는 일련의 과정이다.

흔히 빌드와 함께 나오는 컴파일, 링크 등의 용어는 모두 빌드의 하위 과정이다.
각각의 소스코드 파일을 기계어로 컴파일한 뒤 의존하는 소스코드를 연결시켜 실행 가능한 상태로 만들어주는 것이다.

따라서 Build는 코드 실행 전까지의 모든 과정을 일컫는다.

Gradle 빌드 단계

Gradle 빌드는 3단계로 이루어져있다.

Gradle은 빌드를 실행하기 전 모든 태스크를 한꺼번에 만드는 것이 아니라 아래 세 단계를 거쳐 필요한 태스크만 실제로 생성하고 실행한다.

1. 초기화 (Initialization) :

어떤 프로젝트를 빌드할지 결정하고 각 프로젝트에 대한 Project 객체를 생성하는 단계이다. 프로젝트 정보는 setting.gradle 파일에서 구성한다.

2. 구성 (Configuration) :

각 프로젝트의 build.gradle 파일을 읽어 태스크(Task)를 생성하고 태스크 간의 의존 관계를 구성하는 단계이다.
plugins {} 블록이 실행되고 플러그인이 자동으로 여러 태스크를 등록하는 시점도 바로 이 단계다.

즉, 구성 단계는 필요한 모든 의존성을 가져오고 작업을 준비하는 단계이다.

3. 실행 (Execution) :

앞선 단계에서 준비된 태스크들이 실제로 수행되는 시점이다.
예를 들어 컴파일(compile), 테스트(test), 패키징(package) 등의 작업이 이 단계에서 실행된다.

주의!
소스코드 실행(run)은 빌드 단계에 포함되지 않는다는 것이다. 빌드는 애플리케이션이 실행되기 직전까지의 과정이며 코드를 실제로 수행(run)하는 것은 별도의 단계이다.

즉,

  • 빌드(build) 는 코드를 검증하고 준비하는 과정
  • 실행(run) 은 검증된 코드를 실제로 동작시키는 과정

그렇다면 의문이 생긴다.

“테스트 코드도 결국 코드인데, 왜 빌드 단계에 포함될까?”

그 이유는 빌드의 본질이 “코드가 수행되기 전 잠재적인 오류를 검증하는 과정”이기 때문이다. 테스트는 실제 애플리케이션 실행 전에 코드의 정확성과 안정성을 확인하는 절차이다. 따라서 빌드 과정의 일부로 포함된다.

구성 단계에서 말하는 태스크(Task)란?

Gradle의 빌드는 여러 개의 작업 단위(Task) 로 구성된다.
각 Task는 “무엇을, 언제, 어떻게” 실행할지를 정의한 하나의 객체이다.
예를 들어 아래와 같은 명령을 수행한다.

  • compileJava : Java 코드를 컴파일
  • test : JUnit 테스트 실행
  • bootJar : Spring Boot 실행 JAR 생성

정리: Task = “Gradle이 수행해야 할 구체적인 작업 단위

Gradle은 플러그인 기반 시스템

이런 태스크들은 대부분 우리가 직접 만드는 것이 아니라 plugins {} 블록에 등록된 플러그인들이 자동으로 생성한다.
예를 들어 현재 프로젝트의 build.gradle에서는 다음과 같은 플러그인을 사용하고 있다.

  • javacompileJava, processResources, classes, test, jar 등의 태스크 생성

  • org.springframework.bootbootJar, bootRun, bootBuildImage 등의 태스크 생성

이처럼 build.gradle 파일에 태스크 코드가 직접 보이지 않더라도 Gradle은 플러그인을 읽는 Configuration 단계에서 이 태스크들을 자동으로 등록한다.

Gradle에서의 test {} VS tasks.named('test') {}

이번 오픈 미션을 진행하면서 겪었던 오류이자, 이 글을 작성하게 된 직접적인 계기이기도 하다.
문제 해결 과정에서 Gradle의 동작 원리를 깊이 있게 이해할 수 있었고 지금은 이 경험이 꽤 값진 학습이었다고 생각한다. 😊

암튼 이 두 코드의 차이와 오류가 난 이유를 설명하고 글을 마치겠다.

Gradle이 처음에는 다음과 같이 작성되어있었다.

tasks.named('test') {
	useJUnitPlatform()
}

하지만 테스트 코드를 작성하고 실행할 때마다 계속해서 “No tests were found” 라는 메시지가 출력되었다.
여러 블로그를 찾아보며 원인을 분석한 결과 Gradle의 테스트 태스크 설정 시점에 문제가 있었던 것이다.

그래서 다음과 같이 코드를 수정했다.

test {
	useJUnitPlatform()
}

이후에는 테스트가 정상적으로 동작했다.


Gradle에서 테스트 설정을 하는 방법에는 두 가지가 있다.
둘 다 test 태스크를 구성하지만 적용 시점과 동작 방식이 다르다.

test {}

  • 이미 생성된 test 태스크를 즉시 설정한다.
  • 설정이 바로 적용되어 직관적이지만 유연성이 낮다.

tasks.named('test') {}

  • 나중에 생성될 test 태스크에 설정을 예약한다.
  • ‘지연 구성(lazy configuration)’ 방식이라 유연하지만 플러그인 로딩 시점이 꼬이면 설정이 반영되지 않을 수 있다.

예를 들어 Spring BootJava 플러그인의 등록 시점이 늦어지면 tasks.named('test') {}로 예약한 설정이 제때 적용되지 않아 useJUnitPlatform()이 누락되고 결과적으로 “No tests were found” 오류가 발생할 수 있다.

마무리

이번 경험을 통해 단순히 오류를 해결하는 데 그치지 않고 Gradle의 태스크 생성·구성 시점과 지연 구성 개념을 명확히 이해할 수 있었다.
앞으로는 단순히 “작동하게 만드는” 데서 멈추지 않고, 왜 그렇게 작동하는지를 이해하며 성장하고 싶다.

참고자료

[학습정리] Gradle 알고 쓰자!
tasks.named('test') { 와 그냥 test{}

profile
BE 개발자

0개의 댓글