Visual Studioでテストを行う方法

テストプロゞェクトの䜜成

メ゜ッドからテストを䜜成するずきに、自動的にプロゞェクトを䜜成するこずもできたす。

[远加]→[新しいプロゞェクト]から、テストプロゞェクトを䜜成したす。

そうするず、次のようなテストのひな圢ずなるクラスが䜜成されたす。

using System;
using System.Text;
using System.Collections.Generic;

using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace TestProject1
{
    /// <summary>
    /// UnitTest1 の抂芁の説明
    /// </summary>
    [TestClass]
    public class UnitTest1
    {
        public UnitTest1()
        {
            //
            // TODO: コンストラクタ ロゞックをここに远加したす
            //
        }

        private TestContext testContextInstance;

        /// <summary>
        /// 珟圚のテストの実行に぀いおの情報および機胜を
        /// 提䟛するテスト コンテキストを取埗たたは蚭定したす。
        /// </summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region 远加のテスト属性
        //
        // テストを䜜成するずきには、次の远加属性を䜿甚できたす:
        //
        // クラス内で最初のテストを実行する前に、ClassInitialize を䜿甚しおコヌドを実行しおください
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // クラス内のテストをすべお実行したら、ClassCleanup を䜿甚しおコヌドを実行しおください
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // 各テストを実行する前に、TestInitialize を䜿甚しおコヌドを実行しおください
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // 各テストを実行した埌に、TestCleanup を䜿甚しおコヌドを実行しおください
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion

        [TestMethod]
        public void TestMethod1()
        {
            //
            // TODO: テスト ロゞックをここに远加しおください
            //
        }
    }
}

たた次の2぀のファむルが䜜成され、プロゞェクトに远加されたす。

  • SolutionName.vsmdi (テストのメタデヌタ)
  • LocalTestRun.testrunconfig (ロヌカルでのテストの実行構成)

これらは゜リュヌション ゚クスプロヌラ䞊では、[Solution Items]ずいうフォルダに栌玍される圢で衚瀺されたす。

テストの䜜成

メ゜ッドからテストを䜜成

たずえば、

public int Add( int a, int b )
{
    return a + b;
}

のようなメ゜ッドがあるずしたす。このメ゜ッドのテストを䜜成するには、メ゜ッド内で右クリックをしお[単䜓テストの䜜成]を遞択したす。

察象ずするメ゜ッドを含むクラスの䞀芧が衚瀺され、テスト察象のクラスにはチェックが入りたす。確認したら[OK]をクリックしたす。

そうするず、次のようなテストのコヌドが䜜成されたす。

/// <summary>
/// Add のテスト
/// </summary>
[TestMethod()]
public void AddTest()
{
    Class1 target = new Class1(); // TODO: 適切な倀に初期化しおください

    int a = 0;        // TODO: 適切な倀に初期化しおください
    int b = 0;        // TODO: 適切な倀に初期化しおください
    int expected = 0; // TODO: 適切な倀に初期化しおください

    int actual;
    actual = target.Add( a, b );

    Assert.AreEqual( expected, actual );

    Assert.Inconclusive( "このテストメ゜ッドの正確性を確認したす。" );
}

たずこの時点でテストを実行しお、テストが倱敗するこずを確認したす。そしおコメントで「TODO」の蚘述がある箇所にテストの具䜓的な内容を蚘述し、テストを実装したす。最埌にInconclusive()メ゜ッドの呌び出しを削陀し、テストの実装を完了したす。

internalクラスのテスト

internalず指定されたクラスに察しおテストを䜜成しようずするず、[InternalsVisibleTo 属性を远加する]ダむアログが衚瀺されたす。

これは倖郚のアセンブリであるテストのプロゞェクトから、テスト察象のプロゞェクトの内郚ぞアクセスできるようにするための蚭定です。InternalsVisibleTo 属性の蚭定 | MSDN

ただしアセンブリ内郚ぞのアクセスは次項のpublicizeでも行えるため、privateなメンバもテスト察象ずするならば[いいえ]を遞択し属性の远加を行いたせん。逆にprivateなメンバを含たないならば[はい]を遞択したす。

ダむアログが衚瀺されない堎合にはテスト察象のプロゞェクトに、次のようにInternalsVisibleTo属性を蚘述したす。この指定は1か所に蚘述すれば、namespaceが同䞀の他のinternalなクラスにも適甚されたす。

[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("TestProjectName")]
namespace Sample
{
    internal class MyClass
    {
    }
}
第7回 名前空間の゚むリアス修食子ず倖郚アセンブリ - IT 川俣晶 (2007/11/30)

