Dataflow 파이프라인 개발 및 테스트

이 페이지에서는 Dataflow 파이프라인을 개발하고 테스트하기 위한 권장사항을 제공합니다.

개요

파이프라인 코드가 구현되는 방식에 따라 프로덕션 단계에서 파이프라인의 성능이 크게 달라집니다. 이 문서에서는 올바르고 효율적으로 작동하는 파이프라인 코드를 만드는 데 도움이 되도록 다음을 설명합니다.

  • 개발 및 배포의 다양한 단계에서 코드 실행을 지원하는 파이프라인 실행기
  • 개발, 테스트, 사전 프로덕션, 프로덕션 중에 파이프라인을 실행할 수 있는 배포 환경
  • 그대로 사용하거나 새 파이프라인을 기반으로 코드 개발을 가속화할 수 있는 오픈소스 파이프라인 코드 및 템플릿
  • 파이프라인 코드 테스트를 위한 권장사항입니다. 먼저 이 문서에서는 단위 테스트, 통합 테스트, 엔드 투 엔드 테스트 등 다양한 테스트 유형의 범위와 관계를 포함하는 개요를 제공합니다. 둘째, 테스트 데이터를 만들고 통합하는 메서드 및 각 테스트에 사용할 파이프라인 실행기를 비롯하여 각 테스트 유형을 자세하게 설명합니다.

파이프라인 실행기

개발 및 테스트 중에는 다양한 Apache Beam 실행기를 사용하여 파이프라인 코드를 실행합니다. Apache Beam SDK는 로컬 개발 및 테스트를 위한 Direct Runner를 제공합니다. 출시 자동화 도구는 단위 테스트 및 통합 테스트에 Direct Runner를 사용할 수도 있습니다. 예를 들어 지속적 통합(CI) 파이프라인 내에서 Direct Runner를 사용할 수 있습니다.

Dataflow에 배포된 파이프라인은 프로덕션과 유사한 환경에서 파이프라인을 실행하는 Dataflow Runner를 사용합니다. 또한 임시 개발 테스트 및 엔드 투 엔드 파이프라인 테스트에도 Dataflow Runner를 사용할 수 있습니다.

이 페이지에서는 Apache Beam 자바 SDK를 사용하여 빌드한 파이프라인을 실행하는 데 중점을 두지만 Dataflow는 Python 및 Go를 사용하여 개발한 Apache Beam 파이프라인 역시 지원합니다. Apache Beam 자바, Python, Go SDK는 Dataflow에서 정식 버전으로 사용 가능합니다. SQL 개발자는 Apache Beam SQL을 사용하여 친숙한 SQL 언어를 사용하는 파이프라인을 만들 수도 있습니다.

배포 환경 설정

배포의 여러 단계에서 사용자, 데이터, 코드, 기타 리소스를 분리하려면 배포 환경을 만듭니다. 가능하면 파이프라인 개발의 여러 단계에 격리된 환경을 제공할 수 있도록 별도의 Google Cloud 프로젝트를 사용하세요.

다음 섹션에서는 일반적인 배포 환경 모음을 설명합니다.

로컬 환경

로컬 환경은 개발자의 워크스테이션입니다. 개발 및 신속한 테스트를 위해서는 Direct Runner를 사용하여 로컬에서 파이프라인 코드를 실행합니다.

Direct Runner를 사용하여 로컬로 실행되는 파이프라인은 Pub/Sub 주제 또는 BigQuery 테이블과 같은 원격 Google Cloud 리소스와 상호 작용할 수 있습니다. Google Cloud 서비스를 사용한 임시 테스트를 수행할 수 있도록 개별 개발자에게 별도의 Google Cloud 프로젝트를 제공하세요.

Pub/SubBigtable과 같은 일부 Google Cloud 서비스는 로컬 개발을 위한 에뮬레이터를 제공합니다. 이러한 에뮬레이터를 Direct Runner와 함께 사용하여 엔드 투 엔드 로컬 개발 및 테스트를 사용 설정할 수 있습니다.

샌드박스 환경

