💯

VisualStudioCode + xUnit + テスト用の環境変数読み込み

2023/01/29に公開

.NET6のコンソールアプリ を ChromeBook にインストールしたVisualStudioCode(以下VSCode)を使って、C#で作成します。

また xUnit を使ってテストコードを書きます。

テスト時の構成は.runsettingsファイルに書いて、テスト実行時に環境変数として読み込むようにします。

この記事では VisualStudioCode + C# でコンソールアプリを作りながら、.runsettingsファイルでテスト用の環境変数を読み込むテストコードを書いていきます。

この記事の前提条件

  • ChromeBook で開発する
  • ChromeBook には VSCode がインストールされている
  • C#でコンソールアプリをつくる
  • テスティングフレームワークはxUnitを使う

VSCode と C# でコンソールアプリを作成する手順は、次の記事を参考にしてください。
https://zenn.dev/gatabutsu/articles/2157c6d2a665f8

この記事ではVSCodeでのテストの実行方法と、テスト用環境変数の読み込みを主目的として、xUnitの詳しい使い方については紹介しません。また、テスト駆動開発 (TDD) の一般的なアプローチについても無視します。

この記事でのディレクトリ構造

/dotnet-test-sample
    dotnet-test-sample.sln
    /SampleApp
        SampleApp.cs
        SampleApp.csproj	
    /SampleApp.Tests
        SampleAppTests.cs
        SampleApp.Tests.csproj
	test.runsettings

テスト対象のコンソールアプリ

テスト対象となるSampleApp.csは、以下のようなコードであるものとします。

SampleApp.cs
var app = ConsoleApp.Create(args);
app.AddCommands<Gohan.SampleApp.SampleApp>();
app.Run();

namespace Gohan.SampleApp
{
    public class SampleApp : ConsoleAppBase
    {
        [RootCommand]
        public void Main()
        {
            int answer = Sum(1,4);
        }

        public int Sum([Option(0)]int x, [Option(1)]int y)
        {
            return x + y;
        }
    }
}

テストの作成

テスト対象となる SampleApp プロジェクトは既に作成済のものとし、新たにテストプロジェクトを作成し、テストを追加していきます。

ソリューションの作成

まずは、ソリューションを作成しテスト対象のプロジェクトを、テストプロジェクトと関連付けます。

  1. ソリューションファイルをつくる
    VSCodeのターミナルでdotnet-test-sampleディレクトリを開き、以下のコマンド実行。同フォルダにソリューションファイルができます
dotnet new sln
  1. テスト対象のプロジェクトをソリューションに追加
    dotnet-test-sampleディレクトリで次のコマンドを実行して、テスト対象のプロジェクトをソリューションに追加します。
dotnet sln add ./SampleApp/SampleApp.csproj
  1. テストプロジェクトを作成
    同じくdotnet-test-sampleディレクトリで次のコマンドを実行して、テストプロジェクトを新たに作成します。
dotnet new xunit -o SampleApp.Tests

テストプロジェクトの中にはデフォルトでUnitTest1.csというファイルが作成されますが、今回は不要なので削除します。

  1. テスト対象のプロジェクトをソリューションに追加
dotnet sln add ./SampleApp.Tests/SampleApp.Tests.csproj
  1. SampleApp.Tests プロジェクトへの依存関係を追加
    テストプロジェクトへの依存関係として、テスト対象のプロジェクトを追加します。
dotnet add ./SampleApp.Tests/SampleApp.Tests.csproj reference ./SampleApp/SampleApp.csproj

テストコードを書いてテストを実行する

テスト対象のクラスをテストするためのテストクラスを「テスト対象クラス名+Tests」という名前で作成します。
ここではSampleApp.csをテストするためのSampleAppTests.csを、次のようなコードで作成します。

SampleAppTests.cs
using Gohan.SampleApp;

namespace Gohan.SampleApp.Tests
{
    public class SampleAppTests
    {
        [Fact]
        public void Sum_simpleValues_Calculated()
        {
            SampleApp sampleApp = new SampleApp();
            int actual = sampleApp.Sum(1,3);
            int expected = 4;
            Console.WriteLine($"SampleApp.Sum() expected={expected} actual={actual}");                        
            Assert.Equal(expected,actual);
        }   
    }
}

通常、このようなことをする必要はありませんが、動きの確認のために実行結果と期待値を変数にとりConsole.WriteLine()でログ出力しています。