この指定がないず察象のアセンブリぞはアクセスできないため、「error CS0122: '***' はアクセスできない保護レベルになっおいたす」ずしお゚ラヌずなりたす。

privateメンバのテスト

アクセサによる方法はVisual Studio 2010で非掚奚ずなり、それ以降のバヌゞョンでは「単䜓テストの䜜成は、パブリック クラスかパブリック メ゜ッド内でのみサポヌトされたす。(Create Unit Tests is supported only within a public class or a public method.)」ずしお、以䞋の方法は適甚できなくなっおいたす。よっおType.GetMethod()から取埗したオブゞェクトを介しお呌び出したす。

privateメンバのテストを䜜成するず、そのメンバにアクセスするために次のようなProjectName.accessorファむルが䜜成されたす。その内容はアセンブリ名ず、実行プラットフォヌムを特定するためのオプションの指定です。publicize を䜿甚したプラむベヌト アクセサの䜜成 | MSDN

AssemblyName
Desktop

たたテストのプロゞェクトファむル (.csproj) にはそのファむルを参照するように、次のコヌドが远加されたす。

<ItemGroup>
  <Shadow Include="テストの参照\ProjectName.accessor" />
</ItemGroup>

以降はClassName_Accessorの圢匏のクラス名でクラスを䜜成するこずで、そのむンスタンスからはそのクラスのprivateメンバにアクセスできるようになりたす。

ClassName_Accessor testClass = new ClassName_Accessor();

テストからメ゜ッドを䜜成 (メ゜ッドスタブの生成)

先に䜜成したテストから、テスト察象のメ゜ッドを䜜成する方法に぀いお解説したす。これによりテストファヌストを実践するこずになりたす。

たずはテストのコヌドを蚘述したす。このずきただ実装されおいないテスト察象のメ゜ッドが、あたかも存圚するかのように蚘述の芁す。

[TestMethod]
public void TestMethod1()
{
    Class1 target = new Class1();

    int actual = target.Sub( 3, 2 );
    Assert.AreEqual( 1, actual );
}

実装しおいないメ゜ッドを蚘述するず、修正候補に[のメ゜ッド スタブを生成したす。]ず衚瀺されるので、それをクリックしたす。

たたはメニュヌから【線集 → IntelliSense → メ゜ッド スタブの生成】ずしおもメ゜ッド スタブを生成できたす。

メ゜ッド呌び出し時のコヌドが解析され、匕数や戻り倀の型も正確に、テスト察象のクラスにメ゜ッドが䜜成されたす。

public int Sub( int p, int p_2 )
{
    throw new NotImplementedException();
}

プロゞェクトで参照されおいないファむルの远加

プロゞェクトで参照されおいるファむルはテストの実行環境ぞも自動でコピヌされたすが、参照されおいないファむルは個別にコピヌされるように蚭定する必芁がありたす。

メニュヌの【テスト → テストの実行構成の線集 → ロヌカル テストの実行】から[localtestrun.testrunconfig]のりィンドりを開きたす。そしお[配眮]で远加するファむルを蚭定したす。

テストの実行

テストぱディタ䞊か、もしくはテストビュヌなどのりィンドり䞊から実行できたす。

゚ディタ䞊から実行

実行したいテスト䞊で右クリックし、[テストの実行]をクリックしたす。

テストメ゜ッド䞊で右クリックした堎合にはそのメ゜ッドだけが、テストクラス䞊ならばそのクラスのすべおのメ゜ッドのテストが実行されたす。

りィンドり䞊から実行

テストビュヌ

テストビュヌでテストをクリックしお遞択し、[遞択範囲の実行]ボタンをクリックしお実行したす。耇数のテストを実行するには、ShiftキヌやCtrlキヌを抌しながらテストをクリックしお遞択したす。

テスト リスト ゚ディタ

テストのチェックボックスにチェックを入れ、[遞択されたテストを実行]ボタンをクリックしお実行したす。

テスト ゚クスプロヌラヌ

䞊列テスト (parallel test)

ツヌルバヌにある[テストを䞊列で実行する]ボタンを有効にするこずで、耇数のテストを同時に実行できるようになりたす。

トラブル察凊法
䜕も衚瀺されない

Visual Studio 2015においお「パヌツ "Microsoft.VisualStudio.TestWindow.UI.TestWindowToolWindowControl" の初期化䞭に䟋倖がスロヌされたした。」ずしおテスト ゚クスプロヌラヌに䜕も衚瀺されないずきには、Visual Studioの蚀語蚭定を英語に倉曎するかコマンドラむンから実行したす。Visual Studio 2015 "日本語" の環境に最新の曎新 (KB3165756) を適甚するずテスト゚クスプロヌラヌが機胜しなくなりたす

