Unity 카탈로그의 Scala 및 Java UDF(사용자 정의 함수)

이 페이지에서는 Scala를 만들고 UDF(사용자 정의 함수)를 Java Unity 카탈로그에 등록하고 컴퓨팅 환경에서 공유하는 방법을 설명합니다. Unity 카탈로그 UDF를 사용하면 Unity 카탈로그 거버넌스 및 액세스 제어를 사용하여 기존 JVM 논리를 다시 사용할 수 있습니다.

단일 Notebook 또는 클러스터로 제한되는 세션 범위 Scala UDF 와 달리 Unity 카탈로그에 등록된 UDF는 다음과 같습니다.

  • 관리: Unity 카탈로그 권한 및 액세스 제어를 사용하여 관리됩니다.
  • 재사용 가능: 팀, Notebook, 작업 및 SQL 웨어하우스 간에 공유됩니다.
  • 검색 가능: 카탈로그 탐색기 및 시스템 테이블에 표시됩니다.
  • 격리됨: 샌드박스에서 실행되며, 세션마다 콜드 스타트 비용이 한 번 발생합니다. 후속 호출은 빠릅니다.

Requirements

Unity 카탈로그를 사용하려면 작업 공간이 사용 가능하도록 설정되어 있어야 합니다. 다음과 같은 추가 요구 사항이 적용됩니다.

컴퓨팅: 서버리스 Notebook 및 작업, SQL 웨어하우스Lakeflow의 Spark 선언적 파이프라인을 비롯한 모든 컴퓨팅 유형이 지원됩니다. 클래식 컴퓨팅에는 Databricks Runtime 18.2 이상이 필요합니다. 서버리스 컴퓨팅 및 SQL 웨어하우스에서 UDF 정의는 필드에서 환경 버전 4 이상을 environment_version 지정해야 합니다. 이 요구 사항은 호출 Notebook 또는 작업이 아닌 UDF 정의에 적용됩니다. 서버리스 환경 버전참조하세요.

개발:

  • Scala: 2.13.16. Scala 2.12는 지원되지 않습니다.
  • JDK: 17.
  • 패키징: UDF에서 사용하는 모든 타사 종속성을 포함하는 fat JAR입니다.

권한:

  • UDF 생성: 스키마에서 USAGECREATE FUNCTION, 카탈로그에서 USAGE.
  • 함수에서 EXECUTE를, 스키마와 카탈로그에서 USAGE를 클릭하여 UDF를 실행합니다.
  • JAR이 저장된 볼륨에서 JAR 파일에 READ VOLUME 액세스합니다.

Unity 카탈로그 권한에 대한 자세한 내용은 Unity 카탈로그의 권한 관리를 참조하세요.

UDF JAR 빌드하기

컴파일된 코드를 JAR로 패키지하고 UDF를 등록하기 전에 Unity 카탈로그 볼륨에 업로드합니다. 빌드 방법을 선택합니다.

로컬로 빌드

로컬 개발 환경을 사용하여 fat JAR을 빌드하려면 다음 단계를 수행합니다.

환경 설정

로컬 컴퓨터에 필요한 도구를 설치합니다. 다음 명령은 macOS용입니다. 다른 플랫폼의 경우 플랫폼의 패키지 관리자를 사용하여 JDK 17 및 sbt(Scala) 또는 Maven(Java)을 설치합니다.

Scala

JDK 17 및 sbt를 설치합니다.

brew install openjdk@17
brew install sbt

설치를 확인합니다.

java -version   # Should show Java 17
sbt --version   # Should show sbt version

Java

JDK 17 및 Maven을 설치합니다.

brew install openjdk@17
brew install maven

설치를 확인합니다.

java -version   # Should show Java 17
mvn --version   # Should show Maven version

프로젝트 만들기

Scala 또는 Java 프로젝트를 설정합니다.

Scala

다음을 사용하여 sbt새 Scala 프로젝트를 만듭니다.

sbt new scala/scala-seed.g8

메시지가 표시되면 프로젝트 이름(예: my-udf-project)을 입력합니다.

build.sbt 구성하기

파일의 build.sbt 내용을 다음 구성으로 바꿉니다.

scalaVersion := "2.13.16"

ThisBuild / organization := "com.example"

lazy val myUDF = (project in file("."))
  .settings(
    name := "my-udf"
  )

sbt-assembly 플러그 인 사용