샌드박스 환경은 코드 개발 중에 개발자에게 Google Cloud 서비스에 대한 액세스 권한을 제공하는 Google 클라우드 프로젝트입니다. 파이프라인 개발자는 Google Cloud 프로젝트를 다른 개발자와 공유하거나 자체 프로젝트를 사용할 수 있습니다. 개별 프로젝트를 사용하면 공유 리소스 사용량 및 할당량 관리와 관련된 계획의 복잡성이 줄어듭니다.

개발자는 샌드박스 환경을 사용하여 Dataflow Runner를 사용하여 임시 파이프라인 실행을 수행할 수 있습니다. 샌드박스 환경은 코드 개발 단계에서 프로덕션 실행기를 대상으로 코드를 디버깅하고 테스트하는 데 유용합니다. 예를 들어 임시 파이프라인 실행에서는 개발자가 다음을 수행할 수 있습니다.

  • 확장 동작에 코드 변경이 미치는 영향 관찰
  • Direct Runner와 Dataflow Runner의 동작 간의 잠재적 차이점 이해
  • Dataflow가 그래프 최적화를 적용하는 방법 이해

임시 테스트의 경우 개발자는 로컬 환경에서 코드를 배포하여 샌드박스 환경 내에서 Dataflow를 실행할 수 있습니다.

사전 프로덕션 환경

사전 프로덕션 환경은 엔드 투 엔드 테스트와 같이 유사 프로덕션 조건에서 실행되어야 하는 개발 단계를 위한 환경입니다. 사전 프로덕션 환경에 별도의 프로젝트를 사용하고 가능하면 프로덕션과 비슷하게 구성하세요. 마찬가지로 유사 프러덕션 규모의 엔드 투 엔드 테스트를 허용하려면 Dataflow 및 다른 서비스에 대한 Google Cloud 프로젝트 할당량을 프로덕션 환경과 최대한 비슷하게 만들어야 합니다.

요구사항에 따라 사전 프로덕션을 여러 환경으로 분리할 수 있습니다. 예를 들어 품질 관리 환경은 품질 분석가의 작업을 지원하여 다양한 워크로드 조건에서 데이터 정확성, 최신성, 성능과 같은 서비스 수준 목표(SLO)를 테스트할 수 있습니다.

엔드 투 엔드 테스트에는 테스트 범위 내의 데이터 소스 및 싱크와의 통합이 포함됩니다. 이를 사전 프로덕션 환경에서 사용할 수 있도록 하는 방법을 생각해 보세요. 테스트 데이터를 사전 프로덕션 환경 자체에 저장할 수 있습니다. 예를 들어 테스트 데이터는 입력 데이터가 있는 Cloud Storage 버킷에 저장됩니다. 다른 경우에는 프로덕션 환경에 있는 별도의 구독을 통한 Pub/Sub 주제와 같은 사전 프로덕션 환경 외부에서 테스트 데이터가 시작될 수 있습니다. 스트리밍 파이프라인의 경우 생성된 데이터(예: Dataflow 스트리밍 데이터 생성기 사용)를 사용하여 엔드 투 엔드 테스트를 실행하여 프로덕션과 유사한 데이터 특성 및 볼륨을 에뮬레이션할 수도 있습니다.

스트리밍 파이프라인의 경우 프로덕션에 대한 변경사항을 적용하기 전에 사전 프로덕션 환경을 사용하여 파이프라인 업데이트를 테스트합니다. 특히 다운타임을 피하기 위해 병렬 파이프라인을 실행할 때와 같이 여러 단계를 조정해야 할 경우, 스트리밍 파이프라인의 업데이트 절차를 테스트하고 확인하는 것이 중요합니다.

프로덕션 환경

프로덕션 환경은 전용 Google Cloud 프로젝트입니다. 지속적 배포는 엔드 투 엔드 테스트를 모두 통과한 경우 배포 아티팩트를 프로덕션 환경에 복사합니다.

개발 권장사항

Dataflow 파이프라인 권장사항을 참조하세요.

파이프라인 테스트