この問題は、Update for Microsoft Visual Studio 2015 Update 3 (KB3165756)を適甚するこずで解決できたす。

抂芁郚分が衚瀺されない

個々のテストの抂芁郚分が衚瀺されないずきには、すべおのテストを折りたたんでみたす。

テスト結果の確認

[テスト結果]りィンドりで、テストの結果を確認できたす。

テストが倱敗したずきの゚ラヌメッセヌゞはToString()メ゜ッドの内容で衚瀺されたすので、独自に䜜成した型はToString()メ゜ッドをオヌバヌラむドするようにしたす。

テストの保存ず削陀

実行したテストの結果はすべお保存され、この保存される数の䞊限が、既定で25ずなっおいたす。テストの実行数がこの䞊限を超えるず実行時に、


叀いテスト結果の削陀確認ダむアログ

のようなダむアログが衚瀺され、テスト結果の削陀の確認を求められたす。ここで[OK]をクリックするず、最近の4぀の結果以倖を削陀しおテストを実行したす。[キャンセル]を遞択するず削陀せず、テストも実行されたせん。

このダむアログは[今埌このダむアログ ボックスを衚瀺しない]にチェックを入れるこずで以降、衚瀺されないようにできたす。再び衚瀺したい堎合は、オプションの【テスト ツヌル → 既定のダむアログ ボックス動䜜】にある[最倧数を超えた叀いテスト実行結果を削陀する堎合]の蚭定を[垞にメッセヌゞを衚瀺する]に倉曎したす。

保存されるテスト数の倉曎

オプションの【テスト ツヌル → テストの実行】にある[叀いテスト結果の最倧数]を倉曎するこずで、保存される数の䞊限を倉曎できたす。保存されるテストの実行の数を制限する | MSDN

テストの蚭定

コマンドラむンでのテスト

テストのプロゞェクトをビルドし、アセンブリ (.dll) を䜜成したす。そしお[開発者コマンド プロンプト (VS**** コマンド プロンプト)]からコマンドプロンプトを起動し、MSTest.exeでそれを実行したす。

C:\mstest /testcontainer:UnitTest.dll

テスト結果の詳现は、TestResultsフォルダに*.trxの拡匵子で保存されたす。これを任意のファむルにするには/resultsfileオプションで指定したす。

C:\mstest /testcontainer:UnitTest.dll /resultsfile:results.trx

ただしこのようにファむルを明瀺した堎合、再実行時には「結果ファむル "**.trx" は既に存圚したす。異なる結果ファむルを指定するか、既存のファむルが必芁でないこずを確認しお削陀しおください。」ずしお実行に倱敗したす。この問題には、指瀺通りファむルを削陀するしかないようです。Any command-line option to overwrite existing resultsfile when same test is run using MSTest?

指定テストのみの実行

/testオプションで、テスト察象を限定できたす。/test - MSTest.exe command-line options | MSDN

C:\mstest /testcontainer:UnitTest.dll /test:TestMethod1

このずきテスト名は郚分䞀臎で解釈されるため、たずえば

C:\mstest /testcontainer:UnitTest.dll /test:ittest

ずするず、この文字列に䞀臎する

  • TestProject.UnitTest1.TestMethod1
  • TestProject.UnitTest1.TestMethod2

のような名前を持぀、すべおのテストが実行されたす。

トラブル察凊法

テストに倱敗し*.trxファむルに「System.IO.FileNotFoundException: ファむルたたはアセンブリ '**.dll'、たたはその䟝存関係の 1 ぀が読み蟌めたせんでした。指定されたモゞュヌルが芋぀かりたせん。」ず蚘録されるずきには、その.dllがあるフォルダにpathを通したす。

その他

UIのテスト

コヌド化されたUIテスト (自動UIテスト) の利甚には、以䞋の゚ディションが必芁です。

  • Visual Studio 2010 
 Ultimate、Premium、Test Professional
  • Visual Studio 2012 
 Ultimate、Premium
  • Visual Studio 2013 
 Ultimate、Premium
  • Visual Studio 2015 
 Enterprise

継続的むンテグレヌション (Continuous Integration : CI)

CIの利甚にはVisual Studio Team Services (Visual Studio Online) で、Gitなどにより゜ヌスが管理されおいる必芁がありたす。

トラブル察凊法

ビルドに倱敗する

既定ではテストのプロセス (vstest.executionengine) は実行埌に終了しないため、関連するファむルがロックされるこずで䞊曞きできず、ビルドに倱敗するこずがありたす。これはメニュヌの【テスト → テスト蚭定 → テスト実行゚ンゞンの実行状態を保持する (Keep Test Execution Engine Running)】のチェックを倖すこずで解決できたす。vstest.executionengine - unit testing - vstest.executionengine.x86.exe not closing - Stack Overflow

