데이터 품질 테스트

이 문서에서는 Dataform 테이블 어설션 및 단위 테스트를 사용하여 워크플로 코드를 테스트하는 방법을 보여줍니다.

시작하기 전에

  1. Google Cloud 콘솔에서 Dataform 페이지로 이동합니다.

    Dataform 페이지로 이동

  2. 저장소를 선택하거나 만듭니다.

  3. 개발 작업공간을 선택하거나 만듭니다.

  4. 테이블을 만듭니다.

필요한 역할

어설션과 단위 테스트를 만드는 데 필요한 권한을 얻으려면 관리자에게 다음 IAM 역할을 부여해 달라고 요청하세요.

역할 부여에 대한 자세한 내용은 프로젝트, 폴더, 조직에 대한 액세스 관리를 참조하세요.

커스텀 역할이나 다른 사전 정의된 역할을 통해 필요한 권한을 얻을 수도 있습니다.

어설션으로 데이터 테스트

어설션은 쿼리에 지정된 조건을 하나 이상 위반하는 행을 찾는 데이터 품질 테스트 쿼리입니다. 쿼리가 행을 반환하면 어설션이 실패합니다. Dataform은 워크플로를 업데이트할 때마다 어설션을 실행하고 어설션이 실패할 경우 알림을 제공합니다.

Dataform은 컴파일된 어설션 쿼리의 결과가 포함된 뷰를 BigQuery에 자동으로 만듭니다. 워크플로 설정 파일에 구성된 대로 Dataform은 어설션 스키마에 어설션 결과를 검사할 수 있는 뷰를 만듭니다.

예를 들어 기본 dataform_assertions 스키마의 경우 Dataform은 BigQuery에서 dataform_assertions.assertion_name 형식으로 뷰를 만듭니다.

테이블, 증분 테이블, 뷰, 구체화된 뷰 등 모든 Dataform 테이블 유형에 어설션을 만들 수 있습니다.

다음과 같은 방법으로 어설션을 만들 수 있습니다.

기본 제공 어설션 만들기

테이블의 config 블록에 내장 Dataform 어설션을 추가할 수 있습니다. 테이블 생성 후 Dataform에서 이러한 어설션을 실행합니다. Dataform에서 테이블을 만든 후 작업공간의 워크플로 실행 로그 탭에서 어설션이 통과되었는지 확인할 수 있습니다.

표의 config 블록에서 다음 어설션을 만들 수 있습니다.

  • nonNull

    이 조건은 지정된 열이 모든 테이블 행에서 null이 아니라는 어설션을 만듭니다. 이 조건은 null이 될 수 없는 열에 사용됩니다.

    다음 코드 샘플은 테이블의 config 블록에 있는 nonNull 어설션을 보여줍니다.

config {
  type: "table",
  assertions: {
    nonNull: ["user_id", "customer_id", "email"]
  }
}
SELECT ...
  • rowConditions

    이 조건은 모든 테이블 행이 정의한 커스텀 로직을 따른다는 어설션을 만듭니다. 각 행 조건은 커스텀 SQL 표현식이며 각 테이블 행은 각 행 조건을 기준으로 평가됩니다. 테이블 행이 false를 생성하면 어설션이 실패합니다.

    다음 코드 샘플은 증분 테이블의 config 블록에 있는 맞춤 rowConditions 어설션을 보여줍니다.

config {
  type: "incremental",
  assertions: {
    rowConditions: [
      'signup_date is null or signup_date > "2022-08-01"',
      'email like "%@%.%"'
    ]
  }
}
SELECT ...
  • uniqueKey

    이 조건은 지정된 열에서 동일한 값을 가진 테이블 행이 없다는 어설션을 만듭니다.

    다음 코드 샘플은 뷰의 config 블록에 있는 uniqueKey 어설션을 보여줍니다.