소프트웨어 개발에서 단위 테스트, 통합 테스트, 엔드 투 엔드 테스트는 일반적인 유형의 소프트웨어 테스트입니다. 이러한 테스트 유형은 데이터 파이프라인에도 적용됩니다.

Apache Beam SDK는 이러한 테스트를 사용 설정하는 기능을 제공합니다. 이상적으로 각 테스트 유형은 서로 다른 배포 환경을 대상으로 해야 합니다. 다음 다이어그램은 단위 테스트, 통합 테스트, 엔드 투 엔드 테스트가 파이프라인과 데이터의 여러 부분에 적용되는 방식을 보여줍니다.

테스트 유형 및 변환, 파이프라인, 데이터 소스, 데이터 싱크와의 관계

이 다이어그램에서는 다양한 테스트의 범위를 표시하며, 이들이 변환(DoFnPTransform 서브클래스), 파이프라인, 데이터 소스, 데이터 싱크와 어떻게 관련이 있는지 보여줍니다.

다음 섹션에서는 Dataflow를 사용하여 데이터 파이프라인에 다양한 공식 소프트웨어 테스트가 적용되는 방식을 설명합니다. 이 섹션을 숙독하면서 이 다이어그램으로 돌아가 여러 유형의 테스트가 어떻게 관련되어 있는지 살펴보시기 바랍니다.

데이터 샘플링

Dataflow 파이프라인의 각 단계에서 데이터를 관찰하려면 테스트 중에 데이터 샘플링을 사용 설정합니다. 이렇게 하면 변환의 출력을 보고 출력이 올바른지 확인할 수 있습니다.

단위 테스트

단위 테스트는 확인된 데이터 입력 및 출력 집합과 변환의 출력을 비교하여 DoFn 서브클래스와 복합 변환(PTransform 서브클래스)이 올바르게 작동하는지 확인합니다. 일반적으로 개발자는 로컬 환경에서 이러한 테스트를 실행할 수 있습니다. 빌드 환경에서 지속적 통합(CI)을 사용하여 단위 테스트 자동화를 통해 테스트를 자동으로 실행할 수도 있습니다.

Direct Runner는 변환의 비즈니스 로직 테스트에 중점을 둔 더 작은 참조 테스트 데이터의 하위 집합을 사용하여 단위 테스트를 실행합니다. 테스트 데이터는 테스트를 실행하는 머신의 로컬 메모리에 맞게 작아야 합니다.

Apache Beam SDK는 개별 변환(DoFn 서브클래스), 복합 변환(PTransform), 전체 파이프라인의 단위 테스트에 대하여 TestPipeline이라는 JUnit 규칙을 제공합니다. 다음의 JUnit 테스트 클래스 코드 스니펫에서 보는 것과 같이 PAssert를 사용하는 PCollection 객체의 콘텐츠에 어설션을 적용하기 위해 Direct Runner 또는 Dataflow Runner 같은 Apache Beam 파이프라인 실행기에 TestPipeline을 사용할 수 있습니다.

@Rule
public final transient TestPipeline p = TestPipeline.create();

@Test
@Category(NeedsRunner.class)
public void myPipelineTest() throws Exception {
  final PCollection<String> pcol = p.apply(...)
  PAssert.that(pcol).containsInAnyOrder(...);
  p.run();
}

개별 변환의 단위 테스트

코드를 재사용 가능한 변환(예: 최상위 또는 정적 중첩 클래스)에 포함하면 파이프라인의 여러 부분에 대해 타겟팅된 테스트를 만들 수 있습니다. 테스트의 이점 외에도 재사용 가능한 변환은 파이프라인의 비즈니스 로직을 구성요소 부분으로 자연스럽게 캡슐화함으로써 코드 유지관리성과 재사용성을 강화합니다. 반면, 파이프라인의 개별 부분을 테스트하는 것은 파이프라인이 익명의 내부 클래스를 사용하여 변환을 구현하는 경우에는 어려울 수 있습니다.

다음 자바 스니펫은 테스트를 쉽게 허용하지 않는 익명 내부 클래스로 변환을 구현하는 것을 보여줍니다.