project/assembly.sbt을(를) 생성 또는 편집하고 다음을 추가:

addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "2.0.0")

이 플러그 인은 모든 종속성을 포함하는 fat JAR을 만듭니다.

Java

빠른 시작 원형을 사용하여 새 Maven 프로젝트를 만듭니다.

mvn archetype:generate \
  -DgroupId=com.example \
  -DartifactId=my-udf \
  -DarchetypeArtifactId=maven-archetype-quickstart \
  -DinteractiveMode=false

이 명령은 src/main/javasrc/test/java 디렉터리가 있는 표준 Maven 프로젝트 구조를 만듭니다.

pom.xml 설정

생성된 pom.xml 파일의 <project></project> 태그 내에 다음 구성으로 <properties> 블록을 추가합니다.

<properties>
  <maven.compiler.source>17</maven.compiler.source>
  <maven.compiler.target>17</maven.compiler.target>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

또한 <project></project> 태그 내에 다음 구성으로 <build> 블록을 추가합니다.

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>3.5.0</version>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

maven-shade-plugin는 모든 종속성을 포함하는 fat JAR을 생성합니다.

UDF를 작성하세요

UDF를 작성할 때 지원되는 데이터 형식언어 매핑에 대한 데이터 형식을 참조하여 Scala 및 Java 형식이 SQL 형식에 매핑되는 방식을 확인합니다.

UDF 처리기는 다음 요구 사항을 충족해야 합니다.

  • Scala: 처리기를 object의 메서드로 정의합니다(class가 아니라). HANDLER 값은 Scala object의 메서드로 해석됩니다.
  • Java: 처리기를 메서드로 public static 정의합니다.
  • 서명: 메서드의 매개 변수 형식, 순서 및 반환 형식은 문에 있는 인수 목록 및 형식에 RETURNSCREATE FUNCTION 해당해야 합니다.
  • 스칼라 전용: 처리기는 단일 스칼라 값을 반환해야 합니다. 테이블 반환 형식은 지원되지 않습니다.
  • 자체 완결형: 처리기는 입력 인수만을 사용해 동작해야 합니다. Spark API를 사용하거나 Spark 코어 패키지에 의존할 수 없습니다. 제한 사항을 참조하세요.

메모

Scala의 경우 기본 매개 변수 형식(예: Int)이 있는 처리기는 건너뛰고 입력 인수가 SQLNULL이면 반환 NULL 됩니다. NULL 값을 수신하고 처리하려면 매개변수를 Option로 감싸세요. 예: Option[Int]

Scala

Scala 개체 src/main/scala/com/example/MyUDF.scala 를 만들고 UDF 함수를 정의합니다.

기본 예제

package com.example

object MyUDF {
  def addOne(x: Int): Int = x + 1
}

외부 종속성이 있는 예제

외부 라이브러리를 사용하려면 build.sbt 파일에 추가하세요.

scalaVersion := "2.13.16"

ThisBuild / organization := "com.example"

lazy val myUDF = (project in file("."))
  .settings(
    name := "currency-udf",
    libraryDependencies ++= Seq(
      "org.apache.commons" % "commons-lang3" % "3.12.0"
    )
  )

그런 다음 UDF에서 종속성을 사용합니다.

package com.example

import org.apache.commons.lang3.StringUtils

object CurrencyUDF {
  private val rates: Map[String, Double] = Map(
    "USD" -> 1.0,
    "EUR" -> 1.1,
    "GBP" -> 1.3,
    "JPY" -> 0.007
  )

  def convertToUSD(price: Double, currency: String): Double = {
    require(currency != null, "Currency must not be null")

    val normalizedCurrency = StringUtils.upperCase(currency)

    rates.get(normalizedCurrency) match {
      case Some(rate) => price * rate
      case None => throw new IllegalArgumentException(s"Unsupported currency: $currency")
    }
  }
}

배포하기 전에 단위 테스트를 사용하여 UDF를 테스트합니다. UDF 로컬 테스트를 참조하세요.

Java

Java 클래스를 src/main/java/com/example/MyUDF.java 만들고 UDF를 공용 정적 메서드로 정의합니다.

기본 예제

package com.example;

public class MyUDF {
    public static int addOne(int x) {
        return x + 1;
    }
}

외부 종속성이 있는 예제

외부 라이브러리를 사용하려면 pom.xml 파일의 <dependencies> 섹션에 추가하세요:

<dependencies>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
        <version>3.12.0</version>
    </dependency>
</dependencies>

그런 다음 UDF에서 종속성을 사용합니다.

package com.example;

import org.apache.commons.lang3.StringUtils;
import java.util.Map;
import java.util.HashMap;

public class CurrencyUDF {
    private static final Map<String, Double> rates = new HashMap<>();

    static {
        rates.put("USD", 1.0);
        rates.put("EUR", 1.1);
        rates.put("GBP", 1.3);
        rates.put("JPY", 0.007);
    }

    public static double convertToUSD(double price, String currency) {
        if (currency == null) {
            throw new IllegalArgumentException("Currency must not be null");
        }

        String normalizedCurrency = StringUtils.upperCase(currency);

        if (!rates.containsKey(normalizedCurrency)) {
            throw new IllegalArgumentException("Unsupported currency: " + currency);
        }

        return price * rates.get(normalizedCurrency);
    }
}

배포하기 전에 단위 테스트를 사용하여 UDF를 테스트합니다. UDF 로컬 테스트를 참조하세요.

메모

UDF는 활성 Spark 세션이 없는 격리된 샌드박스에서 실행되므로 함수 본문 내에서 Spark API를 사용할 수 없습니다. 예를 들어 DataFrames 또는 데이터 세트를 생성하거나 조작할 수 없고, spark.sql(...)를 실행하거나, SparkSession 또는 SparkContext에 액세스할 수 없습니다. UDF는 입력 인수에 대한 자체 포함 논리여야 합니다. 또한 Spark 코어 패키지에 의존할 수 없습니다.

fat JAR 빌드하기

프로젝트를 빌드하여 모든 종속성을 포함하는 fat JAR을 만듭니다.

Scala

프로젝트 루트 디렉터리에서 다음을 실행합니다.

sbt clean assembly

fat JAR은 target/scala-2.13/my-udf-assembly-0.1.0-SNAPSHOT.jar와 같은 이름으로 생성됩니다.

Java

프로젝트 루트 디렉터리에서 다음을 실행합니다.

mvn clean package

fat JAR은 target/에서 my-udf-1.0-SNAPSHOT.jar와 같은 이름으로 생성됩니다.

Unity 카탈로그 볼륨에 JAR 업로드

아직 Unity Catalog 볼륨이 없다면 하나를 생성하세요:

CREATE VOLUME IF NOT EXISTS my_catalog.my_schema.udf_jars
COMMENT 'Storage for UDF JAR files';

다른 사용자가 UDF를 실행해야 하는 경우 해당 사용자에게 볼륨에 대한 READ VOLUME 권한을 부여합니다.

GRANT READ VOLUME ON VOLUME my_catalog.my_schema.udf_jars TO `user@example.com`;

카탈로그 탐색기를 사용하여 볼륨에 JAR 파일을 업로드합니다.

  1. Azure Databricks 작업 영역에서 데이터 아이콘을 클릭한 후 카탈로그를 선택하여 카탈로그 탐색기를 엽니다.
  2. 카탈로그를 선택한 다음 볼륨이 포함된 스키마를 선택합니다.
  3. 볼륨 이름을 클릭합니다.
  4. 이 볼륨에 업로드를 클릭하고 JAR 파일을 선택합니다.
  5. 업로드를 클릭합니다.
  6. 업로드가 완료되면 JAR 파일의 이름을 클릭합니다.
  7. 복사 경로를 클릭하여 볼륨 경로를 클립보드에 복사합니다. 예를 들어 /Volumes/my_catalog/my_schema/udf_jars/my-udf-assembly-0.1.0-SNAPSHOT.jar (Scala) 또는 /Volumes/my_catalog/my_schema/udf_jars/my-udf-1.0-SNAPSHOT.jar (Java)입니다. UDF를 등록할 때 이 경로가 필요합니다.

노트북에서 빌드

UDF를 컴파일하고 JAR로 패키지한 다음 Azure Databricks Notebook에서 직접 Unity 카탈로그 볼륨에 업로드할 수 있습니다. 이 방법은 종속성이 없는 작은 UDF에 대해 작동합니다. 타사 라이브러리가 있는 UDF의 경우 빌드를 로컬로 사용합니다.