config {
  type: "view",
  assertions: {
    uniqueKey: ["user_id"]
  }
}
SELECT ...
  • uniqueKeys

    이 조건은 지정된 열에서 동일한 값을 가진 테이블 행이 없다는 어설션을 만듭니다. 지정된 모든 열에 대해 동일한 값을 갖는 행이 테이블에 둘 이상 있는 경우 어설션이 실패합니다.

    다음 코드 샘플은 테이블의 config 블록에 있는 uniqueKeys 어설션을 보여줍니다.

config {
  type: "table",
  assertions: {
    uniqueKeys: [["user_id"], ["signup_date", "customer_id"]]
  }
}
SELECT ...

config 블록에 어설션 추가

테이블의 구성 블록에 어설션을 추가하려면 다음 단계를 따르세요.

  1. 개발 작업공간의 파일 창에서 테이블 정의 SQLX 파일을 선택합니다.
  2. 표 파일의 config 블록에 assertions: {}을 입력합니다.
  3. assertions: {} 안에 어설션을 추가합니다.
  4. (선택사항): 형식을 클릭합니다.

다음 코드 샘플은 config 블록에 추가된 조건을 보여줍니다.

config {
  type: "table",
  assertions: {
    uniqueKey: ["user_id"],
    nonNull: ["user_id", "customer_id"],
    rowConditions: [
      'signup_date is null or signup_date > "2019-01-01"',
      'email like "%@%.%"'
    ]
  }
}
SELECT ...

SQLX로 수동 어설션 만들기

수동 어설션은 전용 SQLX 파일에 작성하는 SQL 쿼리입니다. 수동 어설션 SQL 쿼리는 0개의 행을 반환해야 합니다. 쿼리가 실행될 때 행을 반환하면 어설션이 실패합니다.

새 SQLX 파일에 수동 어설션을 추가하려면 다음 단계를 따르세요.

  1. 파일 창에서 definitions/ 옆에 있는 더보기 메뉴를 클릭합니다.
  2. 파일 만들기를 클릭합니다.
  3. 파일 경로 추가 필드에 파일 이름을 입력하고 파일 이름 다음에 .sqlx를 입력합니다. 예를 들면 definitions/custom_assertion.sqlx입니다.

    파일 이름에는 숫자, 문자, 하이픈, 밑줄만 포함할 수 있습니다.

  4. 파일 만들기를 클릭합니다.

  5. 파일 창에서 새 파일을 클릭합니다.

  6. 파일에 다음을 입력합니다.

    config {
      type: "assertion"
    }
    
  7. config 블록 아래에 SQL 쿼리 또는 여러 쿼리를 작성합니다.

  8. (선택사항): 형식을 클릭합니다.

다음 코드 샘플은 A, B 필드를 어설션하고 csometable에서 NULL이 아닌 SQLX 파일의 수동 어설션을 보여줍니다.

config { type: "assertion" }

SELECT
  *
FROM
  ${ref("sometable")}
WHERE
  a IS NULL
  OR b IS NULL
  OR c IS NULL

단위 테스트로 데이터 품질 테스트

단위 테스트는 테스트된 워크플로 작업의 모든 종속 항목을 모의하고 예상 결과를 제공하는 전용 .sqlx 파일에 정의된 데이터 품질 테스트입니다. 단위 테스트를 사용하여 제어된 모의 입력에 대해 Dataform 작업을 테스트하여 작업 코드가 특이 사례, null 값, 집계, 정규식, 조건부 로직을 올바르게 처리하는지 확인할 수 있습니다.

${ref()} 함수에서 참조되는 선행 테이블, 뷰 또는 원시 선언과 같은 작업 종속 항목의 모의는 input 블록에 정의됩니다. 각 input 블록은 이름으로 종속 항목을 참조하고 모의 행을 정의하는 SQL 쿼리를 포함합니다. 이 쿼리는 일반적으로 UNION ALL와 결합된 일련의 SELECT 문입니다. 예상 결과는 워크플로 작업 SQL 문에 지정된 입력을 실행한 결과를 나타내는 SQL 쿼리입니다.