PipelineOptions options = PipelineOptionsFactory.create();

Pipeline p = Pipeline.create(options)

PCollection<Integer> output =
    p.apply("Read from text", TextIO.Read.from(...))
        .apply("Split words", ParDo.of(new DoFn() {
          // Untestable anonymous transform 1
        }))
        .apply("Generate anagrams", ParDo.of(new DoFn() {
          // Untestable anonymous transform 2
        }))
        .apply("Count words", Count.perElement());

앞의 예시를 다음 예시와 비교해 봅시다. 여기서 익명 내부 클래스는 이름이 지정된 구체적인 DoFn 서브클래스로 리팩터링됩니다. 엔드 투 엔드 파이프라인을 구성하는 각 구체적인 DoFn 서브클래스에 대해 개별 단위 테스트를 만들 수 있습니다.

PipelineOptions options = PipelineOptionsFactory.create();

Pipeline p = Pipeline.create(options)

PCollection<Integer> output =
    p.apply("Read from text", TextIO.Read.from(...))
        .apply("Split words", ParDo.of(new SplitIntoWordsFn()))
        .apply("Generate anagrams", ParDo.of(new GenerateAnagramsFn()))
        .apply("Count words", Count.perElement());

DoFn 서브클래스를 테스트하는 것은 단일 변환이 포함된 일괄 파이프라인을 단위 테스트하는 것과 유사합니다. Create 변환을 사용하여 테스트 데이터의 PCollection 객체를 만든 후 DoFn 객체에 전달합니다. PAssert를 사용하여 PCollection 객체의 콘텐츠가 올바른지 확인합니다. 다음 자바 코드 예시에서는 PAssert 클래스를 사용하여 출력 양식이 올바른지 확인합니다.

@Rule
public final transient TestPipeline p = TestPipeline.create();

@Test
@Category(NeedsRunner.class)
public void testGenerateAnagramsFn() {
    // Create the test input
    PCollection<String> words = p.apply(Create.of("friend"));

    // Test a single DoFn using the test input
    PCollection<String> anagrams =
        words.apply("Generate anagrams", ParDo.of(new GenerateAnagramsFn()));

    // Assert correct output from
    PAssert.that(anagrams).containsInAnyOrder(
        "finder", "friend", "redfin", "refind");

    p.run();
}

통합 테스트

통합 테스트는 전체 파이프라인이 올바르게 작동하는지 확인합니다. 다음 통합 테스트 유형을 고려하세요.

  • 데이터 파이프라인을 구성하는 모든 개별 변환의 통합 기능을 평가하는 변환 통합 테스트. 변환 통합 테스트는 외부 데이터 소스 및 싱크와의 통합을 제외한 전체 파이프라인의 단위 테스트로 생각할 수 있습니다. Apache Beam SDK는 데이터 파이프라인에 테스트 데이터를 제공하고 처리 결과를 확인하는 메서드를 제공합니다. Direct Runner는 변환 통합 테스트를 실행하는 데 사용합니다.
  • 데이터 파이프라인의 라이브 데이터 소스 및 싱크와의 통합을 평가하는 시스템 통합 테스트입니다. 파이프라인이 외부 시스템과 통신하려면 외부 서비스에 액세스할 수 있는 적절한 사용자 인증 정보로 테스트를 구성해야 합니다. 스트리밍 파이프라인은 무기한으로 실행되므로 실행 중인 파이프라인을 종료할 시기와 방법을 결정해야 합니다. Direct Runner를 사용하여 시스템 통합 테스트를 실행하면 Dataflow 작업을 제출하고 완료될 때까지 기다리지 않고도 파이프라인과 다른 시스템 간의 통합을 빠르게 확인할 수 있습니다.

개발자 생산성 저하 없이 빠른 결함 감지 및 피드백을 제공하도록 변환 및 시스템 통합 테스트를 설계합니다. Dataflow 작업으로 실행되는 테스트와 같이 오래 실행되는 테스트에는 자주 실행되는 엔드 투 엔드 테스트가 적합할 수 있습니다.