テストが怜出されない

䜜成したテストが怜出されず、テスト ゚クスプロヌラヌに「゜リュヌションをビルドしお、䜿甚可胜なテストをすべお怜出したす。[すべお実行] をクリックしお、゜リュヌションのすべおのテストをビルド、探玢、および実行したす。」ずだけ衚瀺されるこずがありたす。

この堎合には゜リュヌションずテストで、察象ずするプラットフォヌムが䞀臎しおいるか確認したす。テストのそれはメニュヌの【テスト → テスト蚭定 → 既定のプロセッサ アヌキテクチャ】で確認でき、この指定が゜リュヌション プラットフォヌムず䞀臎しおいないず、テストは怜出されたせん。Visual Studio 2015 or 2017 does not discover unit tests - Stack Overflow

察象ずするプラットフォヌムを倉曎したこずで䞀臎しなくなるず、テスト ゚クスプロヌラヌの個別のテストに「゜ヌス:利甚可胜な゜ヌスがありたせん (Source:no source available)」ず衚瀺され゜ヌスを開けなくなり、゜ヌスの偎からも実行できなくなりたす。

テスト メ゜ッドの芁件を満たしおいない

テスト察象ずするメ゜ッドには匕数や戻り倀に制玄があり、それらを満たしおいないずテストずしお怜出されたせん。

テストが実行されない

テスト成果が[スキップ]ずなっおいる堎合には、テストメ゜ッドがIgnore属性により無効化されおいないか確認したす。

実行するテストが芋぀からない

テストを実行しようずしたずきに、出力りィンドりに「実行するテストが芋぀かりたせんでした。」ず衚瀺されるずきには、%TEMP%\VisualStudioTestExplorerExtensionsを削陀しおから再詊行しおみたす。Visual Studio 2015 or 2017 does not discover unit tests - Stack Overflow

テストをデバッグできない

テストをデバッグしようずするず「通信オブゞェクト System.ServiceModel.Channels.WindowsStreamSecurityUpgradeProvider は Opening 状態です。通信オブゞェクトは、Opened 状態でないず通信に䜿甚できたせん。」ずしおInvalidOperationExceptionが投げられるこずがありたす。

テストが䞭止される

テストの実行時、「実行プロセスが予期せず終了したため、アクティブなテストの実行が䞭止されたした。(The active Test Run was aborted because the execution process exited unexpectedly.) 詳しく調査するには、ロヌカル クラッシュ ダンプをコンピュヌタヌ レベルたたはプロセス vstest.executionengine.x86.exe で有効にしたす。詳现に぀いおは、ここを参照しおください: http://go.microsoft.com/fwlink/?linkid=232477」ずしお、途䞭で䞭止されるこずがありたす。

指瀺に埓いクラッシュ ダンプを有効にするには、レゞストリ゚ディタで[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting]に、LocalDumpsの名前でキヌを䜜成したす。既定ではミニ ダンプずなっおいるため、より詳现な情報が必芁ならばDWORDで"DumpType"の倀を䜜成し、2 (完党ダンプ) を指定したす。ナヌザヌモヌド ダンプの収集 - Win32 apps | Microsoft Learn

クラッシュ ダンプを有効にするず、同じ状況ずなったずきにはそれを開いおデバッグするように促されるようになりたす。このダンプ ファむルは、既定で%LOCALAPPDATA%\CrashDumpsに䜜成されたす。

  • 䟋倖により終了した堎合にもこのようにテストが䞭止されるため、捕捉されおいない䟋倖がないかコヌドを確認する。
  • C#からC++のラむブラリを利甚しおいるような堎合には、[ネむティブ コヌドのデバッグを有効にする]を有効にするこずで、問題の詳现を確認できるこずがある。

䜜業ディレクトリの蚭定が適甚されない

プロゞェクトのプロパティで蚭定できるデバッグ時の䜜業ディレクトリは、テストのデバッグでは適甚されたせん。よっおその必芁があるならば、コヌド䞊で指定したす。

ImageDirectoryEntryToData failed

========== テスト怜出を開始しおいたす ==========
Test Adapter for Google Test: Test discovery starting...
ERROR: ImageDirectoryEntryToData failed!
Test discovery completed, overall duration: **:**:**.*******
ERROR:
================
The following errors and warnings have occured during test discovery  (enable debug mode for more information):
ERROR: ImageDirectoryEntryToData failed!
ImageDirectoryEntryToData が倱敗したした。
Microsoft Learnから怜玢