「消化するテスト」から「価値を生むテスト」へ──業務の複雑さに適したテスト方針(後編)
はじめに
前編では、業務の複雑さに応じた実装スタイルとテスト方針の組合せについて、書籍『ドメイン駆動をはじめよう』[1]の知見をもとに整理しました。
後編となる本記事では、私自身がテスト支援の立場で関わっている現場で直面した、「業務の複雑さに対して相性の悪い実装とテストの組合せ」についてご紹介します。そこから見えてきた課題と、より適した組合せに近づくための「最初の一歩」について考察していきます。
複雑な業務に対する“相性の悪い組合せ”とその背景
私が支援した現場では、業務の複雑さに対して、トランザクションスクリプトやアクティブレコードによる実装が採用されており、テスト方針もダイヤモンド型に近い構成となっていました。そのため次にあげるような課題が生じていました。
- 複雑な業務が分散・重複して実装されるため、修正箇所の特定が困難になるなど保守性の低下
- ユニットテストのカバレッジは高いが、業務ロジックの断片的なテストにとどまり、実際の振る舞いを捉えにくい
- UIテスト、APIテストはユニットテストより相対的に高コストなため、テストで詳細なふるまいまで網羅しきれない
こうした構成に至った背景には、現場ならではの事情や制約が存在します。
たとえば、当初は業務が比較的単純で、トランザクションスクリプトで十分に対応できていたものの、時間の経過とともに業務が複雑化し、設計の見直しが追いつかなくなったケースが考えられます。また、ドメインモデルやイベント履歴式ドメインモデルの構築が難しいという現実的な課題もあります。
- システム自体がドメインモデル提唱以前から存在していた
- ドメインモデルの設計には高度な業務理解と設計スキルが求められる
- チームの体制やリソースの制約により、段階的な移行が難しい
こうした背景を踏まえると、現在の構成は「最善ではないかもしれないが、当時の状況においては合理的な選択だった」と言えます。実装スタイルやテスト方針は、業務の変化や技術的制約、チームの体制など、さまざまな要因の影響を受けて決まるものです。
特に長く運用されているシステムでは、初期の設計判断がその後の複雑化に十分対応しきれなくなることもあります。こうした構成は、開発の努力や工夫の積み重ねの上に成り立っている一方で、今後の改善に向けた見直しの余地も含んでいると捉えることができます。
もっとも、業務の複雑さに対して実装とテストの構造が噛み合っていない場合には、いくつかの課題が表面化しやすくなります。たとえば、業務ロジックがサービス層やモデル層に分散し、ユニットテストでは本質的な振る舞いを捉えにくくなることがあります。その結果、テストの網羅性や保守性に課題が生じ、変更に対する信頼性が低下するリスクも高まります。
改善に向けた2つのアプローチ
相性の悪い組合せに直面したとき、すぐに理想的な構成に移行するのは現実的ではありません。特に既存のコードベースやチームの体制を考慮すると、段階的かつ現実的な改善アプローチが求められます。ここでは、2つの方向性から改善の糸口を探ってみます。
1. 現状の実装スタイルに合わせたテスト方針の見直し
複雑な業務をトランザクションスクリプトやアクティブレコードで実装している場合でも、すぐにドメインモデルへ移行できないことは少なくありません。そのような状況では、テスト方針を現実に即して調整することが有効です。
たとえば、業務ロジックが複数の層に分散している場合、統合テストを中心に据えるダイヤモンド型の方針が適しています。E2Eテストだけに依存するのではなく、ユースケース単位での統合テストを整備することで、振る舞いの検証と保守性のバランスを取ることができます。
また、業務ロジックの集中度が高い箇所を特定し、そこだけでもユニットテスト可能な構造にリファクタリングすることで、段階的にテストの信頼性を高めることも可能です。
2.ドメインモデル導入に向けた設計方針の転換
一方で、将来的にドメインモデルへの移行を視野に入れる場合、いきなり大規模な再設計を行うのではなく、小さな構造的改善から始めることが現実的です。
その第一歩として推奨されているのが、「値オブジェクト(Value Object)」と「集約(Aggregate)」の導入です。これにより、業務ルールをコード上で明示的に表現できるようになり、テストの焦点も自然と「振る舞い」に向かうようになります。
ただし、このアプローチにはいくつかの課題も伴います。たとえば:
- 業務ルールを正確に捉えるための業務理解の深掘り
- 値オブジェクトや集約の設計スキルの習得
- チーム内での共通言語(ユビキタス言語)の形成
これらは一朝一夕には解決できませんが、小さなユースケースから試行的に導入することで、徐々にチーム全体の設計力と理解を高めていくことができます。
改善に向けた「最初の一歩」
設計やテストの改善は、一度にすべてを変える必要はありません。むしろ、小さな一歩を積み重ねることが、結果的に大きな変化につながると私は考えています。
たとえば、現状の実装スタイルを維持しつつ改善を図る場合は、まず業務ロジックがどこに実装されているかを可視化することから始めるのが有効です。サービス層やモデル層にまたがる処理を洗い出し、ユースケース単位での統合テストを整備することで、テストの信頼性を高めることができます。
一方で、ドメインモデルへの移行を視野に入れる場合は、小さなユースケースを選び、そこに値オブジェクトや集約を導入してみるのがよい出発点になります。最初から完璧な設計を目指すのではなく、試行錯誤を通じてチーム内に理解と共通言語を育てていくことが、長期的な改善につながります。
どちらのアプローチにおいても共通して言えるのは、 「今の構成を否定すること」ではなく、「よりよい選択肢を模索すること」 が大切だということです。現場の制約や背景を尊重しながら、少しずつでも前に進むことが、結果として開発体験と品質の向上につながっていくはずです。
おわりに
設計とテストの“相性”は、業務の複雑さやデータ構造に深く関係しています。今回ご紹介したように、現場で相性の悪い組合せに直面したときでも、業務の構造を見直し、ドメインモデルの導入に向けた小さな一歩を踏み出すことで、改善の糸口が見えてきます。
すぐにすべてを変えることは難しくても、少しずつでも「業務に合った設計とテスト」に近づいていくことが、開発体験と品質の向上につながると信じています。
今後も、現場での気づきや実践を通じて得た知見を共有していきますので、引き続きよろしくお願いします。
-
Vlad Khononov著、増田亨、綿引琢磨訳:ドメイン駆動設計をはじめよう―ソフトウェアの実装と事業戦略を結びつける実践技法, O'Reilly Japan, 2024 ↩︎

NTT DATA公式アカウントです。 技術を愛するNTT DATAの技術者が、気軽に楽しく発信していきます。 当社のサービスなどについてのお問い合わせは、 お問い合わせフォーム nttdata.com/jp/ja/contact-us/ へお願いします。
Discussion