데이터 파이프라인은 하나 이상의 관련 변환으로 생각할 수 있습니다. 파이프라인의 캡슐화 복합 변환을 만들고 TestPipeline을 사용하여 전체 파이프라인의 통합 테스트를 수행할 수 있습니다. 파이프라인을 일괄 처리 또는 스트리밍 모드로 테스트할지 여부에 따라 Create 또는 TestStream 변환을 사용하여 테스트 데이터를 제공하세요.

통합 테스트에 테스트 데이터 사용

프로덕션 환경에서는 파이프라인이 여러 데이터 소스 및 싱크와 통합될 수 있습니다. 그러나 단위 테스트와 변환 통합 테스트의 경우 테스트 입력을 제공하고 출력을 직접 확인하여 파이프라인 코드의 비즈니스 로직을 확인하는 데 중점을 둡니다. 이 방법을 사용하면 테스트를 단순화할 수 있을 뿐만 아니라 파이프라인 관련 문제를 데이터 소스 및 싱크로 인해 발생할 수 있는 문제와 분리할 수 있습니다.

일괄 파이프라인 테스트

일괄 파이프라인의 경우 Create 변환을 사용하여 자바 List 객체와 같은 표준 메모리 내 컬렉션에서 입력 테스트 데이터의 PCollection 객체를 만듭니다. 테스트 데이터가 코드에 포함될 만큼 충분히 작은 경우에는 Create 변환을 사용하는 것이 적합합니다. 그런 다음 출력 PCollection 객체에서 PAssert를 사용하여 파이프라인 코드의 정확성을 확인할 수 있습니다. 이 방법은 Direct Runner와 Dataflow Runner에서 지원합니다.

다음 자바 코드 스니펫은 파이프라인(WeatherStatsPipeline)을 구성하는 개별 변환의 일부 또는 전체를 포함하는 복합 변환의 출력 PCollection 객체에 대한 어설션을 보여줍니다. 이 방법은 파이프라인의 단위 테스트 개별 변환과 유사합니다.

private class WeatherStatsPipeline extends
    PTransform<PCollection<Integer>, PCollection<WeatherSummary>> {
  @Override
  public PCollection<WeatherSummary> expand(PCollection<Integer> input) {
    // Pipeline transforms …
  }
}

@Rule
public final transient TestPipeline p = TestPipeline.create();

@Test
@Category(NeedsRunner.class)
public void testWeatherPipeline() {
  // Create test input consisting of temperature readings
  PCollection<Integer> tempCelsius =
      p.apply(Create.of(24, 22, 20, 22, 21, 21, 20));

  // CalculateWeatherStats calculates the min, max, and average temperature
  PCollection<WeatherSummary> result =
      tempCelsius.apply("Calculate weather statistics", new WeatherStatsPipeline());

   // Assert correct output from CalculateWeatherStats
   PAssert.thatSingleton(result).isEqualTo(new WeatherSummary.Builder()
       .withAverageTemp(21)
       .withMaxTemp(24)
       .withMinTemp(20)
       .build());

   p.run();
}

윈도우 동작을 테스트하려면 다음 코드 스니펫에서와 같이 Create 변환을 사용하여 타임스탬프가 있는 요소를 만들 수도 있습니다.

private static final Duration WINDOW_DURATION = Duration.standardMinutes(3);

@Rule
public final transient TestPipeline p = TestPipeline.create();

@Test
@Category(NeedsRunner.class)
public void testWindowedData() {
    PCollection<String> input =
        p.apply(
            Create.timestamped(
                    TimestampedValue.of("a", new Instant(0L)),
                    TimestampedValue.of("a", new Instant(0L)),
                    TimestampedValue.of("b", new Instant(0L)),
                    TimestampedValue.of("c", new Instant(0L)),
                    TimestampedValue.of("c", new Instant(0L).plus(WINDOW_DURATION)))
                .withCoder(StringUtf8Coder.of()));

   PCollection<KV<String, Long>> windowedCount =
       input
           .apply(Window.into(FixedWindows.of(WINDOW_DURATION)))
           .apply(Count.perElement());

    PAssert.that(windowedCount)
        .containsInAnyOrder(
            // Output from first window
            KV.of("a", 2L),
            KV.of("b", 1L),
            KV.of("c", 1L),
            // Output from second window
            KV.of("c", 1L));

   p.run();
}