Dataform은 단위 테스트를 행별로 실행하고 워크플로 작업의 SQL 로직을 모의 데이터에 대해 실행한 실제 결과를 예상 결과 집합과 비교합니다.

단위 테스트는 다음 상태로 확인됩니다.

  • SUCCESS: 테스트를 통과했습니다. 실제 결과가 예상 결과와 일치합니다.
  • FAILURE: 테스트가 실패했습니다. 실제 결과가 예상 결과와 일치하지 않습니다.

제한사항

Dataform 단위 테스트에는 다음과 같은 제한사항이 적용됩니다.

  • 단위 테스트는 Dataform 코어 버전 3.0.56 이상에서 사용할 수 있습니다.
  • 단위 테스트의 입력 데이터 최대 크기는 입력당 100개 행입니다.

단위 테스트 만들기

단위 테스트용 .sqlx 파일을 definitions/ 디렉터리에 저장합니다. definitions/ 디렉터리에 새 단위 테스트 .sqlx 파일을 만들려면 다음 단계를 따르세요.

  1. Google Cloud 콘솔에서 Dataform 페이지로 이동합니다.

    Dataform 페이지로 이동

  2. 저장소를 선택합니다.

  3. 개발 작업공간을 선택합니다.

  4. 파일 창에서 definitions/ 옆에 있는 더보기 메뉴를 클릭합니다.

  5. 파일 만들기를 클릭합니다.

  6. 새 파일 만들기 창에서 다음을 수행합니다.

    1. 파일 경로 추가 필드에 definitions/ 다음에 파일 이름을 입력하고 _test.sqlx를 입력합니다. 예를 들면 definitions/customer_spend_test.sqlx입니다.

      파일 이름에는 숫자, 문자, 하이픈, 밑줄만 포함할 수 있습니다.

    2. 파일 만들기를 클릭합니다.

  7. 테스트 파일에 다음 config 블록을 추가합니다.

    config {
      type: "test",
      dataset: "ACTION_NAME"
    }
    

    ACTION_NAME을 이 테스트에서 검증하는 작업의 이름으로 바꿉니다.

  8. 테스트된 작업을 모의하려면 각 작업 종속 항목에 input 블록을 추가하고 다음 형식으로 종속 항목을 테스트하는 SQL 쿼리를 작성합니다.

    input "DEPENDENCY_NAME" {
    SELECT ...
    SELECT ...
    }
    

    DEPENDENCY_NAME을 이 입력이 모의하는 테스트된 작업 종속 항목의 이름으로 바꿉니다.

  9. input 블록 아래에 예상 출력 행을 나타내는 표준 SQL 쿼리를 다음 형식으로 작성합니다.

    -- Expected Output
    SELECT ...
    SELECT ...
    

예상 출력 쿼리는 테스트된 작업이 모의 입력을 고려하여 생성해야 하는 행과 열만 반환해야 합니다.

다음 코드 샘플은 customer_spend.sqlx 워크플로 작업을 보여줍니다.

config {
type: "table",
name: "customer_spend"
}

SELECT
  c.customer_id,
  c.name,
  SUM(o.amount) AS total_completed_amount
FROM
  ${ref("source_customers")} c
  JOIN
  ${ref("source_orders")} o
  ON c.customer_id = o.customer_id
WHERE
  o.status = 'COMPLETED'
GROUP BY
  1, 2

다음 코드 샘플은 customer_spend.sqlx 작업의 종속 항목을 모의하고 모의의 예상 결과를 정의하는 customer_spend_test.sqlx 단위 테스트를 보여줍니다.

config {
  type: "test",
  dataset: "customer_spend"
}

input "source_customers" {
  SELECT 101 AS customer_id, 'Alice' AS name UNION ALL
  SELECT 102 AS customer_id, 'Bob' AS name UNION ALL
  SELECT 103 AS customer_id, 'Charlie' AS name
}

