DebugTrace-net チュートリアル
DebugTraceについて
DebugTrace-javaチュートリアルを参照ください。
プロジェクト(C#)の作成
Visual Studio 2019(日本語サイト)を使用するのでインストールします。 Visual Studio 2019の言語が日本語の場合は、以下の内容を適宜日本語に置き換えてください。
- Visual Studio 2019を起動後に
Create a new project
をクリックします。(または[File]-[New]-[Project...]
を実行) - Create a new Projectダイアログが表示されるので、
Class Libraey (.NET Core)
を選択してNext
をクリックします。 - Configure your new projectダイアログが表示されるので、以下を入力して
Create
をクリックするとプロジェクトが作成されます。
Project name:Tutorial
Location: <任意>
Solution name:DebugTraceNetTutorial
▢ Place solution and project in the same directory - Solution ExplolerでTutorialプロジェクトのDependenciesのコンテキストメニュー(右ボタンでクリック)から
Manage Nuget Packeges...
を選択します。 - 生成されたソース(DebugTraceNetTutorial/Tutorial/
Class1.cs
)を削除し、Tutorialプロジェクト下にsrc
フォルダーを作成します。 [File]-[New]-[Project...]
を実行します。- Create a new Projectダイアログが表示されるので、
MSTest Test Project (.NET Core)
を選択してNext
をクリックします。 - Configure your new projectダイアログが表示されるので、以下を入力して
Create
をクリックするとテストプロジェクトが追加されます。
Project name:TutorialTest
Location: <変更なし>
Solution:Add to solution
Solution Name: <入力不可> - 生成されたソース(DebugTraceNetTutorial/TutorialTest/
UnitTest1.cs
)を削除し、TutorialTestプロジェクト下にsrc
フォルダーを作成します。 - TutorialTest/Dependenciesのコンテキストメニューから
Add Project Reference...
を選択し、Tutorialプロジェクトにチェックを入れ[OK]
をクリックします。
チュートリアル1
Tutorial/src下に以下のソースファイルを追加します。
パス: DebugTraceNetTutorial\Tutorial\src\Tutorial1.cs
using System.Text; namespace DebugTraceTutorial { public class Tutorial1 { public static int MaxLogByteArrayLength = 1024; /// <summary> /// バイト配列の文字列表現をStringBuilderに追加する。 /// </summary> /// <param name="builder">StringBuilder</param> /// <param name="bytes">バイト配列</param> /// <returns>引数のbuilder</returns> public static StringBuilder AppendBytes(StringBuilder builder, byte[] bytes) { builder.Append('['); var delimiter = ""; for (var index = 0; index < bytes.Length; ++index) { builder.Append(delimiter); if (index >= MaxLogByteArrayLength) { builder.Append("..."); break; } var value = bytes[index]; var ch = (char)(value / 16 + '0'); if (ch >= '9') ch += (char)('A' - '9' - 1); builder.Append(ch); ch = (char)(value % 16 + '0'); if (ch >= '9') ch += (char)('A' - '9' - 1); builder.Append(ch); delimiter = ", "; } builder.Append(']'); return builder; } } }
TutorialTest/src下に以下のソースファイルを追加します。
パス: DebugTraceNetTutorial\TutorialTest\src\Tutorial1Test.cs
using DebugTraceTutorial; using Microsoft.VisualStudio.TestTools.UnitTesting; using System.Text; namespace DebugtraceTutorial { [TestClass] public class Tutorial1Test { /** * appendBytesのテスト。 * @param bytes バイト配列 * @param expected StringBuilderに追加されると期待する文字列 */ [DataTestMethod] [DataRow(new byte[] {}, "[]")] [DataRow(new byte[] {1}, "[01]")] [DataRow( new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}, "[00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 0A, 0B, 0C, 0D, 0E, 0F]" )] [DataRow( new byte[] {0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF}, "[F0, F1, F2, F3, F4, F5, F6, F7, F8, F9, FA, FB, FC, FD, FE, FF]" )] public void TestAppendBytes(byte[] bytes, string expected) { // when var builder = Tutorial1.AppendBytes(new StringBuilder(), bytes); // then Assert.AreEqual(expected, builder.ToString()); } } }
テストを実行すると最初の2つの引数のテストは成功しますが、その後のテストでは失敗します。
テスト結果(最初の失敗):
Assert.AreEqual failed. Expected:<[00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 0A, 0B, 0C, 0D, 0E, 0F]>. Actual:<[00, 01, 02, 03, 04, 05, 06, 07, 08, 0@, 0A, 0B, 0C, 0D, 0E, 0F]>.
08, 0@, 0A
ではなく08, 09, 0A
となるのが正しいです。
DebugTrace-netを使用してみます。
プロジェクトにDebugTrace-netパッケージを以下の手順で追加します。
1. Solution Explorer
のTutorial/Dependecies
のコンテキストメニューからManage NuGet Package...
を選択します。
1. Brawse
をクリックし、DebugTrace
で検索して表示されたリストからDebugTrace
を選択してインストールします。
対象のメソッドとテストメソッドにDebugTrace-netのメソッドを呼び出すコードを挿入します。
using System.Text; using static DebugTrace.CSharp; // TODO: Delete after debugging namespace DebugTraceTutorial { public class Tutorial1 { public static int MaxLogByteArrayLength = 1024; /// <summary> /// バイト配列の文字列表現をStringBuilderに追加する。 /// </summary> /// <param name="builder">StringBuilder</param> /// <param name="bytes">バイト配列</param> /// <returns>引数のbuilder</returns> public static StringBuilder AppendBytes(StringBuilder builder, byte[] bytes) { Trace.Enter(); // TODO: Delete after debugging Trace.Print("bytes", bytes); // TODO: Delete after debugging builder.Append('['); var delimiter = ""; for (var index = 0; index < bytes.Length; ++index) { Trace.Print("index", index); // TODO: Delete after debugging builder.Append(delimiter); if (index >= MaxLogByteArrayLength) { builder.Append("..."); break; } var value = bytes[index]; Trace.Print("value", value); // TODO: Delete after debugging var ch = (char)(value / 16 + '0'); Trace.Print("1-1 ch", ch); // TODO: Delete after debugging if (ch >= '9') ch += (char)('A' - '9' - 1); Trace.Print("1-2 ch", ch); // TODO: Delete after debugging builder.Append(ch); ch = (char)(value % 16 + '0'); Trace.Print("2-1 ch", ch); // TODO: Delete after debugging if (ch >= '9') ch += (char)('A' - '9' - 1); Trace.Print("2-2 ch", ch); // TODO: Delete after debugging builder.Append(ch); delimiter = ", "; } builder.Append(']'); Trace.Leave(); // TODO: Delete after debugging return builder; } } }
using DebugTraceTutorial; using Microsoft.VisualStudio.TestTools.UnitTesting; using System.Text; using static DebugTrace.CSharp; // TODO: Delete after debugging namespace DebugtraceTutorial { [TestClass] public class Tutorial1Test { /** * appendBytesのテスト。 * @param bytes バイト配列 * @param expected StringBuilderに追加されると期待する文字列 */ [DataTestMethod] [DataRow(new byte[] {}, "[]")] [DataRow(new byte[] {1}, "[01]")] [DataRow( new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}, "[00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 0A, 0B, 0C, 0D, 0E, 0F]" )] [DataRow( new byte[] {0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF}, "[F0, F1, F2, F3, F4, F5, F6, F7, F8, F9, FA, FB, FC, FD, FE, FF]" )] public void TestAppendBytes(byte[] bytes, string expected) { Trace.Enter(); // TODO: Delete after debugging Trace.Print("bytes", bytes); // TODO: Delete after debugging Trace.Print("expected", expected); // TODO: Delete after debugging // when var builder = Tutorial1.AppendBytes(new StringBuilder(), bytes); // then Assert.AreEqual(expected, builder.ToString()); Trace.Leave(); // TODO: Delete after debugging } } }
もう一度テストを実行してみます。以下は上記を実行したログの一部です。ログはデフォルトで標準エラー(stderr)に出力されます。
Text Explorer
のTest Detail Summary
からOpen additional output for this result
をクリッすると出力内容を確認できます。
2020-11-22 12:03:32.798 [04] Enter DebugtraceTutorial.Tutorial1Test.TestAppendBytes(Byte[] bytes, String expected) (Tutorial1Test.cs:28) 2020-11-22 12:03:32.799 [04] | 2020-11-22 12:03:32.799 [04] | bytes = 2020-11-22 12:03:32.799 [04] | byte[16] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} (Tutorial1Test.cs:29) 2020-11-22 12:03:32.799 [04] | 2020-11-22 12:03:32.799 [04] | expected = 2020-11-22 12:03:32.799 [04] | (Length:64)"[00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 0A, 0B, 0C, 0D, 0 2020-11-22 12:03:32.799 [04] | E, 0F]" (Tutorial1Test.cs:30) 2020-11-22 12:03:32.800 [04] | Enter DebugTraceTutorial.Tutorial1.AppendBytes(StringBuilder builder, Byte[] bytes) (Tutorial1.cs:17) 2020-11-22 12:03:32.800 [04] | | 2020-11-22 12:03:32.800 [04] | | bytes = 2020-11-22 12:03:32.800 [04] | | byte[16] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} (Tutorial1.cs:18) 2020-11-22 12:03:32.800 [04] | | 2020-11-22 12:03:32.800 [04] | | index = 0 (Tutorial1.cs:22) 2020-11-22 12:03:32.800 [04] | | value = byte 0 (Tutorial1.cs:29) 2020-11-22 12:03:32.801 [04] | | 1-1 ch = '0' (Tutorial1.cs:31) 2020-11-22 12:03:32.801 [04] | | 1-2 ch = '0' (Tutorial1.cs:33) 2020-11-22 12:03:32.801 [04] | | 2-1 ch = '0' (Tutorial1.cs:36) 2020-11-22 12:03:32.802 [04] | | 2-2 ch = '0' (Tutorial1.cs:38) ... 2020-11-22 12:03:32.822 [04] | | index = 9 (Tutorial1.cs:22) 2020-11-22 12:03:32.822 [04] | | value = byte 9 (Tutorial1.cs:29) 2020-11-22 12:03:32.822 [04] | | 1-1 ch = '0' (Tutorial1.cs:31) 2020-11-22 12:03:32.824 [04] | | 1-2 ch = '0' (Tutorial1.cs:33) 2020-11-22 12:03:32.825 [04] | | 2-1 ch = '9' (Tutorial1.cs:36) 2020-11-22 12:03:32.826 [04] | | 2-2 ch = '@' (Tutorial1.cs:38) ...
バイト配列の9
の2桁目が'9'
であるはずが'@'
に間違って変換されています。
これはif (ch >= '9')
の判定が間違っているのでif (ch > '9')
に修正します。
修正後もう一度テストを実行すると成功します。ログの一部は以下になります。
2020-11-22 12:04:41.466 [05] | | index = 9 (Tutorial1.cs:22) 2020-11-22 12:04:41.466 [05] | | value = byte 9 (Tutorial1.cs:29) 2020-11-22 12:04:41.466 [05] | | 1-1 ch = '0' (Tutorial1.cs:31) 2020-11-22 12:04:41.468 [05] | | 1-2 ch = '0' (Tutorial1.cs:33) 2020-11-22 12:04:41.468 [05] | | 2-1 ch = '9' (Tutorial1.cs:36) 2020-11-22 12:04:41.468 [05] | | 2-2 ch = '9' (Tutorial1.cs:38)
デバッグの終了後にデバッグ用コードを削除するには、正規表現で検索して空文字列に置換します。改行コードも削除しているのでデバッグ用コードを挿入する前のソースに戻ります。
正規表現検索文字列: ^.+(Debug)?Trace\..*\r?\n
チュートリアル2
次のチュートリアルのソースとテストソースは以下です。
パス: DebugTraceNetTutorial\Tutorial\src\Tutorial2.cs
using System; using System.Collections.Generic; using System.Text; namespace DebugTraceTutorial { public class Tutorial2 { private static Dictionary<Type, string> shortNames = new Dictionary<Type, string>() { {typeof(void) , "void" }, {typeof(bool) , "bool" }, {typeof(sbyte) , "sbyte" }, {typeof(byte) , "byte" }, {typeof(short) , "short" }, {typeof(ushort), "ushort"}, {typeof(int) , "int" }, {typeof(uint) , "uint" }, {typeof(long) , "long" }, {typeof(ulong) , "ulong" }, {typeof(float) , "float" }, {typeof(double), "double"}, {typeof(decimal), "decimal"}, {typeof(char) , "char" }, {typeof(string), "string"}, }; /// <summary> /// 型名を返します。ただしSystem名前空間の場合は名前空間を取り除いて返します。 /// </summary> /// <param name="type">型</param> /// <returns>型名</returns> public static string GetName(Type type) { if (shortNames.ContainsKey(type)) return shortNames[type]; if (type.IsArray) return GetName(type.GetElementType()) + "[]"; var typeArguments = type.GenericTypeArguments; var backets = ("", ""); var isValueTuple = type == typeof(ValueTuple); if (typeArguments.Length > 0) backets = isValueTuple ? ("(", ")") : ("<", ">"); var builder = new StringBuilder(); if (!isValueTuple) { var typeName = type.Namespace == "System" ? type.Name : type.FullName; var backquoteIndex = typeName.IndexOf('`'); if (backquoteIndex >= 0) typeName = typeName.Substring(0, backquoteIndex); builder.Append(typeName); } builder.Append(backets.Item1); var delimiter = ""; foreach (var typeArgument in typeArguments) { builder.Append(delimiter).Append(GetName(typeArgument)); delimiter = ", "; } builder.Append(backets.Item2); return builder.ToString(); } } }
パス: DebugTraceNetTutorial\TutorialTest\src\Tutorial2Test.cs
using DebugTraceTutorial; using Microsoft.VisualStudio.TestTools.UnitTesting; using System; using System.Collections.Generic; using System.Data; namespace DebugtraceTutorial { [TestClass] public class Tutorial2Test { /** * GetNameのテスト。 * @param type 対象の型 * @param expected 予期する型名 */ [DataTestMethod] /* 1 */ [DataRow(typeof(string), "string")] /* 2 */ [DataRow(typeof(string[]), "string[]")] /* 3 */ [DataRow(typeof(string[][]), "string[][]")] /* 4 */ [DataRow(typeof(List<string>), "System.Collections.Generic.List<string>")] /* 5 */ [DataRow(typeof(List<string>[]), "System.Collections.Generic.List<string>[]")] /* 6 */ [DataRow(typeof((int, long)), "(int, long)")] /* 7 */ [DataRow(typeof(((byte, short), (int, long))), "((byte, short), (int, long))")] public void TestGetName(Type type, string expected) { // when var typeName = Tutorial2.GetName(type); // then Assert.AreEqual(expected, typeName); } } }
実行すると最初の5つで成功しますが、後の2つ(ValueTuple)では失敗します。
テスト結果(最初の失敗):
Assert.AreEqual failed. Expected:<(int, long)>. Actual:<ValueTuple<int, long>>.
デバッグコードを挿入しますが、メソッドが終了する箇所が3箇所あるため、Trace.Leave
メソッドの呼び出しをGetName
メソッドの最後に挿入だけでは不十分です。
この場合は、以下のようにします。
using System; using System.Collections.Generic; using System.Text; using static DebugTrace.CSharp; // TODO: Delete after debugging namespace DebugTraceTutorial { public class Tutorial2 { private static Dictionary<Type, string> shortNames = new Dictionary<Type, string>() { {typeof(void) , "void" }, {typeof(bool) , "bool" }, {typeof(sbyte) , "sbyte" }, {typeof(byte) , "byte" }, {typeof(short) , "short" }, {typeof(ushort), "ushort"}, {typeof(int) , "int" }, {typeof(uint) , "uint" }, {typeof(long) , "long" }, {typeof(ulong) , "ulong" }, {typeof(float) , "float" }, {typeof(double), "double"}, {typeof(decimal), "decimal"}, {typeof(char) , "char" }, {typeof(string), "string"}, }; /// <summary> /// 型名を返します。ただしSystem名前空間の場合は名前空間を取り除いて返します。 /// </summary> /// <param name="type">型</param> /// <returns>型名</returns> public static string GetName(Type type) { try {Trace.Enter(); // TODO: Delete after debugging Trace.Print("type", type); // TODO: Delete after debugging if (shortNames.ContainsKey(type)) return shortNames[type]; if (type.IsArray) return GetName(type.GetElementType()) + "[]"; var typeArguments = type.GenericTypeArguments; Trace.Print("typeArguments", typeArguments); // TODO: Delete after debugging var backets = ("", ""); var isValueTuple = type == typeof(ValueTuple); Trace.Print("typeof(ValueTuple)", typeof(ValueTuple)); // TODO: Delete after debugging Trace.Print("isValueTuple", isValueTuple); // TODO: Delete after debugging if (typeArguments.Length > 0) backets = isValueTuple ? ("(", ")") : ("<", ">"); Trace.Print("backets", backets); // TODO: Delete after debugging var builder = new StringBuilder(); if (!isValueTuple) { var typeName = type.Namespace == "System" ? type.Name : type.FullName; var backquoteIndex = typeName.IndexOf('`'); if (backquoteIndex >= 0) typeName = typeName.Substring(0, backquoteIndex); builder.Append(typeName); } builder.Append(backets.Item1); var delimiter = ""; foreach (var typeArgument in typeArguments) { builder.Append(delimiter).Append(GetName(typeArgument)); delimiter = ", "; } builder.Append(backets.Item2); return builder.ToString(); } finally {Trace.Leave();} // TODO: Delete after debugging } } }
テスト対象のメソッド全体をtry {Trace.Enter();
と} finally {Trace.Leave();}
で囲います。
テストメソッドの方はチュートリアル1と同様にします。
テストを実行すると以下のログ(失敗している部分)が出力されます。
2020-11-22 19:05:52.115 [04] Enter DebugtraceTutorial.Tutorial2Test.TestGetName(Type type, String expected) (Tutorial2Test.cs:27) 2020-11-22 19:05:52.115 [04] | 2020-11-22 19:05:52.115 [04] | type = 2020-11-22 19:05:52.115 [04] | System.RuntimeType System.ValueTuple`2[System.Int32,System.Int64] (Tutorial2Test.cs:28) 2020-11-22 19:05:52.115 [04] | 2020-11-22 19:05:52.115 [04] | expected = (Length:11)"(int, long)" (Tutorial2Test.cs:29) 2020-11-22 19:05:52.116 [04] | Enter DebugTraceTutorial.Tutorial2.GetName(Type type) (Tutorial2.cs:27) 2020-11-22 19:05:52.116 [04] | | 2020-11-22 19:05:52.116 [04] | | type = 2020-11-22 19:05:52.116 [04] | | System.RuntimeType System.ValueTuple`2[System.Int32,System.Int64] (Tutorial2.cs:28) 2020-11-22 19:05:52.118 [04] | | 2020-11-22 19:05:52.118 [04] | | typeArguments = System.Type[2] { 2020-11-22 19:05:52.118 [04] | | System.RuntimeType System.Int32, System.RuntimeType System.Int64 2020-11-22 19:05:52.118 [04] | | } (Tutorial2.cs:32) 2020-11-22 19:05:52.119 [04] | | 2020-11-22 19:05:52.119 [04] | | typeof(ValueTuple) = System.RuntimeType System.ValueTuple (Tutorial2.cs:35) 2020-11-22 19:05:52.119 [04] | | isValueTuple = false (Tutorial2.cs:36) 2020-11-22 19:05:52.120 [04] | | backets = ("<", ">") (Tutorial2.cs:40) 2020-11-22 19:05:52.120 [04] | | Enter DebugTraceTutorial.Tutorial2.GetName(Type type) (Tutorial2.cs:27) 2020-11-22 19:05:52.120 [04] | | | type = System.RuntimeType System.Int32 (Tutorial2.cs:28) 2020-11-22 19:05:52.121 [04] | | Leave DebugTraceTutorial.Tutorial2.GetName(Type type) (Tutorial2.cs:26) duration: 00:00:00.0003259 2020-11-22 19:05:52.121 [04] | | 2020-11-22 19:05:52.121 [04] | | Enter DebugTraceTutorial.Tutorial2.GetName(Type type) (Tutorial2.cs:27) 2020-11-22 19:05:52.124 [04] | | | type = System.RuntimeType System.Int64 (Tutorial2.cs:28) 2020-11-22 19:05:52.124 [04] | | Leave DebugTraceTutorial.Tutorial2.GetName(Type type) (Tutorial2.cs:26) duration: 00:00:00.0028577 2020-11-22 19:05:52.124 [04] | Leave DebugTraceTutorial.Tutorial2.GetName(Type type) (Tutorial2.cs:26) duration: 00:00:00.0085159
テストの最後のLeaveの出力がないのは、テストが失敗した場合は、途中で例外がスローされてテストメソッドのTrace.Leave()
が呼ばれないためです。そこでテストメソッドもtry {}
とfinally{}
を使用します。
using DebugTraceTutorial; using Microsoft.VisualStudio.TestTools.UnitTesting; using System; using System.Collections.Generic; using System.Data; using static DebugTrace.CSharp; // TODO: Delete after debugging namespace DebugtraceTutorial { [TestClass] public class Tutorial2Test { /** * GetNameのテスト。 * @param type 対象の型 * @param expected 予期する型名 */ [DataTestMethod] /* 1 */ [DataRow(typeof(string), "string")] /* 2 */ [DataRow(typeof(string[]), "string[]")] /* 3 */ [DataRow(typeof(string[][]), "string[][]")] /* 4 */ [DataRow(typeof(List<string>), "System.Collections.Generic.List<string>")] /* 5 */ [DataRow(typeof(List<string>[]), "System.Collections.Generic.List<string>[]")] /* 6 */ [DataRow(typeof((int, long)), "(int, long)")] /* 7 */ [DataRow(typeof(((byte, short), (int, long))), "((byte, short), (int, long))")] public void TestGetName(Type type, string expected) { try {Trace.Enter(); // TODO: Delete after debugging Trace.Print("type", type); // TODO: Delete after debugging Trace.Print("expected", expected); // TODO: Delete after debugging // when var typeName = Tutorial2.GetName(type); // then Assert.AreEqual(expected, typeName); } finally {Trace.Leave();} // TODO: Delete after debugging } } }
実行してみます。
2020-11-22 19:14:25.609 [04] Enter DebugtraceTutorial.Tutorial2Test.TestGetName(Type type, String expected) (Tutorial2Test.cs:27) 2020-11-22 19:14:25.609 [04] | 2020-11-22 19:14:25.609 [04] | type = 2020-11-22 19:14:25.609 [04] | System.RuntimeType System.ValueTuple`2[System.Int32,System.Int64] (Tutorial2Test.cs:28) 2020-11-22 19:14:25.609 [04] | 2020-11-22 19:14:25.609 [04] | expected = (Length:11)"(int, long)" (Tutorial2Test.cs:29) 2020-11-22 19:14:25.610 [04] | Enter DebugTraceTutorial.Tutorial2.GetName(Type type) (Tutorial2.cs:27) 2020-11-22 19:14:25.610 [04] | | 2020-11-22 19:14:25.610 [04] | | type = 2020-11-22 19:14:25.610 [04] | | System.RuntimeType System.ValueTuple`2[System.Int32,System.Int64] (Tutorial2.cs:28) 2020-11-22 19:14:25.612 [04] | | 2020-11-22 19:14:25.612 [04] | | typeArguments = System.Type[2] { 2020-11-22 19:14:25.612 [04] | | System.RuntimeType System.Int32, System.RuntimeType System.Int64 2020-11-22 19:14:25.612 [04] | | } (Tutorial2.cs:32) 2020-11-22 19:14:25.613 [04] | | 2020-11-22 19:14:25.613 [04] | | typeof(ValueTuple) = System.RuntimeType System.ValueTuple (Tutorial2.cs:35) 2020-11-22 19:14:25.614 [04] | | isValueTuple = false (Tutorial2.cs:36) 2020-11-22 19:14:25.614 [04] | | backets = ("<", ">") (Tutorial2.cs:40) 2020-11-22 19:14:25.614 [04] | | Enter DebugTraceTutorial.Tutorial2.GetName(Type type) (Tutorial2.cs:27) 2020-11-22 19:14:25.615 [04] | | | type = System.RuntimeType System.Int32 (Tutorial2.cs:28) 2020-11-22 19:14:25.615 [04] | | Leave DebugTraceTutorial.Tutorial2.GetName(Type type) (Tutorial2.cs:26) duration: 00:00:00.0003853 2020-11-22 19:14:25.615 [04] | | 2020-11-22 19:14:25.615 [04] | | Enter DebugTraceTutorial.Tutorial2.GetName(Type type) (Tutorial2.cs:27) 2020-11-22 19:14:25.619 [04] | | | type = System.RuntimeType System.Int64 (Tutorial2.cs:28) 2020-11-22 19:14:25.619 [04] | | Leave DebugTraceTutorial.Tutorial2.GetName(Type type) (Tutorial2.cs:26) duration: 00:00:00.0031286 2020-11-22 19:14:25.619 [04] | Leave DebugTraceTutorial.Tutorial2.GetName(Type type) (Tutorial2.cs:26) duration: 00:00:00.0090726 2020-11-22 19:14:25.622 [04] Leave DebugtraceTutorial.Tutorial2Test.TestGetName(Type type, String expected) (Tutorial2Test.cs:34) duration: 00:00:00.0128997
テストが失敗する原因は、type
がValueTuple
の場合は、true
になって欲しいvar isValueTuple = type == typeof(ValueTuple);
が原因なので、var isValueTuple = type.FullName.StartsWith("System.ValueTuple");
に修正します。
デバッグ終了後は、チュートリアル1と同様にデバッグ用コードを削除します。
まとめ
- チュートリアル1: デバッグコードを挿入する対象のメソッドの終了箇所が1箇所でかつ例外をスローしない場合
(または例外がスローされた場合にインデントが正しくなくても良い場合) - チュートリアル2: デバッグコードを挿入する対象のメソッドの終了箇所が複数か途中で例外をスローする可能性がある場合
以上でチュートリアルは終了です。