스트리밍 파이프라인 테스트

스트리밍 파이프라인에는 제한되지 않은 데이터를 처리하는 방법을 정의하는 가정이 포함됩니다. 이러한 가정은 실제 상황의 데이터 시의성에 대한 가정이며, 가정이 참인지 거짓인지에 따라 정확성에 영향을 미칩니다. 스트리밍 파이프라인의 통합 테스트에는 스트리밍 데이터 도착의 비확정적 특성을 시뮬레이션하는 테스트가 포함되어야 합니다.

이러한 테스트를 사용 설정하기 위해 Apache Beam SDK는 TestStream 클래스를 제공하여 데이터 파이프라인 결과에 요소 타이밍(조기, 시간 또는 지연 데이터)의 효과를 모델링합니다. 이러한 테스트를 PAssert 클래스와 함께 사용하여 예상 결과를 확인합니다.

TestStream은 Direct Runner 및 Dataflow Runner에서 지원됩니다. 다음 코드 샘플은 TestStream 변환을 만듭니다.

final Duration WINDOW_DURATION = Duration.standardMinutes(3);

@Rule
public final transient TestPipeline p = TestPipeline.create();

@Test
@Category(NeedsRunner.class)
public void testDroppedLateData() {
   TestStream<String> input = TestStream.create(StringUtf8Coder.of())
      // Add elements arriving before the watermark
      .addElements(
         TimestampedValue.of("a", new Instant(0L)),
         TimestampedValue.of("a", new Instant(0L)),
         TimestampedValue.of("b", new Instant(0L)),
         TimestampedValue.of("c", new Instant(0L).plus(Duration.standardMinutes(3))))
         // Advance the watermark past the end of the window
      .advanceWatermarkTo(new Instant(0L).plus(WINDOW_DURATION).plus(Duration.standardMinutes(1)))
      // Add elements which will be dropped due to lateness
      .addElements(
         TimestampedValue.of("c", new Instant(0L)))
      // Advance the watermark to infinity which will close all windows
      .advanceWatermarkToInfinity();

      PCollection<KV<String, Long>> windowedCount =
          p.apply(input)
             .apply(Window.into(FixedWindows.of(WINDOW_DURATION)))
             .apply(Count.perElement());

   PAssert.that(windowedCount)
      .containsInAnyOrder(
          // Output from first window
          KV.of("a", 2L),
          KV.of("b", 1L),
          KV.of("c", 1L));

   p.run();
}

TestStream에 대한 상세 내용은 Apache Beam에서 제한 없는 파이프라인 테스트를 참조하세요. 단위 테스트에 Apache Beam SDK를 사용하는 방법에 대한 자세한 내용은 Apache Beam 문서를 참조하세요.

통합 테스트에 Google Cloud 서비스 사용

Direct Runner는 Google Cloud 서비스와 통합할 수 있으므로 로컬 환경의 임시 테스트와 시스템 통합 테스트에서 필요에 따라 Pub/Sub, BigQuery 및 기타 서비스를 사용할 수 있습니다. Direct Runner를 사용하는 경우 gcloud 명령줄 도구를 사용하거나 GOOGLE_APPLICATION_CREDENTIALS 환경 변수를 사용하여 지정한 서비스 계정으로서 구성한 사용자 계정으로 파이프라인이 실행됩니다. 따라서 파이프라인을 실행하기 전에 이 계정에 필요한 리소스에 대한 충분한 권한을 부여해야 합니다. 자세한 내용은 Dataflow 보안 및 권한을 참조하세요.

전체 로컬 통합 테스트의 경우 일부 Google Cloud 서비스에 로컬 에뮬레이터를 사용할 수 있습니다. Pub/SubBigtable에서 로컬 에뮬레이터를 사용할 수 있습니다.

