CDKTF 유닛 테스트 작성하기

CDKTF를 타입스크립트로 작성한 스택에 대해 유닛 테스트를 추가해 봅니다.
2023.04.02

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

이전 블로그에서 CDKTF로 Amazon VPC를 작성하였습니다. 이 스택에 대해 테스트를 추가해보겠습니다.

이전 블로그

https://dev.classmethod.jp/articles/cdktf-amazon-vpc-typescript/

레포지토리

https://github.com/Tolluset/cdktf-for-vpc

유닛 테스트

CDKTF의 유닛 테스트는 공식문서에서 제시하는 방법이 3가지가 있습니다.

  1. 정의한 리소스 확인 테스트
  2. 스냅샷 테스트
  3. 테라폼 설정 검증 테스트

순서대로 진행하겠습니다.

리소스 테스트

import "cdktf/lib/testing/adapters/jest";
import { TerraformStack, Testing } from "cdktf";
import {
  vpc,
  provider,
  subnet,
  internetGateway,
  routeTable,
} from "@cdktf/provider-aws";
import { VpcStack } from "../main";

describe("Vpc stack", () => {
  it("should contain the follow resources", () => {
    const app = Testing.app();
    const stack = new VpcStack(app, "test", slots);
    const synthesized = Testing.synth(stack);

    expect(synthesized).toHaveProviderWithProperties(
      provider.AwsProvider,
      {
        region: "ap-northeast-2",
      }
    );
    expect(synthesized).toHaveResource(vpc.Vpc);
    expect(synthesized).toHaveResource(subnet.Subnet);
    expect(synthesized).toHaveResource(
      internetGateway.InternetGateway
    );
    expect(synthesized).toHaveResource(routeTable.RouteTable);
  });
});

처음으로는 생성한 스택에 정의한 리소스가 있는지 확인하는 테스트입니다.

const app = Testing.app();
const stack = new VpcStack(app, "test");

---

const app = new App();
new VpcStack(app, "cdktf-for-vpc");

위 쪽이 테스트 코드가 아래쪽이 실제 스택 코드입니다. 위와 같이 CDKTF을 생성한 후 앱의 상테에 정의한 리소스들의 스택을 생성하는 느낌입니다.

스냅샷 테스트

 // 생략

 it("compare snapshots", () => {
    const app = Testing.app();
    const stack = new VpcStack(app, "test", slots);

    expect(Testing.synth(stack)).toMatchSnapshot();
  });

Jest에서 지원하는 스냅샷 테스트를 할 수 있습니다. 테스트를 업데이트하게 되면 아래와 같은 json 형식의 스냅샷 파일이 생성됩니다.

__test__/__snapshots__/main-test.ts.snap

// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Vpc stack compare snapshots 1`] = `
"{
  "provider": {
    "aws": [
      {
        "region": "ap-northeast-2"
      }
    ]
  },
  "resource": {
    "aws_internet_gateway": {
      "test-internet-gateway": {
        "vpc_id": "\${aws_vpc.test-vpc.id}"
      }
    },

테라폼 설정 테스트

  it("to be valid terraform stack", () => {
    const app = Testing.app();
    const stack = new TerraformStack(app, "test");

    new VpcStack(stack, "test-app", slots);

    expect(Testing.fullSynth(stack)).toBeValidTerraform();
  });

  it("to be planned", () => {
    const app = Testing.app();
    const stack = new TerraformStack(app, "test");

    new VpcStack(stack, "test-app", slots);

    expect(Testing.fullSynth(stack)).toPlanSuccessfully();
  });

toBeValidTerraform, toPlanSuccessfully의 테스트들은 테라폼 설정이 올바른지 테스트 해줍니다. 각각 terrafrom validateterraform plan의 단계의 확인에 해당합니다. 위의 테스트들에서는 Testing.synth를 사용했지만 Testing.fullSynth를 사용합니다. 실제 테라폼의 synth하는 것과 같은 동작을 지원합니다.

Currently only Typescript is capable of testing for successful plans, while all languages are capable of testing for validity of the Terraform produced.

위 테스트는 현재 타입스크립트만 지원하고 있습니다. (v0.5.15)

  // Testing.fullSynth 코드 
  public static fullSynth(stack: TerraformStack): string {
    const outdir = fs.mkdtempSync(path.join(os.tmpdir(), "cdktf.outdir."));


    const manifest = new Manifest("stubbed", outdir);


    stack.synthesizer.synthesize({
      outdir,
      manifest,
    });


    manifest.writeToFile();


    return outdir;
  }

https://github.com/hashicorp/terraform-cdk/blob/v0.15.5/packages/cdktf/lib/testing/index.ts#L136-L149

마무리

IaC를 검증하기 위한 방법 중 하나로 유용한게 유닛 테스트입니다. 인프라를 자주 만지지 않는 경우 유닛 테스트가 존재한다면 어떤 의도의 코드였는지 알 수 있어 유용하다고 생각합니다.

레퍼런스

https://developer.hashicorp.com/terraform/cdktf/test/unit-tests