ちょっと作りたいアプリがあり、フロントどうしようかと。
VueやReact、どれも一から学習で、どれ使おうか迷っていたのですが、なんとなくBlazorにしてみようと
で、DevOpsに関することも学習していきたいので、単体テストも自動化したいと。
なので、書き方とか含めそもそもどうやって作っていくのかもが一緒に学習してみようと思っていまして
とりあえず、Visual Studioで作成されるBlazorのサンプル?アプリを題材に簡単な単体テストを作ってみようと
ChatGPTにおんぶにだっこで進める。
Blazor WebAssemblyの
ASP.NET Core Hostedなし(バックエンドなしのスタンドアロン)のやつを使いました。
既定でこんなのが作られる
実行したらこんな感じ
まずは、この"Click me"ボタンを押すとカウントアップしていくCounterページがシンプルっぽい気がするので、ここの単体テストを作ってみる
とりあえず、テストプロジェクトを追加したいので、ソリューションに新しいプロジェクトを追加。追加しない方法もあるっぽいが、いったんこれで。
いろんなテストプロジェクトがあるんだけど、どれがいいのかChatGPTに聞いたところ、Blazorアプリケーション専用のテストライブラリとして、bUnitというのがあり、bUnitはxUnit.netと組み合わせて使用されることが推奨されているとのこと。
ということでxUnitのテストプロジェクトを選択。
NuGetでbunitをインストール。
Preview版ではなく、なんとなく最新安定版の1.25.3を選択
テストプロジェクトからサンプルアプリが参照できるように、
サンプルアプリを参照追加
で、ChatGPTにテストコード作ってもらった
ボタンを1回押したらCurrent countが1になるかのテスト
using Bunit;
using YourApp.Components; // Counterコンポーネントが含まれている名前空間を使用
using Xunit;
public class CounterTests
{
[Fact]
public void CounterShouldIncrementWhenClicked()
{
// テストコンテキストのセットアップ
using var ctx = new TestContext();
// Counterコンポーネントのレンダリング
var cut = ctx.RenderComponent<Counter>();
// ボタンを見つける
var button = cut.Find("button");
// ボタンをクリックする
button.Click();
// 状態の検証
// クリック後にカウントが1増えているか確認
cut.Find("p").MarkupMatches("<p role=\"status\">Current count: 1</p>");
}
}
ちなみにAssertがないので、これって大丈夫なの?って質問をしたら、
MarkupMatches というメソッドが bUnit の機能の一つで、指定した期待値のマークアップと一致するかを検証する処理だからAssertと同じだよ。とのこと。ふーん。
// クリック後にカウントが1増えているか確認
cut.Find("p").MarkupMatches("<p role=\"status\">Current count: 1</p>");
ちなみにその<p role="status">の箇所はここ
これをUnitTest1.csに貼り付け。
using YourApp.Components;
の箇所をサンプルアプリのCounter.razorを読み込めるようにしないといけないんだけど、どう書けばいいのかわからんのでChatGPTに聞いてみると
using BlazorApp1.Pages;でいいっぽい。
コンパイル時にCounter.razorがクラスに変換され、Pagesが名前空間になるので、とのこと
では、テストを実行
お、一発で動いた。
試しにもうひとつテストを追加。これもChatGPTに作ってもらった。
ボタンを2回押したらCurrent countが2になるかのテスト
ご丁寧にAssert使ってくれた。
using Bunit;
using BlazorApp1.Pages; // Counterコンポーネントが含まれている名前空間を使用
using Xunit;
public class CounterTests
{
[Fact]
public void CounterShouldIncrementWhenClicked()
{
// テストコンテキストのセットアップ
using var ctx = new TestContext();
// Counterコンポーネントのレンダリング
var cut = ctx.RenderComponent<Counter>();
// ボタンを見つける
var button = cut.Find("button");
// ボタンをクリックする
button.Click();
// 状態の検証
// クリック後にカウントが1増えているか確認
cut.Find("p").MarkupMatches("<p role=\"status\">Current count: 1</p>");
}
[Fact]
public void CounterShouldIncrementTwiceWhenClickedTwice()
{
// Arrange
using var ctx = new TestContext();
var cut = ctx.RenderComponent<Counter>();
// Act
var button = cut.Find("button");
button.Click(); // First click
button.Click(); // Second click
// Assert
var paragraph = cut.Find("p[role='status']");
Assert.Equal("Current count: 2", paragraph.TextContent);
}
}
テストケースが2つに増えている。
とりあえず、なんとなくわかってきたので次に進もうと思う。