다음 Python 셀은 문자열을 정리하고(공백을 잘라내고, 반복되는 공백과 소문자를 축소하고, JDK 17로 컴파일하고, JAR로 패키징하고, Unity 카탈로그 볼륨에 복사하는 Java UDF를 작성합니다. volume_path 사용 권한이 있는 기존 볼륨 WRITE VOLUME 을 가리키도록 업데이트합니다.

import os
import subprocess
import shutil

build_dir = "/tmp/udf_build"
package_dir = f"{build_dir}/src/com/databricks/udf"
classes_dir = f"{build_dir}/classes"
os.makedirs(package_dir, exist_ok=True)
os.makedirs(classes_dir, exist_ok=True)

# The UDF handler: a public static method on a plain Java class.
# The doubled backslashes produce a single backslash in the Java source (\\s+).
udf_code = """package com.databricks.udf;
public class StringCleanUDF {
    public static String clean(String input) {
        if (input == null) return null;
        return input.trim().replaceAll("\\\\s+", " ").toLowerCase();
    }
}
"""
with open(f"{package_dir}/StringCleanUDF.java", "w") as f:
    f.write(udf_code)

# Compile with JDK 17 to match Environment Version 4.
subprocess.run(
    ["javac", "--release", "17", "-d", classes_dir, f"{package_dir}/StringCleanUDF.java"],
    check=True,
)

# Package the compiled class into a JAR.
jar_path = f"{build_dir}/string_clean_udf.jar"
subprocess.run(["jar", "cf", jar_path, "-C", classes_dir, "."], check=True)

# Copy the JAR to a Unity Catalog volume.
volume_path = "/Volumes/my_catalog/my_schema/udf_jars/string_clean_udf.jar"
os.makedirs(os.path.dirname(volume_path), exist_ok=True)
shutil.copy2(jar_path, volume_path)

print(f"JAR uploaded to: {volume_path}")

JAR이 볼륨에 있으면 UDF를 등록합니다. LANGUAGE JAVA를 사용하고 HANDLERcom.databricks.udf.StringCleanUDF.clean와 같은 전체 경로가 포함된 메서드로 설정합니다.

Unity 카탈로그에 UDF 등록

JAR을 빌드하고 업로드한 후 CREATE FUNCTION 문을 사용하여 Unity Catalog에 UDF를 등록합니다.

Scala

CREATE OR REPLACE FUNCTION my_catalog.my_schema.add_one(x INT)
RETURNS INT
LANGUAGE SCALA
DETERMINISTIC
ENVIRONMENT (
  java_dependencies = '["/Volumes/my_catalog/my_schema/udf_jars/my-udf-assembly-0.1.0-SNAPSHOT.jar"]',
  environment_version = '4'
)
HANDLER 'com.example.MyUDF.addOne';

Java

CREATE OR REPLACE FUNCTION my_catalog.my_schema.add_one(x INT)
RETURNS INT
LANGUAGE JAVA
DETERMINISTIC
ENVIRONMENT (
  java_dependencies = '["/Volumes/my_catalog/my_schema/udf_jars/my-udf-1.0-SNAPSHOT.jar"]',
  environment_version = '4'
)
HANDLER 'com.example.MyUDF.addOne';

이 문은 CREATE FUNCTION 다음 매개 변수를 사용합니다.

  • LANGUAGE: UDF의 언어입니다.

  • HANDLER: 형식 'package.Object.method' (Scala) 또는 'package.ClassName.method' (Java)으로 메서드에 대한 정규화된 경로입니다.

  • DETERMINISTIC: 함수가 항상 동일한 입력에 대해 동일한 출력을 반환하여 쿼리 최적화를 사용하도록 선언합니다.

    메모

    함수가 외부 API를 호출하거나 다른 비결정적 동작이 있는 경우 제거 DETERMINISTIC 합니다.

  • ENVIRONMENT: UDF의 실행 환경을 정의합니다.

    • java_dependencies: Unity 카탈로그 볼륨에 있는 JAR 파일 경로의 JSON 배열입니다. 이전 단계에서 복사한 파일 경로입니다. 배열 주위에 작은따옴표와 경로 주위에 큰따옴표를 사용합니다.
    • environment_version: Scala 및 Java UDF의 경우 '4' 이상이어야 합니다. 환경 버전 4는 Scala 2.13.16 및 JDK 17을 지정합니다. 서버리스 환경 버전참조하세요.

SQL 및 Notebook에서 UDF 호출

등록 후 SQL 쿼리, Notebook 및 뷰에서 UDF를 호출할 수 있습니다.

-- Simple select
SELECT my_catalog.my_schema.add_one(5) AS result;

-- With table data
SELECT
  id,
  price,
  currency,
  my_catalog.my_schema.convert_to_usd(price, currency) AS price_usd
FROM my_catalog.my_schema.transactions;

-- Filtering
SELECT *
FROM my_catalog.my_schema.products
WHERE my_catalog.my_schema.convert_to_usd(price, currency) > 100;

-- Aggregation
SELECT
  category,
  SUM(my_catalog.my_schema.convert_to_usd(price, currency)) AS total_usd
FROM my_catalog.my_schema.sales
GROUP BY category;

거버넌스 및 공유

Unity 카탈로그 권한을 사용하여 UDF를 실행할 수 있는 사용자를 제어하고 조직 전체에서 검색할 수 있도록 합니다.

권한 부여

카탈로그 탐색기 또는 SQL을 사용하여 다른 사용자가 UDF를 실행하는 데 필요한 권한을 부여합니다.

카탈로그 탐색기

  1. 사이드바에서 데이터 아이콘을 클릭합니다.카탈로그.
  2. 카탈로그를 선택한 다음 함수가 포함된 스키마를 선택합니다.
  3. 함수 이름을 클릭합니다.
  4. 사용 권한 탭에서 권한 부여를 클릭합니다.
  5. 액세스 권한을 부여할 보안 주체를 선택한 다음, EXECUTE 권한을 선택합니다.
  6. 확인을 클릭합니다.

SQL

Notebook 또는 Databricks SQL 편집기에서 다음 명령을 실행하여 사용자 또는 그룹에 권한을 부여 EXECUTE 합니다.

-- Grant to a specific user
GRANT EXECUTE ON FUNCTION my_catalog.my_schema.add_one TO `user@example.com`;

-- Grant to a group
GRANT EXECUTE ON FUNCTION my_catalog.my_schema.add_one TO `data-engineers`;

사용 권한 취소

카탈로그 탐색기 또는 SQL을 사용하여 다른 사용자의 사용 권한을 취소합니다.

카탈로그 탐색기

  1. 사이드바에서 데이터 아이콘을 클릭합니다.카탈로그.
  2. 카탈로그를 선택한 다음 함수가 포함된 스키마를 선택합니다.
  3. 함수 이름을 클릭합니다.
  4. 사용 권한 탭에서 액세스 권한을 취소하려는 보안 주체 옆의 확인란을 선택합니다. 취소를 클릭합니다.
  5. 알림에서 취소를 클릭합니다.

SQL

노트북 또는 Databricks SQL 편집기에서 다음 명령을 실행하여 사용자 또는 그룹으로부터 EXECUTE 권한을 취소합니다.

-- Revoke from specific user
REVOKE EXECUTE ON FUNCTION my_catalog.my_schema.add_one FROM `user@example.com`;

-- Revoke from a group
REVOKE EXECUTE ON FUNCTION my_catalog.my_schema.add_one FROM `data-engineers`;

UDF 검색

Unity Catalog에서 관리되는 UDF를 찾으려면 information_schema.routines 테이블을 쿼리하고 my_catalogmy_schema 값을 바꾸세요:

SELECT
  routine_catalog,
  routine_schema,
  routine_name,
  routine_definition,
  created
FROM system.information_schema.routines
WHERE routine_catalog = 'my_catalog'
  AND routine_schema = 'my_schema';

UDF 업데이트

기존 Unity 카탈로그 UDF를 새 코드로 업데이트하려면 다음을 수행합니다.

  1. 코드를 로컬로 변경합니다.
  2. 새 버전 번호로 JAR을 다시 빌드합니다.
    • Scala: sbt clean assembly(예를 들어, my-udf-assembly-0.2.0-SNAPSHOT.jar)
    • Java: (예: mvn clean packagemy-udf-2.0-SNAPSHOT.jar)
  3. Unity 카탈로그 볼륨에 새 JAR을 업로드합니다.
  4. CREATE OR REPLACE FUNCTION 동일한 함수 이름으로 UDF를 업데이트합니다. java_dependencies에서 최신 JAR을 참조하는지 확인하세요.

Azure Databricks 다음 호출에서 새 코드를 사용합니다. 클러스터를 다시 시작할 필요가 없습니다.

성능 최적화

콜드 스타트 지연 시간

세션의 첫 번째 UDF 호출은 격리된 샌드박스를 초기화하여 대기 시간을 추가합니다. 동일한 세션의 후속 호출은 더 빠릅니다. 대기 시간에 민감한 워크로드를 벤치마킹하거나 디자인할 때 이를 고려합니다.

비용이 큰 연산 캐싱

UDF가 비용이 많이 드는 초기화 또는 계산을 수행하는 경우 결과를 캐시하여 한 번만 계산합니다.

Scala

val Scala 개체의 필드를 사용하여 결과를 캐시합니다.

package example

object CachedUDF {
  // Computed once and cached
  val expensiveData: Map[String, Double] = {
    // Load data from somewhere expensive
    Map("key1" -> 1.0, "key2" -> 2.0)
  }

  def lookup(key: String): Double = {
    expensiveData.getOrElse(key, 0.0)
  }
}

Java

결과를 캐시하려면 정적 초기화 블록이 있는 static 필드를 사용합니다.

package example;

import java.util.Map;
import java.util.HashMap;

public class CachedUDF {
    // Computed once and cached
    private static Map<String, Double> expensiveData;

    static {
        // Load data from somewhere expensive
        expensiveData = new HashMap<>();
        expensiveData.put("key1", 1.0);
        expensiveData.put("key2", 2.0);
    }

    public static double lookup(String key) {
        return expensiveData.getOrDefault(key, 0.0);
    }
}

적절한 경우 DETERMINISTIC 사용

UDF가 동일한 입력에 대해 항상 동일한 출력을 생성한다면 DETERMINISTIC로 표시하세요. 이렇게 하면 쿼리 최적화 프로그램에서 결과를 캐시하고 성능을 향상시킬 수 있습니다.

Limitations

  • 스칼라 UDF만 지원됩니다. UDF(사용자 정의 집계 함수) 및 UDF(사용자 정의 테이블 함수)는 지원되지 않습니다.
  • UDF는 활성 Spark 세션이 없는 격리된 샌드박스에서 실행됩니다. Spark API(SparkSession, SparkContext, spark.sql(...), DataFrame 및 데이터 세트 작업)를 사용할 수 없습니다.
  • UDF는 Spark 코어 패키지에 의존할 수 없습니다.
  • UDF는 런타임에 작업 영역 파일 또는 Unity 카탈로그 볼륨에 액세스할 수 없습니다.

모범 사례

Databricks는 다음 방법을 권장합니다.

  • JAR 파일의 버전을 지정합니다. 예: my-udf-0.1.0.jar, my-udf-0.2.0.jar
  • 배포 전에 SQL 형식 매핑의 유효성을 검사합니다. 언어 매핑을 참조하세요.
  • UDF를 실행해야 하는 사용자에게만 READ VOLUMEEXECUTE 권한을 부여합니다. 팀 간에 공유되는 UDF에 그룹 소유권을 사용합니다.

UDF를 로컬로 테스트

프로덕션에 배포하기 전에 단위 테스트를 사용하여 UDF를 테스트합니다.

Scala

src/main/scala/example/MyUDF.scala을 테스트하려면 src/test/scala/example/MyUDFTest.scala에 테스트 파일을 만듭니다:

package example

import org.scalatest.funsuite.AnyFunSuite

class MyUDFTest extends AnyFunSuite {
  test("addOne should add 1 to input") {
    assert(MyUDF.addOne(5) == 6)
  }

  test("addOne should handle negative numbers") {
    assert(MyUDF.addOne(-1) == 0)
  }
}

테스트 종속성을 다음에 추가합니다 build.sbt.

libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.15" % Test

테스트를 실행하려면 다음을 수행합니다.

sbt test

Java

src/main/java/com/example/MyUDF.java을 테스트하려면 src/test/java/com/example/MyUDFTest.java에 테스트 파일을 생성합니다:

package com.example;

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class MyUDFTest {
    @Test
    public void testAddOne() {
        assertEquals(6, MyUDF.addOne(5));
    }

    @Test
    public void testAddOneWithNegativeNumbers() {
        assertEquals(0, MyUDF.addOne(-1));
    }
}

pom.xml<dependencies> 섹션에 JUnit 종속성을 추가합니다:

<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter</artifactId>
    <version>5.10.0</version>
    <scope>test</scope>
</dependency>

테스트를 실행하려면 다음을 수행합니다.

mvn test

추가 리소스