【Visual Studio 2017】[テスト実行]が急にできなくなるトラブルと復帰方法

# 概要
Visual Studio2017で発生した事象と復帰方法を紹介する。
なお、Visual Studio2017 + NUnitの組合せでが発生した事象の動画と復帰方法を説明する。

# 経緯
何度か本事象に遭遇した。体感で頻度は0.5~2時間に一度ぐらい。
Visual Studio2017の最新バージョン(15.9.36 。2021/05/28時点で最新)なら回避できるかを試した。
検証結果を情報共有するために記事にした。

# まとめ
先にまとめを示しておきます。

* ~~Visual Studio2017+NUnitの組合せ~~ Visual Studio2017で本事象は発生する。Visual Studio2019では本事象を修正済み。
　※訂正 2022/03/16 Visual Studio2017 + MSTestでも発生した。
* [Microsoft Developer Community][1]、[StackOverFlow][2]で同様の報告がされている。
* Visual Studioでは、テスト実行時に内部的に通信を行っており、[テストのデバック実行]と［デバックの中断］を繰り返すと、本事象が発生につながる。
* 復帰方法はVisual Studioを再起動すること。

# トラブルの内容
アクティブだったテストが急に実行できなくなる（下記動画を参照）。

![デバック実行できなくなる事象の再現動画.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156594/4923b0b3-7a66-306a-d66b-ec062eb7a774.gif)

補足説明をします。

* 事象が発生するまで「テストをデバック」を実行すると、ブレークポイントで止まっていた。<br>事象が発生すると、テスト関数まで到達しない。

* コンソール出力を確認すると、下記の例外が出力されている。
  例外のスタックトレースは[調査結果]に掲載する。

~~~
System.Reflection.TargetInvocationException: 呼び出しのターゲットが例外をスローしました。
 ---> System.IO.IOException: 転送接続にデータを書き込めません: 確立された接続がホスト コンピューターのソウトウェアによって中止されました。
---> System.Net.Sockets.SocketException: 確立された接続がホスト コンピューターのソウトウェアによって中止されました。
~~~

* テスト対象コードは単なる条件判定の関数である(下記を参照)。
　単純なコードで検証した。例外にSocketExceptionが出ているが、通信していない。

~~~~C#:テスト対象コード
    public class Foo
    {
        public bool Hoge(int a, int b)
        {
            if (a >= 0)
            {
                if (b >= 0) return true;
                Console.WriteLine("PASS1");
                return false;
            }
            Console.WriteLine("PASS2");
            return false;
        }
~~~~

テストコードは下記のとおり。特殊なことは一切していない。

~~~~C#:テストコード
    [TestFixture]
    public class TestFoo
    {
        [Test]
        public void TestHoge_False()
        {
            var foo= new Foo();
            Assert.IsFalse(foo.Hoge(-1, -2));
        }

        [Test]
        public void TestHoge_True()
        {
            var foo = new Foo();
            Assert.IsTrue(foo.Hoge(1, 2));
        }
    }
~~~~

# 復帰方法
事象が発生したら、Visual Studioを再起動する。


# 調査結果

* [Microsoft Developer Community][1]、[StackOverFlow][2]で同様の報告がされている。
例外内容、スタックトレース内容は同一。折りたたみで例外の詳細を掲載する。
<details><summary>例外の詳細</summary>
The active Tests Run was aborted.
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.IO.IOException: Unable to write data to the transport connection: An existing connection was forcibly closed by the remote host. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
   at System.Net.Sockets.Socket.Send(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
   at System.Net.Sockets.NetworkStream.Write(Byte[] buffer, Int32 offset, Int32 size)
   --- End of inner exception stack trace ---
   at System.Net.Sockets.NetworkStream.Write(Byte[] buffer, Int32 offset, Int32 size)
   at System.IO.BufferedStream.WriteByte(Byte value)
   at System.IO.BinaryWriter.Write(Byte value)
   at System.IO.BinaryWriter.Write7BitEncodedInt(Int32 value)
   at System.IO.BinaryWriter.Write(String value)
   at Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.SocketCommunicationManager.WriteAndFlushToChannel(String rawMessage)
   at M    icrosoft.VisualStudio.TestPlatform.CommunicationUtilities.SocketCommunicationManager.SendMessage(String messageType)
       at Microsoft.TestPlatform.VsTestConsole.TranslationLayer.VsTestConsoleRequestSender.AbortTestRun()
       at Microsoft.TestPlatform.VsTestConsole.TranslationLayer.VsTestConsoleWrapper.AbortTestRun() at Microsoft.VisualStudio.TestWindow.TestPlatformV2.ProxyRunRequest.Abort()
       at Microsoft.VisualStudio.TestWindow.TestPlatformV2.ProxyRunRequest.Dispose()
       at Microsoft.VisualStudio.TestWindow.Controller.Request.<RunRequests>d__95.MoveNext()
       --- End of inner exception stack trace ---
       at Microsoft.VisualStudio.TestWindow.Controller.Request.<ProcessRequest>d__94.MoveNext()
</details> 

* 報告事例を読んで分かったこと

| No | 分かったこと |
|:-|:-|
|  1 |Visual Studio 2019　V16.0.1で過去に発生していた 。<br>Visual Studio 2019は修正された。<br>  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156594/6ae62108-3789-551e-cd9d-8869bc065195.png)<br>([Microsoft Developer Community][1]から引用)|
| 2  | Visual Studio 2017で他の人も発生したと言っている。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156594/49e45002-b324-ee57-4b0e-9586d1c84768.png)<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156594/0068931c-1ead-b512-a3b8-c9565286847b.png)<br>|
| 3  | 一日に複数回の頻度で発生したという人もいる。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156594/d3d0809a-b8ac-c8bf-e318-5c1e8438a50b.png)|
|4   |[テストのデバック(Ctrl+R,Ctrl+T)]を押して、テストを中断することが関連している様子。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156594/423ac629-2de8-325b-7401-dbf2a9778404.png)<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156594/2b7a9799-be87-84ef-214e-b62d2a10d335.png)<br>|

# 検証方法
調査結果を踏まえて、下記手順を事象が発生するまで繰り返した。
1. [テストのデバック(Ctrl+R,Ctrl+T)]
2.［デバックの停止(Shift + F5)］

# 検証環境
## 開発環境
Visual Studio Community 2017(Version 15.9.36)
.NETFramework 4.6.2(C#を使用)
NUnit V3.13.2
NUnit3TestAdapter V3.17.0

## PC
Windows 10 Home 21H1 64bitOS
Intel Core i7-7700HQ CPU@2.80GHz
実装RAM 16.0GB


# 検証結果
153回(約40分）ほどで再現した。
検証作業以前に何度か遭遇しているため、再現確認は一度のみ。

事象再現時の通信状態を[TCPView][3]で確認した。
Visual Studioがテスト時に内部的に通信が発生している。何故かはわからないが、ソケットの処理でコケたってことだね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156594/ca7aad9a-e054-fd0c-f467-cbdd374ba738.png)


# 参考
[Microsoft Developer Community][1]
[StackOverFlow][2]
[TCPView][3]

[1]:https://developercommunity.visualstudio.com/t/unit-testing-issue-the-active-tests-run-was-aborte/496822
[2]:https://stackoverflow.com/questions/62779188/the-active-tests-run-was-aborted-system-reflection-targetinvocationexception
[3]:https://docs.microsoft.com/ja-jp/sysinternals/downloads/tcpview