<

TypescriptでArchUnitしてみた

ArchUnit をというものを最近知りました。依存関係のテストができるそうです。さっそく試してみたいと思いますので、その備忘録として残しておきます。

ArchUnit

https://www.archunit.org/

ArchUnit is a free, simple and extensible library for checking the architecture of your Java code using any plain Java unit test framework. That is, ArchUnit can check dependencies between packages and classes, layers and slices, check for cyclic dependencies and more. It does so by analyzing given Java bytecode, importing all classes into a Java code structure.

Java のアーキテクチャをテストできるライブラリで、パッケージやクラス、レイヤー、スライス(?)の依存関係をテストできるそうです。 そこで、親の顔よりも見たこの図をテストしたいと思います。

Clean Coder Blog > The Clean Architecture
Clean Coder Blog > The Clean Architecture

Typescript でも ArchUnit したい

ArchUnit は Java 製です。私は Typescript の ArchUnit がしたいです。 そこで、良さげなライブラリを発見しました。

https://github.com/MaibornWolff/ts-arch

特に拘りなく、アーキテクチャのテストができれば何でも良いかなと思います。 極端な話、ソースコードを AST パースし、依存関係を抽出できれば自作できるんじゃないかと思います。

試してみた

試したソースコードは、下記に置いています。ご参考下さい。

https://github.com/silverbirder/try-archunit

全体のソースコードツリーは次の構成です。

src
└ 1_enterprise_business_rules
  └ entities
    └ Entity.ts
└ 2_application_business_rules
  └ use_cases
    └ UseCase.ts
└ 3_interface_adapters
  └ controllers
    └ Controller.ts
  └ gateways
    └ Gateway.ts
  └ presenters
    └ Presenter.ts
└ 4_frameworks_and_drivers
  └ web
    └ Web.ts
└ clean_architecture.puml
└ clean_architecture.test.ts

各プロダクトコードは、下の階層のファイルを import しているだけとします。

// src/4_frameworks_and_drivers/web/Web.ts
import "../../3_interface_adapters/gateways/Gateway";
import "../../3_interface_adapters/controllers/Controller";
import "../../3_interface_adapters/presenters/Presenter";
// src/3_interface_adapters/controllers/Controller.ts
import "../../2_application_business_rules/use_cases/UseCase";
// src/2_application_business_rules/use_cases/UseCase.ts
import "../../1_enterprise_business_rules/entities/Entity";
// src/1_enterprise_business_rules/entities/Entity.ts

下記ファイルにある UML のコンポーネント図で依存関係を表します。

# clean_architecture.puml
@startuml
  component [4_frameworks_and_drivers] #Blue
  component [3_interface_adapters] #Green
  component [2_application_business_rules] #Red
  component [1_enterprise_business_rules] #Yellow

  4_frameworks_and_drivers --> 3_interface_adapters
  3_interface_adapters --> 2_application_business_rules
  2_application_business_rules --> 1_enterprise_business_rules
@enduml

UML を可視化すると、下記の図のとおりです。

clean_architecture.puml
clean_architecture.puml

テストコードは、下記のとおりです。

// clean_architecture.test.ts
describe("architecture", () => {
  it("Check dependency", async () => {
    const architectureUml = path.resolve(__dirname, "clean_architecture.puml");
    const violations = await slicesOfProject()
      .definedBy("src/(**)/")
      .should()
      .adhereToDiagramInFile(architectureUml)
      .check();
    await expect(violations).toEqual([]);
  });
});

このテストケースは PASS します。

src/clean_architecture.test.ts > architecture > Check dependency #Succeed
src/clean_architecture.test.ts > architecture > Check dependency #Succeed

では、違反コードを書いてみます。

// src/3_interface_adapters/controllers/Controller.ts
import "../../2_application_business_rules/use_cases/UseCase";
import "../../4_frameworks_and_drivers/web/Web";

3 レイヤーが上位の 4 レイヤーを使用しています。この状態でテストを実行すると、

src/clean_architecture.test.ts > architecture > Check dependency #Failed
src/clean_architecture.test.ts > architecture > Check dependency #Failed

見事 Failed となりました。つまり、依存関係の誤りを自動的に検出することができます。

最後に

規模が大きなプロジェクトほど、依存関係が複雑になりがちです。(Java でいう) パッケージやクラスの依存関係を適切に設計できていたとしても、誰かが壊しかねません。せっかく設計したのに壊されるのは、とても残念なので、テストコードで守ってあげましょう!

Tags

Google Apps Script でも テスト がしたい! (Clasp + Typescript + Jest)

2020-02-01

Google Apps Script(以下,GAS)でライブラリを公開しました。ライブラリを開発する際、テストのフィードバックサイクルを短くするため、`Clasp + Typescript + Jest` という技術スタックを選択しました。その開発体験について共有しようと思います。特段変わったことはしていません。...

IntelliJ + TypeScript + Docker で Remote Debug (Break Point)

2019-12-28

Dockerコンテナ上で、 `ts-node-dev --inspect=0.0.0.0:9229 ./dist/index.js` を実行...

BigQueryだけで完結するモック可能なユニットテスト手法

2021-11-26

BigQuery、皆さん使っていますか? 私は、業務でBigQueryを使ったデータ構築をしています。品質担保のため、BigQueryのSQLに対してテストをしたいと考えています。本記事では、BigQueryだけで完結し、かつ、Mockデータを差し替え可能なユニットテスト手法について、紹介します。...

ユニットテストを書く上で守りたいこと

2020-01-12

背景 普段、業務でユニットテストを書いたり、レビューをしたりしています。ユニットテストがあることは良いことなのですが、困ったことがあります。それは、ユニットテストのルールが明確じゃない点です。そのため、人によって、ユニットテストの書き方がマチマチで、なんとかしたいなと困っています。...

BigQueryだけで完結するモック可能なユニットテスト手法

2021-11-26

BigQuery、皆さん使っていますか? 私は、業務でBigQueryを使ったデータ構築をしています。品質担保のため、BigQueryのSQLに対してテストをしたいと考えています。本記事では、BigQueryだけで完結し、かつ、Mockデータを差し替え可能なユニットテスト手法について、紹介します。...

Webアプリのテスト観点を調べてまとめてみた (25選)

2020-06-18

最近、Property Based Test という言葉を知りました。他にどういうテストの種類があるのか気になったので、調べてみました。本記事は、テストの種類を列挙します。※ 使用する技術は、私の都合上、node.jsで選んでいます。...

Google Apps Script でも テスト がしたい! (Clasp + Typescript + Jest)

2020-02-01

Google Apps Script(以下,GAS)でライブラリを公開しました。ライブラリを開発する際、テストのフィードバックサイクルを短くするため、`Clasp + Typescript + Jest` という技術スタックを選択しました。その開発体験について共有しようと思います。特段変わったことはしていません。...

ユニットテストを書く上で守りたいこと

2020-01-12

背景 普段、業務でユニットテストを書いたり、レビューをしたりしています。ユニットテストがあることは良いことなのですが、困ったことがあります。それは、ユニットテストのルールが明確じゃない点です。そのため、人によって、ユニットテストの書き方がマチマチで、なんとかしたいなと困っています。...