コードがカバーされていると表示されない理由は、非同期メソッドの実装方法に関係しています。C#コンパイラは、実際には非同期メソッドのコードをステートマシンを実装するクラスに変換し、元のメソッドを初期化してそのステートマシンを呼び出すスタブに変換します。このコードはアセンブリで生成されるため、コードカバレッジ分析に含まれます。
対象となるコードの実行時に完了していないタスクを使用する場合、コンパイラーによって生成されたステートマシンは、タスクの完了時に再開するために完了コールバックをフックします。これにより、ステートマシンコードがより完全に実行され、完全なコードカバレッジが実現します(少なくともステートメントレベルのコードカバレッジツールの場合)。
現時点では完了していないが、ある時点で完了するタスクを取得する一般的な方法は、単体テストでTask.Delayを使用することです。ただし、時間遅延が小さすぎる(テスト対象のコードが実行される前にタスクが完了することがあるため、コードカバレッジが予測できない)か、大きすぎる(テストの速度が不必要に遅くなる)ため、これは一般的に不適切なオプションです。
より良いオプションは、「await Task.Yield()」を使用することです。これはすぐに戻りますが、設定されるとすぐに継続を呼び出します。
もう1つのオプションは、多少ばかげていますが、継続コールバックがフックされるまでレポートが不完全であるというセマンティクスを持つ独自の待機可能なパターンを実装し、すぐに完了することです。これは基本的にステートマシンを非同期パスに強制し、完全なカバレッジを提供します。
確かに、これは完璧な解決策ではありません。最も不幸な点は、ツールの制限に対処するために製品コードを変更する必要があることです。コードカバレッジツールが、コンパイラによって生成された非同期ステートマシンの部分を無視することを強く望んでいます。しかし、それが起こるまで、本当に完全なコードカバレッジを取得しようとする場合、多くのオプションはありません。
このハッキングのより完全な説明はここで見つけることができます:http://blogs.msdn.com/b/dwayneneed/archive/2014/11/17/code-coverage-with-async-await.aspx