1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

最終回:「未来のバグを予言する」〜並列実行とこれからのエンジニア〜

1
Posted at

『先輩、私のコードがバグだらけです!〜TUnit と Moq で始めるユニットテスト入門〜』シリーズは、全 6 回です。

前回はこちら

登場人物

先輩 : .NET 開発歴 10 年。「DRY」が座右の銘。テストコードのないリリース作業は、命綱なしのバンジージャンプだと思っている。
後輩 : 新人開発者。TUnit の修行を通じて、コピペ職人からテスト駆動エンジニアへと進化しつつある。


1. プロローグ:なぜこんなに速いのか?

後輩:「先輩……変なんです」

先輩:「どうした? またテストが全部失敗したか?」

後輩:「いえ、逆です。全部成功してるんですが……速すぎるんです。さっきテストを 100 ケース追加したのに、Visual Studio のテストエクスプローラーの完了時間がほとんど変わっていません。もしかして、サボって実行してないんじゃ……?」

先輩:「フッ、気づいたか。それが TUnit の真骨頂、『完全並列実行(Parallel Execution)』だ」

6-1.png

後輩:「並列……? つまり、全部同時に動いてるってことですか?」

先輩:「その通り。従来のテストランナーは、基本的に『1つ終わったら次』というリレー方式だった。だが TUnit は違う。『よーいドン!』で全員同時に走り出す徒競走なんだ」

2. 並列実行の落とし穴:「staticおじさん」の排除

先輩:「だが、この速さには代償がある。並列で走るためには、『コース(メモリ)』を共有してはいけないという絶対のルールがある」

後輩:「共有? どういうことですか?」

先輩:「もし、全テストで使い回す『静的変数(static field)』があったらどうなる?」

UserDatabase.cs
// 【TUnitには向かない例】
public static class UserDatabase
{
    // 全員でこのリストを共有してしまう!
    // テストAが追加中に、テストBが削除するとクラッシュする
    public static List<string> Users = new List<string>();
}

先輩:「これを『テスト汚染』と呼ぶ。並列実行のテストでは、 共有される static な状態は深刻な不具合の原因になりやすい。だからこそ、第 4 回で教えた **『毎回 new して DI する(インスタンス化)』という書き方が重要になってくるんだ」



後輩:「ああっ! だから先輩は『使い回すな』って口酸っぱく言ってたんですね! あれは並列実行での事故を防ぐためだったのか……!」

先輩:「そう。TUnit を使うということは、『static おじさん(グローバルな状態に依存する古い設計)』との決別を意味するんだ」

6-2.png

3. 最後の罠:非同期アサーション await Assert

先輩:「さて、TUnit ならではの重要なルールを一つ教えよう。今まで何気なく書いていた Assert だが……」

// TUnitの流儀
[Test]
public async Task CalculatorAdd_Test()
{
    var result = Calculator.Add(1, 2);
    
    // × 間違い:検証が終わる前にテストが終了してしまう!
    // Assert.That(result).IsEqualTo(3);

    // ○ 正解:検証完了を待機する
    // ※ TUnitでは Assert 自体が非同期 API として設計されているため、await が必須となります。
    await Assert.That(result).IsEqualTo(3);
}

後輩:「そういえば、なんで Assertawait が付いてるんですか? 検証なんて一瞬で終わるのに」

先輩:「TUnit は、アサーション自体も非同期で動くように作られている。もし await を忘れると、『検証結果が出る前にテストメソッドが終了し、合格扱いになってしまう』という恐ろしいことが起きる」

後輩:「ひえっ! バグがあるのにテスト成功!? それ一番怖いじゃないですか!」

先輩:「そうだ。だから TUnit では、『息をするように await を書け』。それが未来のバグを防ぐ唯一の方法だ」

6-3.png

4. 爆速の向こう側:Native AOT への対応

後輩:「並列実行に非同期アサーション……TUnit って、とことん『現代的なC#』に特化してるんですね」

先輩:「ああ。そしてもう一つ、これからの時代に欠かせない最強の武器がある。『Native AOT(ネイティブ・エーオーティー)』への完全対応だ」