ターミナルでSampleApp.Testsディレクトリを開きdotnet testコマンドでテストを実行します。両方のプロジェクトをビルドし、テストが実行されます。

dotnet test

ターミナルから実行しているのでConsole.WriteLine()の結果も表示されています。

(略)
SampleApp.Sum() expected=4 actual=4
Passed!  - Failed:     0, Passed:     1, Skipped:     0, Total:     1, Duration: < 1 ms - /dotnet-test-sample/SampleApp.Tests/bin/Debug/net6.0/SampleApp.Tests.dll (net6.0)

VSCodeからテストを実行する

VSCode上ではテストクラスにRun All TestsDebug All Testsが、テストメソッドにはRun TestDebug Testが追加されています。(表示されていない場合には、VSCodeを再起動すれば表示されます)

それぞれ、クリックすることでVSCodeからクラス単位でのテスト、メソッド単位でのテストを実行できます。Debugをクリックすれば、ステップ実行などもおこなえます。またConsole.WriteLine()の結果も、デバッグコンソールに出力されます。

ただし、Run Testをクリックした場合にはConsole.WriteLine()の結果は、テストエクスプローラーの出力(VSCode上では「出力」ウインドウ)に出力されません。

どうしてもログをテストエクスプローラー上で確認したい場合にはITestOutputHelperをDIして使用します。
https://xunit.net/docs/capturing-output

テスト用環境変数の読み込み

環境設定ファイル

テスト用のデータベース接続先などを環境設定ファイルなどに書きたい場合は.runsettingsファイルを作成します。VSCodeから利用する分にはファイル名は何でも構わないですが、VisualStudioから自動検出するときなどのためにも、拡張子は.runsettingsのほうが良いと思います。

通常、このようなことをする必要はありませんが、ここではSampleApp.Sum()への引数を環境設定ファイルに持つようにします。

test.runsettings
<?xml version="1.0" encoding="utf-8"?>
<RunSettings>
	<RunConfiguration>
		<EnvironmentVariables>
			<ArgsA>1</ArgsA>
			<ArgsB>3</ArgsB>
	    </EnvironmentVariables>
	</RunConfiguration>
</RunSettings>

環境変数の読み込み

環境変数の値はEnvironment.GetEnvironmentVariable()で読み込むことができます。Sum_simpleValues_Calculatedを次のように書き換えます。

SampleAppTests.cs
public void Sum_simpleValues_Calculated()
{
    SampleApp sampleApp = new SampleApp();
    string? argsA = Environment.GetEnvironmentVariable("ArgsA");
    string? argsB = Environment.GetEnvironmentVariable("ArgsB");
    Console.WriteLine($"GetEnvironmentVariable argsA={argsA} argsA={argsB}"); 
    int numA = Int32.Parse(argsA);
    int numB = Int32.Parse(argsB);
    Assert.Equal(4,sampleApp.Sum(numA,numB));
}

ただし、この状態でテストを実行しても環境設定ファイルを指定していないので、値を取ってくることはできずInt32.Parse()で例外が発生します。

環境設定ファイルを指定してテストの実行

ターミナルを開きdotnet testコマンドのパラメータで作成した環境設定ファイルを指定して、テストを実行します。今度はtest.runsettingに指定した環境変数が読み込まれ、テストが実行されます。

dotnet test --settings:./test.runsettings

ただし、毎回コマンドを入力するのも面倒ですし、この方法だとVSCode上に表示されたRun TestDebug Testなどから実行した場合には環境設定ファイルは読み込まれません。

VSCodeでC#の開発をおこなっている場合には、C#の拡張機能をインストールしていると思いますので、その設定で環境設定ファイルを指定します。

C#拡張機能で環境設定ファイルを指定する

VSCodeの設定からC#拡張機能の設定を開きTest Run Settingsに環境設定ファイルを指定します。Omnisharpでフィルタリングするとすぐに見つかります。
ここでは./SampleApp.Tests/test.runsettingsと指定します。

これで、VSCode上に表示されたRun TestDebug Testなどから実行した場合でも、環境設定ファイルが読み込まれるようになります。

拡張機能「.Net Core Test Explorer」を使用する場合

VSCodeの拡張機能「.Net Core Test Explorer」などを使用する場合でも同様で、拡張機能の設定で「Test Arguments」に--settings:./test.runsettingsと入力することで、環境設定ファイルが読み込まれます。

「.Net Core Test Explorer」でデバッグする場合には、実行したいテストを右クリックし「Debug Test」を実行します。

参考

Discussion