스트리밍 파이프라인의 시스템 통합 테스트의 경우 setBlockOnRun 메서드(DirectOptions 인터페이스에 정의됨)를 사용하여 Direct Runner가 파이프라인을 비동기적으로 실행하게 할 수 있습니다 그렇지 않으면 파이프라인 실행은 파이프라인이 수동으로 종료될 때까지 호출 상위 프로세스(예: 빌드 파이프라인의 스크립트)를 차단합니다. 파이프라인을 비동기식으로 실행하는 경우 다음 코드 예시와 같이 반환된 PipelineResult 인스턴스를 사용하여 파이프라인 실행을 취소할 수 있습니다.

public interface StreamingIntegrationTestOptions extends
   DirectOptions, StreamingOptions, MyOtherPipelineOptions {
   ...
}

@Rule
public final transient TestPipeline p = TestPipeline.create();

@Test
@Category(NeedsRunner.class)
public void testNonBlockingPipeline() {
    StreamingIntegrationTestOptions options =
        p.getOptions().as(StreamingIntegrationOptions.class);

    options.setBlockOnRun(false); // Set non-blocking pipeline execution
    options.setStreaming(true); // Set streaming mode

    p.apply(...); // Apply pipeline transformations

    PipelineResult result = p.run(); // Run the pipeline

    // Generate input, verify output, etc
    ...

    // Later on, cancel the pipeline using the previously returned
    result.cancel();
}

엔드 투 엔드 테스트

엔드 투 엔드 테스트는 프로덕션과 거의 동일한 조건의 Dataflow Runner에서 테스트를 실행하여 엔드 투 엔드 파이프라인이 올바로 동작하는지 확인합니다. 이 테스트는 Dataflow Runner를 사용하여 비즈니스 로직이 올바르게 작동하는지 확인하고 파이프라인이 프로덕션과 유사한 로드에서 예상대로 작동하는지 테스트합니다. 일반적으로 사전 프로덕션 환경으로 지정된 전용 Google Cloud 프로젝트에서 엔드 투 엔드 테스트를 실행합니다.

파이프라인을 다양한 규모로 테스트하려면 다음과 같은 여러 유형의 엔드 투 엔드 테스트를 사용합니다.

  • 테스트 데이터 세트의 소량(예: 1%)을 사용하여 소규모 엔드 투 엔드 테스트를 실행하여 사전 프로덕션 환경에서 파이프라인 기능을 빠르게 검증합니다.
  • 전체 테스트 데이터 세트를 사용하여 대규모 엔드 투 엔드 테스트를 실행하여 프로덕션과 유사한 데이터 볼륨 및 조건에서 파이프라인 기능을 검증합니다.

스트리밍 파이프라인의 경우 동일한 데이터를 사용할 수 있다면 프로덕션 파이프라인과 테스트 파이프라인을 동시에 실행하는 것이 좋습니다. 이 프로세스를 통해 결과와 자동 확장 및 성능과 같은 작업 동작을 비교할 수 있습니다.

엔드 투 엔드 테스트는 파이프라인이 프로덕션 SLO를 얼마나 잘 충족하는지 예측하는 데 도움이 됩니다. 사전 프로덕션 환경은 프로덕션과 유사한 조건에서 파이프라인을 테스트합니다. 엔드 투 엔드 테스트 내에서 파이프라인은 Dataflow Runner를 사용하여 실행되어 프로덕션의 데이터 세트와 일치하거나 거의 유사한 전체 참조 데이터 세트를 처리합니다.

실제 데이터를 정확하게 시뮬레이션하는 테스트용 합성 데이터를 생성하지 못할 수도 있습니다. 이 문제를 해결하는 한 가지 방법은 프로덕션 데이터 소스에서 정리된 추출을 사용하여 참조 데이터 세트를 만드는 것입니다. 이때 민감한 정보는 적절한 변환을 통해 익명화됩니다. 이를 위해 민감한 정보 보호를 사용하는 것이 좋습니다. 민감한 정보 보호는 다양한 콘텐츠 유형 및 데이터 소스에서 민감한 정보를 감지하고 수정, 마스킹, 암호화 보존 형식, 날짜 이동 등 다양한 익명화 기술을 적용할 수 있습니다.