後輩:「AOT? 最近ニュースでよく見ますけど、起動が爆速になるやつですよね? でも設定が難しそう……」

先輩:「いや、TUnit なら簡単だ。方法は 2 つある。好きな方を選べ」

方法A:XML を直接編集する(硬派な君へ)

先輩:「Visual Studio でプロジェクトファイル(.csproj)を開いて、この設定を追加するだけでいい」

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net9.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>

    <PublishAot>true</PublishAot>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="TUnit" Version="0.1.0" />
  </ItemGroup>
</Project>

方法B:Visual Studioの画面で設定する(UI 派の君へ)

後輩:「先輩、XML いじるのちょっと怖いです……。マウスでポチッとできませんか?」

先輩:「できるぞ。Visual Studio のプロパティ画面を使えばいい」

Visual Studio のプロパティ画面の設定

1. 右クリック: ソリューションエクスプローラーでプロジェクトを右クリックして 「プロパティ」 を選択。

2. 検索: 検索バーに 「AOT」 と入力する。

3. チェック: 「ネイティブ AOT の公開」 にチェックを入れる。
スクリーンショット 2026-04-09 142311.png

後輩:「おおっ! チェックを入れるだけ! これなら僕でも安心です!」

先輩:「従来のフレームワーク(xUnit など)は『リフレクション』を多用していたから AOT 化すると動かなくなることが多かった。だが TUnit は『Source Generator』でコンパイル時にコードを生成するから、AOT と相性抜群なんだ」

後輩:「つまり、これから僕たちが作るアプリがクラウドやコンテナで AOT 化されても、TUnit なら問題なくテストできるってことですね!」

先輩:「そういうことだ。.NET 10 時代のクラウドネイティブ開発において、これは大きなアドバンテージになる」

6-4.png
※ Native AOT では一部の動的機能(動的生成・一部のライブラリ)が制限されるため、利用ライブラリの対応状況は事前に確認しましょう。

5. エピローグ:テストは君を守る盾

後輩:「……終わりました。TUnit のインストールから始まって、Moq でのスタントマン、データ駆動テスト、そして Native AOT の設定まで。なんか、プログラマーとして少し強くなれた気がします」

先輩:「ああ。最初の頃、手動でポチポチ画面を操作していた頃とは顔つきが違うな」

後輩:「先輩、僕そろそろ今回の機能をリリースしてきます。いつもなら『バグが出たらどうしよう』って胃が痛くなるんですけど……今日は平気です」

先輩:「なぜだ?」

後輩:「だって、僕の後ろには数百人のスタントマン(テストコード)がいて、1秒で全部チェックしてくれてますから!

先輩:「……いい答えだ」

先輩:「いいか後輩。テストコードは、面倒な義務じゃない。 『未来の自分』と『チーム』を守るための最強の盾だ。この盾がある限り、エンジニアは何度でも大胆に挑戦できる。リファクタリングも、機能追加も、怖くない」

6-5.png

後輩:「はい! 行ってきます!」

先輩:「(……ふん、あいつも一人前になったな。さて、俺も自分のコードに await 付け忘れてないか見直すかw)」

【連載終了】これからのエンジニアへ

TUnit は、.NET 8 以降で利用でき、今後の .NET の進化を見据えたモダンな設計思想(非同期・並列・Source Generator・Native AOT)を先取りした次世代のフレームワークです。

この連載で紹介したテクニックは、TUnit に限らず、あらゆるテストフレームワークに通じる 「良いテストの書き方」 の基礎です。

良いテストの書き方

環境分離 : テストと本番を混ぜない。
依存分離 : Moq で外部依存を断ち切る。
データ駆動 : パターンを網羅する。
状態分離 : 並列実行に備えて Static を避ける。
未来志向 : .csproj またはプロパティ画面で AOT を有効化し、モダンな技術スタックを選ぶ。

さあ、あなたも今すぐ NuGet から TUnit をインストールして、爆速のテストライフを始めましょう!

(完)

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?