input "source_orders" {
  -- Alice has one completed and one pending order
  SELECT 1 AS order_id, 101 AS customer_id, 'COMPLETED' AS status, 100.0 AS amount UNION ALL
  SELECT 2 AS order_id, 101 AS customer_id, 'PENDING' AS status, 50.0 AS amount UNION ALL
  -- Bob has one completed order
  SELECT 3 AS order_id, 102 AS customer_id, 'COMPLETED' AS status, 250.0 AS amount UNION ALL
  -- Charlie has no orders
  SELECT 4 AS order_id, 999 AS customer_id, 'COMPLETED' AS status, 10.0 AS amount
}

-- Expected Output
SELECT 101 AS customer_id, 'Alice' AS name, 100.0 AS total_completed_amount UNION ALL
SELECT 102 AS customer_id, 'Bob' AS name, 250.0 AS total_completed_amount

단위 테스트 실행

단위 테스트를 실행하려면 다음 단계를 따르세요.

콘솔

  1. Google Cloud 콘솔에서 Dataform 페이지로 이동합니다.

    Dataform 페이지로 이동

  2. 저장소를 선택합니다.

  3. 개발 작업공간을 선택합니다.

  4. 실행 시작  > 작업 실행을 클릭합니다.

  5. 실행 패널의 실행 모드 섹션에서 단위 테스트를 선택합니다.

  6. 다음 옵션 중 하나를 선택합니다.

    • 단위 테스트 선택: 수동으로 선택한 단위 테스트를 실행합니다.
    • 태그된 단위 테스트 선택: 선택한 태그로 단위 테스트를 실행합니다.
    • 모든 단위 테스트: 작업공간의 모든 단위 테스트를 실행합니다.
  7. 선택사항: 실행 옵션 섹션에서 우선순위가 높은 대화형 작업으로 실행 체크박스를 선택하여 실행 속도를 우선시하여 단위 테스트를 즉시 실행합니다.

    우선순위가 높은 대화형 작업으로 실행 체크박스를 선택하지 않으면 Dataform은 기본적으로 일괄 리소스를 사용하여 단위 테스트를 실행하여 컴퓨팅 비용 절감을 우선시합니다.

  8. 실행 시작을 클릭합니다.

API

단위 테스트를 프로그래매틱 방식으로 실행하려면 WorkflowInvocations.create 메서드를 사용하여 워크플로 호출을 만들고 invocationConfig 객체에서 다음 단위 테스트 실행 매개변수를 설정하세요.

"executionMode": "UNIT_TESTS_ONLY"
"UNIT_TESTS_ONLY"로 설정된 이 매개변수는 저장소에 정의된 단위 테스트의 실행을 트리거합니다.
선택사항: "queryPriority": "INTERACTIVE"
이 매개변수가 "INTERACTIVE"로 설정되면 Dataform은 즉시 쿼리를 실행합니다. 설정하지 않으면 Dataform은 기본 일괄 쿼리 우선순위로 단위 테스트를 실행합니다.
선택사항: "includedTargets": []
이 매개변수를 사용하면 Dataform이 이러한 테스트만 실행하도록 단위 테스트를 지정할 수 있습니다.
선택사항: "includedTags": []
이 매개변수를 사용하면 태그를 지정하여 Dataform이 해당 태그로 태그된 단위 테스트만 실행하도록 할 수 있습니다.

다음 코드 샘플은 기본 일괄 쿼리 우선순위로 my-repo 저장소에 정의된 모든 단위 테스트를 실행하는 워크플로 호출의 본문을 보여줍니다.

{
  "compilationResult": "projects/my-project/locations/us/repositories/my-repo/compilationResults/my-compilation-id",
  "invocationConfig": {
    "executionMode": "UNIT_TESTS_ONLY"
  }
}

다음 코드 샘플은 대화형 쿼리 우선순위로 my-test 단위 테스트만 실행하는 워크플로 호출의 본문을 보여줍니다.