일괄 및 스트리밍 파이프라인의 엔드 투 엔드 테스트의 차이

대규모 테스트 데이터 세트에 대해 완전한 엔드 투 엔드 테스트를 실행할 때는 미리 테스트 데이터의 적은 비율(예: 1% 테스트 실행)로 테스트를 실행하여 더 짧은 시간 내에 예상되는 동작을 확인하는 것이 좋습니다. Direct Runner를 사용하는 통합 테스트와 마찬가지로 Dataflow Runner를 사용하여 파이프라인을 실행할 때 PCollection 객체에서 PAssert를 사용할 수 있습니다. PAssert에 대한 자세한 내용은 이 페이지의 단위 테스트 섹션을 참조하세요.

사용 사례에 따라 엔드 투 엔드 테스트에서 매우 큰 출력을 검증하는 것은 비실용적이거나 비용이 많이 들거나 그 밖의 어려움이 있을 수 있습니다. 이 경우, 출력 결과 집합에서 대표 샘플을 확인하는 것이 가능합니다. 예를 들어 BigQuery를 사용하여 출력 행을 샘플링하고 예상 결과의 참조 데이터 세트를 비교하는 방식입니다.

스트리밍 파이프라인의 경우 합성 데이터로 실제 스트리밍 조건을 시뮬레이션하기가 어려울 수 있습니다. 엔드 투 엔드 테스트를 위한 스트리밍 데이터를 제공하는 일반적인 방법은 테스트를 프로덕션 데이터 소스와 통합하는 것입니다. Pub/Sub를 데이터 소스로 사용하는 경우 기존 주제에 대한 추가 구독을 통해 엔드 투 엔드 테스트를 위한 별도의 데이터 스트림을 사용 설정할 수 있습니다. 그런 다음 동일한 데이터를 사용하는 여러 파이프라인의 결과를 비교할 수 있습니다. 이는 후보 파이프라인을 다른 사전 프로덕션 및 프로덕션 파이프라인과 비교하는 데 유용합니다.

다음 다이어그램은 이 방법으로 프로덕션 파이프라인과 테스트 파이프라인이 서로 다른 배포 환경에서 동시에 실행되도록 허용하는 방법을 보여줍니다.

단일 Pub/Sub 스트리밍 소스를 사용하여 프로덕션 파이프라인과 병렬로 테스트 파이프라인 실행하기.

다이어그램에서 두 파이프라인은 모두 동일한 Pub/Sub 주제에서 읽지만 별도의 구독을 사용합니다. 이 설정을 통해 두 파이프라인이 동일한 데이터를 독립적으로 처리하고 결과를 비교할 수 있습니다. 테스트 파이프라인은 프로덕션 프로젝트와 별도의 서비스 계정을 사용하므로 프로덕션 프로젝트에 Pub/Sub 구독자 할당량을 사용하지 않습니다.

일괄 파이프라인과 달리 스트리밍 파이프라인은 명시적으로 취소될 때까지 계속 실행됩니다. 엔드 투 엔드 테스트에서는 다음 엔드 투 엔드 테스트가 실행될 때까지 파이프라인을 계속 실행할지 또는 결과를 검사할 수 있도록 테스트 완료 지점에서 파이프라인을 취소할지 여부를 결정해야 합니다.

사용하는 테스트 데이터의 유형은 이 결정에 영향을 미칩니다. 예를 들어 스트리밍 파이프라인에 제공되는 제한된 테스트 데이터 세트를 사용하는 경우 모든 요소가 처리를 완료하면 파이프라인을 취소할 수 있습니다. 또는 실제 데이터 소스(예: 프로덕션에 사용되는 기존 Pub/Sub 주제)를 사용하거나 테스트 데이터를 지속적으로 생성하는 경우 테스트 파이프라인을 더 오랜 기간 계속 실행해야 할 수 있습니다. 후자의 경우 프로덕션 환경 또는 다른 테스트 파이프라인에서도 동작을 비교할 수 있습니다.