環境構築から始めるテスト駆動開発 ~.NET開発環境を構築する~

## はじめに

これは [環境構築から始めるテスト駆動開発 ~ プログラミング環境の共通基盤を構築する ~](https://qiita.com/k2works/items/19d037814875b3a03eb3) の開発言語セットアップ記事です。Windows 10 Home で共通基盤が構築されていることを前提としています。

<!-- more -->

## インストール

スタートメニューから `Windows PowerShell` を選択します。

![](https://github.com/k2works/k2works.github.io/blob/source/docs/images/asciidoc/tdd_env/pkg-001.png?raw=true)

.NET 開発環境をインストールします。

```powershell
> scoop install dotnet-sdk
```

バージョンを確認しておきます。

```powershell
> dotnet -version
5.0.202
```

## Hello world

### プログラムを作成する

`Projects` フォルダ内に `dotnet` フォルダを作成してエディタからフォルダを開きます。

![](https://github.com/k2works/k2works.github.io/blob/source/blog/source/_posts/1617957275/001.png?raw=true)

`新しいターミナルを` を実行してターミナルに以下のコマンドを入力します。

![](https://github.com/k2works/k2works.github.io/blob/source/blog/source/_posts/1617957275/002.png?raw=true)

```powershell
dotnet new sln -o hello-dotnet
cd hello-dotnet
dotnet new classlib -o Program
dotnet sln add ./Program/Program.csproj
dotnet new xunit -o Program.Tests
dotnet sln add ./Program.Tests/Program.Tests.csproj
dotnet add ./Program.Tests/Program.Tests.csproj reference ./Program/Program.csproj
```

セットアップが完了したら `UnitTest1.cs` を開きます。
拡張機能インストールの案内が表示されるので `インストール` を押します。

![](https://github.com/k2works/k2works.github.io/blob/source/blog/source/_posts/1617957275/003.png?raw=true)

拡張機能インストールが終わると画面左下に .NET プロジェクト読み込みの確認メッセージが表示されるので `Yes` を押します。

![](https://github.com/k2works/k2works.github.io/blob/source/blog/source/_posts/1617957275/004.png?raw=true)

読み込みが完了したら `Run All Tests` と表示されるのでそこを押します。

![](https://github.com/k2works/k2works.github.io/blob/source/blog/source/_posts/1617957275/005.png?raw=true)

テストが実行されます。

![](https://github.com/k2works/k2works.github.io/blob/source/blog/source/_posts/1617957275/006.png?raw=true)

`.NET Core Test Explorer` 機能拡張を追加します。

![](https://github.com/k2works/k2works.github.io/blob/source/blog/source/_posts/1617957275/007.png?raw=true)

機能拡張のインストールが終わったらソリューション内のテストを読み込むため`hello-dotnet`フォルダを開きます。

![](https://github.com/k2works/k2works.github.io/blob/source/blog/source/_posts/1617957275/008.png?raw=true)

![](https://github.com/k2works/k2works.github.io/blob/source/blog/source/_posts/1617957275/009.png?raw=true)

サイドメニューの `テスト` からテストが実行できるようになります。

![](https://github.com/k2works/k2works.github.io/blob/source/blog/source/_posts/1617957275/010.png?raw=true)

`UnitTest1.cs` ファイルを以下のコードに書き換えます。

```csharp
using System;
using Xunit;

namespace Program.Tests
{
    public class UnitTest1
    {
        [Fact]
        public void 何か便利なもの()
        {
            Assert.Equal(true, false);
        }
    }
}
```

`Run All Tests` またはサイドメニューの `テスト`から実行ボタンを押してテストを実行します。

![](https://github.com/k2works/k2works.github.io/blob/source/blog/source/_posts/1617957275/011.png?raw=true)

テストをパスするようにコードを修正してプログラムを実行します。

```csharp
using System;
using Xunit;

namespace Program.Tests
{
    public class UnitTest1
    {
        [Fact]
        public void 何か便利なもの()
        {
            Assert.Equal(true, true);
        }
    }
}
```

![](https://github.com/k2works/k2works.github.io/blob/source/blog/source/_posts/1617957275/012.png?raw=true)

テスティングフレームワークの動作が確認できたので `helloWorld` メソッドの作成に入ります。まず以下のコードを追加して テストが失敗することを確認します。

```csharp
using System;
using Xunit;

namespace Program.Tests
{
    public class UnitTest1
    {
        [Fact]
        public void 何か便利なもの()
        {
            Assert.Equal(true, true);
        }

        [Fact]
        public void 簡単な挨拶を返す()
        {
            Assert.Equal("Hello from .NET", App.helloWorld());
        }
    }
}
```

![](https://github.com/k2works/k2works.github.io/blob/source/blog/source/_posts/1617957275/013.png?raw=true)

`App` クラスに `helloWorld` メソッドを 追加してテストをパスさせます。

```csharp
using System;
using Xunit;

namespace Program.Tests
{
    public class UnitTest1
    {
        [Fact]
        public void 何か便利なもの()
        {
            Assert.Equal(true, true);
        }

        [Fact]
        public void 簡単な挨拶を返す()
        {
            Assert.Equal("Hello from .NET", App.helloWorld());
        }
    }
}

class App
{
    public static String helloWorld()
    {
        return "Hello from .NET";
    }
}
```

![](https://github.com/k2works/k2works.github.io/blob/source/blog/source/_posts/1617957275/014.png?raw=true)

指定された名前で挨拶を返すようにします。

```csharp
using System;
using Xunit;

namespace Program.Tests
{
    public class UnitTest1
    {
        [Fact]
        public void 何か便利なもの()
        {
            Assert.Equal(true, true);
        }

        [Fact]
        public void 簡単な挨拶を返す()
        {
            Assert.Equal("Hello from .NET", App.helloWorld());
        }

        [Fact]
        public void 指定された名前で挨拶を返す() {
            Assert.Equal("Hello from VSCode", App.helloWorld("VSCode"));
        }
    }
}

class App
{
    public static String helloWorld()
    {
        return "Hello from .NET";
    }
}
```

![](https://github.com/k2works/k2works.github.io/blob/source/blog/source/_posts/1617957275/014.png?raw=true)

メソッドに引数を追加します。

```csharp
using System;
using Xunit;

namespace Program.Tests
{
    public class UnitTest1
    {
        [Fact]
        public void 何か便利なもの()
        {
            Assert.Equal(true, true);
        }

        [Fact]
        public void 簡単な挨拶を返す()
        {
            Assert.Equal("Hello from .NET", App.helloWorld());
        }

        [Fact]
        public void 指定された名前で挨拶を返す()
        {
            Assert.Equal("Hello from VSCode", App.helloWorld("VSCode"));
        }
    }
}

class App
{
    public static String helloWorld(String name)
    {
        return $"Hello from {name}";
    }
}
```

![](https://github.com/k2works/k2works.github.io/blob/source/blog/source/_posts/1617957275/016.png?raw=true)

ビルドエラー `'App.helloWorld(string)' の必要な仮パラメーター 'name' に対応する特定の引数がありません` が表示されています `簡単な挨拶を返す` に対応するメソッドが存在しないのでメソッドをオーバーロードしてテストをパスするようにします。

```csharp
using System;
using Xunit;

namespace Program.Tests
{
    public class UnitTest1
    {
        [Fact]
        public void 何か便利なもの()
        {
            Assert.Equal(true, true);
        }

        [Fact]
        public void 簡単な挨拶を返す()
        {
            Assert.Equal("Hello from .NET", App.helloWorld());
        }

        [Fact]
        public void 指定された名前で挨拶を返す()
        {
            Assert.Equal("Hello from VSCode", App.helloWorld("VSCode"));
        }
    }
}

class App
{
    public static String helloWorld()
    {
        return "Hello from .NET";
    }
    public static String helloWorld(String name)
    {
        return $"Hello from {name}";
    }
}
```

![](https://github.com/k2works/k2works.github.io/blob/source/blog/source/_posts/1617957275/017.png?raw=true)

仕上げに不要なテストを削除してテストケースの文言をわかりやすくしておきます。

```csharp
using System;
using Xunit;

namespace Program.Tests
{
    public class UnitTest1
    {
        [Fact]
        public void 何も指定されていない場合は既定の挨拶を返す()
        {
            Assert.Equal("Hello from .NET", App.helloWorld());
        }

        [Fact]
        public void 指定された名前で挨拶を返す()
        {
            Assert.Equal("Hello from VSCode", App.helloWorld("VSCode"));
        }
    }
}

class App
{
    public static String helloWorld()
    {
        return "Hello from .NET";
    }
    public static String helloWorld(String name)
    {
        return $"Hello from {name}";
    }
}
```

![](https://github.com/k2works/k2works.github.io/blob/source/blog/source/_posts/1617957275/018.png?raw=true)

### プログラムをデバッグする

まず確認したいプログラムの行を左部分を押してブレークポイント（赤丸）を設定します。

![](https://github.com/k2works/k2works.github.io/blob/source/blog/source/_posts/1617957275/019.png?raw=true)

ブレークポイントを設定したら `Debug All Tests` を押してプログラムの実行します。そうするとブレークポイント部分でプログラムが停止して変数などの情報が確認できるようになります。

![](https://github.com/k2works/k2works.github.io/blob/source/blog/source/_posts/1617957275/020.png?raw=true)

画面上の実行ボタンを押すと次のブレークポイントに移動します。

![](https://github.com/k2works/k2works.github.io/blob/source/blog/source/_posts/1617957275/021.png?raw=true)

デバッガを終了するには終了ボタンを押します。

![](https://github.com/k2works/k2works.github.io/blob/source/blog/source/_posts/1617957275/021.png?raw=true)

ブレークポイントを再度押すことで解除ができます。

![](https://github.com/k2works/k2works.github.io/blob/source/blog/source/_posts/1617957275/023.png?raw=true)

### プログラムをリポジトリに保存する

`新しいターミナル` を実行して以下のコマンドを入力します。

```powershell
> dotnet new gitignore
```

ソース管理を選択して `リポジトリを初期化する` を押します。

![](https://github.com/k2works/k2works.github.io/blob/source/blog/source/_posts/1617957275/023.png?raw=true)

`全ての変更をステージ` を選択します。

![](https://github.com/k2works/k2works.github.io/blob/source/blog/source/_posts/1617957275/025.png?raw=true)

変更内容に `feat: HelloWorld` と入力して `コミット` を押します。

![](https://github.com/k2works/k2works.github.io/blob/source/blog/source/_posts/1617957275/026.png?raw=true)

変更内容は `ソース管理` から確認できます。

![](https://github.com/k2works/k2works.github.io/blob/source/blog/source/_posts/1617957275/027.png?raw=true)

## GitHub に公開する

続いて、GitHub を使ってレポジトリを外部に公開できるようにしてみましょう。

まず、[GitHub](https://github.com/) でレポジトリを作成します。

ログインしたら画面右上の+マークから `New repository` を選択します。

![](https://github.com/k2works/k2works.github.io/blob/source/blog/source/_posts/1617957275/028.png?raw=true)

レポジトリ名は `hello-dotnet` として `Public` で公開します。 公開したくない場合は `Private` を選択します。
`Add a README file` にもチェックを入れておきます。
最後に `Create repository` を押して公開レポジトリを作成します。

![](https://github.com/k2works/k2works.github.io/blob/source/blog/source/_posts/1617957275/029.png?raw=true)

公開レポジトリが作成されたら VSCode から読み込めるようにするためリンク先の情報を取得します。

![](https://github.com/k2works/k2works.github.io/blob/source/blog/source/_posts/1617957275/030.png?raw=true)

クリップボードのアイコンをクリックするとレポジトリの URL がコピーできます。

![](https://github.com/k2works/k2works.github.io/blob/source/blog/source/_posts/1617957275/031.png?raw=true)

続いて VSCode に戻り、`表示` メニューから `コマンドパレット` を選択します。

![](https://github.com/k2works/k2works.github.io/blob/source/blog/source/_posts/1617957275/032.png?raw=true)

`clone` と入力して `Git クローン` を選択します。

![](https://github.com/k2works/k2works.github.io/blob/source/blog/source/_posts/1617957275/033.png?raw=true)

リポジトリの URL へ先ほどコピーした公開レポジトリの URL を貼り付けます。

![](https://github.com/k2works/k2works.github.io/blob/source/blog/source/_posts/1617957275/034.png?raw=true)

公開レポジトリの保存場所を指定する必要があるのでここでは `Projects` フォルダに `GitHub` フォルダを追加してそこに保存することにします。

![](https://github.com/k2works/k2works.github.io/blob/source/blog/source/_posts/1617957275/035.png?raw=true)

チェックアウトが終わると画面左下に通知が出ますので `開く` を押します。

![](https://github.com/k2works/k2works.github.io/blob/source/blog/source/_posts/1617957275/036.png?raw=true)

`新しいターミナル` を実行して以下のコマンドを入力します。

```powershell
$var = "Program"
$var_test = ${var} + "." + "Tests"
dotnet new gitignore
dotnet new sln -o .
dotnet new classlib -o ${var}
dotnet sln add ./${var}/${var}.csproj
dotnet new xunit -o ${var_test}
dotnet sln add ./${var_test}/${var_test}.csproj
dotnet add ./${var_test}/${var_test}.csproj reference ./${var}/${var}.csproj
```

準備ができましたので先ほどやった `HelloWorld` プログラムをもう一度作成して先ほどと同様にローカルレポジトリに保存します。

![](https://github.com/k2works/k2works.github.io/blob/source/blog/source/_posts/1617957275/037.png?raw=true)

ローカルレポジトリの内容を GitHub の公開レポジトリに登録します。`表示` メニューから `コマンドパレット` を選択します。

![](https://github.com/k2works/k2works.github.io/blob/source/blog/source/_posts/1617957275/038.png?raw=true)

`push` と入力して `Git プッシュ` を選択します。

![](https://github.com/k2works/k2works.github.io/blob/source/blog/source/_posts/1617957275/035.png?raw=true)

以下の GitHub 認証画面が表示された場合は `Sign in with your browser` を押します。

![](https://github.com/k2works/k2works.github.io/blob/source/blog/source/_posts/1617957275/040.png?raw=true)

`Authorize GitCrendtialManager` を押します。

![](https://github.com/k2works/k2works.github.io/blob/source/docs/images/asciidoc/tdd_env/ruby-win-github-014.png?raw=true)

GitHub アカウントのパスワードを入力します。

![](https://github.com/k2works/k2works.github.io/blob/source/docs/images/asciidoc/tdd_env/ruby-win-github-015.png?raw=true)

![](https://github.com/k2works/k2works.github.io/blob/source/docs/images/asciidoc/tdd_env/ruby-win-github-016.png?raw=true)

認証が完了してローカルレポジトリの内容が公開レポジトリに登録されました。

![](https://github.com/k2works/k2works.github.io/blob/source/blog/source/_posts/1617957275/041.png?raw=true)

内容が反映されているかをブラウザ画面から確認します。

![](https://github.com/k2works/k2works.github.io/blob/source/blog/source/_posts/1617957275/042.png?raw=true)