{
  "compilationResult": "projects/my-project/locations/us/repositories/my-repo/compilationResults/my-compilation-id",
  "invocationConfig": {
    "executionMode": "UNIT_TESTS_ONLY",
    "queryPriority": "INTERACTIVE",
    "includedTargets": [
      {
        "database": "my-project",
        "schema": "my-dataset",
        "name": "my-test"
      }
    ]
  }
}

다음 코드 샘플은 test-tag-1 또는 test-tag-2로 태그된 my-repo 저장소에서 단위 테스트를 실행하는 워크플로 호출의 본문을 보여줍니다.

{
  "compilationResult": "projects/my-project/locations/us/repositories/my-repo/compilationResults/my-compilation-id",
  "invocationConfig": {
    "executionMode": "UNIT_TESTS_ONLY",
    "queryPriority": "INTERACTIVE",
    "includedTags": [
      "test-tag-1",
      "test-tag-2"
    ]
  }
}

단위 테스트 결과 검사

컴파일된 그래프 또는 실행에서 단위 테스트의 예상 스크립트와 실제 스크립트 간의 차이점을 검사할 수 있습니다.

컴파일된 그래프

컴파일된 워크플로 작업 그래프에서 단위 테스트의 실제 스크립트와 예상 스크립트를 보려면 다음 단계를 따르세요.

  1. Google Cloud 콘솔에서 Dataform 페이지로 이동합니다.

    Dataform 페이지로 이동

  2. 저장소를 선택합니다.

  3. 개발 작업공간을 선택합니다.

  4. 선택사항: 단위 테스트를 독립적인 그래프 노드로 보는 대신 테스트하는 작업에 연결된 단위 테스트를 보려면 workflow_settings.yaml 파일에서 includeTestsInCompiledGraph 설정을 true로 설정합니다.

    1. workflow_settings.yaml 파일을 선택합니다.
    2. 다음 코드를 추가합니다.
    includeTestsInCompiledGraph: true
    
  5. 컴파일된 그래프를 클릭합니다.

  6. 컴파일된 그래프에서 단위 테스트를 선택한 후 쿼리를 클릭합니다.

  7. 실제 SQL 스크립트예상 SQL 스크립트를 비교합니다.

실행

  1. Google Cloud 콘솔에서 Dataform 페이지로 이동합니다.

    Dataform 페이지로 이동

  2. 저장소를 선택합니다.

  3. 개발 작업공간을 선택합니다.

  4. 실행을 클릭한 다음 선택한 단위 테스트 옆에 있는 세부정보 보기를 클릭합니다.

  5. 실제 결과 쿼리예상 결과 쿼리를 비교합니다.

단위 테스트 권장사항

모의 데이터 세트를 작게 유지
더 빠른 컴파일과 쉬운 디버깅을 위해 모의 입력 데이터를 10개 행 미만으로 유지하세요.
명시적 행 순서 지정
평가 중에 결정적인 행 순서를 보장하려면 작업 쿼리와 예상 출력 쿼리 모두에 ORDER BY 절을 추가하세요.
모의 문에서 열을 명시적으로 변환
모의 문에서 열을 명시적으로 변환하면(예: CAST(100 AS INT64) 사용) 유형 엄격성이 유지되고 컴파일 오류가 방지됩니다.
NULL 또는 누락된 값이 있는 테스트 사례 포함
NULL 또는 누락된 값이 있는 테스트 사례를 입력 모의 쿼리에 포함하면 COALESCE 문, 문자열 작업, 필터 기준이 불완전하거나 null인 프로덕션 데이터를 안전하게 처리할 수 있습니다.

다음 코드 샘플은 NULL 테스트 사례를 보여줍니다.

input "source_customers" {
  SELECT 101 AS customer_id, 'Alice' AS name UNION ALL
  SELECT 102 AS customer_id, NULL AS name -- Test null handling
}

다음 단계