kazuk は null に触れてしまった

C# / .NET 系技術ネタ縛りでお送りしております

カテゴリーアーカイブ: Pex&Moles

Microsoft Code Digger をさっそくハックした


昨夜リリースされたばかりの Microsoft Code Digger をさっそくハックしてみました。

明け方の段階ではつかえねーコレだったのですが、ハックによってそこそこ使えるようになった感じです。

何ができる物ですか?

簡単に言えば Pex の低機能版です。一メソッドを選択し、コンテキストメニューから Generate Inputs / Outputs Table を行うとPexでの動作パスの列挙および、その動作パスに入るパラメータ値、そのパラメータでの呼び出し結果がリストアップされます。

    public class Class1
    {
        public int Test( int x,int y)
        {
            checked
            {
                return x/y;
            }
        }
    }

というTestAddを Generate Inputs/Outputs すると以下のように表示されます。

image

UI上ではそれだけです。これ以上の何もできません。

結果が気に入らなければコードを直せば良い、気に入ったならそのコードで良いんでしょ。別にすることないよねって鼻くそをホジってる感じです。

何ができない物ですか?

Code Digger 単体ではこのコードが将来に渡って同一の結果を返し続けるように保障する事はできません。

この一覧を元に単体テストを作って、ビルドサーバでそれを実行するようにすればそれはきっと実現する事ができるでしょう。Pexにはそれは備わっていましたが Code Digger には含まれません。

実際の所として現状追認のテストコードが一杯できるだけで、Pexでのテストコード生成は決して便利とは言いきれなかったのですが、それにしてもバッサリ切ってしまわれるとちょっとアレです。

カッとなってハックした

というわけで、Code Digger の出力をちょっと眺めてみたらテストコード自体は生成しているという事が解ったので、それを元に C# での単体テストコードを再構成する T4 テンプレートを書いてみました。

現物ファイルは gist にあります。

https://gist.github.com/kazuk/5449781

ファイルをダウンロードしたうえで Code Digger と組み合わせて使ってみましょう。

ポータブルクラスライブラリと単体テストのプロジェクトを作ります。

image

デフォルト名でビシバシひどいですが、こんなもんです。

足し算では単調すぎるので、割り算でやってみましょう。

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

namespace PortableClassLibrary1
{
    public class Class1
    {
        public int Test( int x,int y)
        {
            checked
            {
                return x/y;
            }
        }
    }
}

というコードに対して

image

という結果が得られました。

さっきの gist から取ってきたttを単体テストプロジェクトに突っ込みます。

最初の <#@ assembly #>の行を

<#@ assembly name=”$(SolutionDir)\PortableClassLibrary1\bin\Debug\PortableClassLibrary1.dll”#>

と書き換えて保存します。

普通に C# ソースが吐かれますが、一部エラーとなっているはずで、TODOコメントがいくらか出ていると思います。

// info PexFrameworkDir = C:\Users\kazuk\AppData\Local\Microsoft\VisualStudio\11.0\Extensions\z2qe4t0q.wnk
// TODO: add reference Microsoft.Pex.Framework.dll to this Project. path shown previous line

TODOの二つ目が上記内容です。どこにインストールされるかはちょっと予想がつかないので、パスが表示されています。ここにある Microsoft.Pex.Framework.dll を参照設定してください。(ソースコードを共有している場合に人様が自分のAppData\Local を参照できないとかで困らないようにソリューション内の適当な場所にコピーする等気は使って下さいね。)

これでエラーは消えるはずです。

もう一つのTODOである名前空間まで調整すれば特にもうする事はありません。

テストは生成されていますので、実行してみましょう。

image

もともとCode Digger で失敗したよと表示されているテストは失敗するように生成されました。

テストをいじったのにT4 から再生成されては意味がないので、ソースコードをまっとうなファイル名を付け替えて保存すれば完了です。

最後に例外で失敗してる所とかをそれを望むなら PexRaisedExceptionのtypeof通りに ExpectedException で想定通りと言い聞かせればいいでしょう。

注意事項

複数の Code Digger の結果が残ってると一気に生成するので生成メソッドが重複する事があります。bin\Debug配下にreportsとして結果は出ていますので、不要な物は適宜削除するか、さっくりデバッグしたい時などは名前空間を変える等で重複をごまかしておけば良いんじゃないかな。

まとめ

普通に使うにはちょっと機能不足な気もするけど、機能が無いならハックすれば良いじゃないで何とかなってみました。

Pex は楽しいツールなんでうまく使って下さい。ではでは!ハッピーな開発を!

Pex & Moles 0.94 をインストールしたらVS2008で csproj を読めなくなったっていう人に捧げます


2010/9/24 追記 0.94.1 がリリースされてました、それでは直ってるはずです(これから試します)

2010/9/24 追記 その2

Facebook 上で Pex and Moles Updated to 0.94.1: VS2008 registration issue and other little issues fixed… The MSDN download should be working again too… なんてアナウンスされていて、0.94.1 ってのが出るのかなと待っていたんですが、0.94のリビジョン違いでリリースされている模様です。

現在でmsdn subscriber downloadから落ちてくる en_visual_studio_2010_pex_0.94_power_tools_x64_587798.exe が0.94.1って事になりそうです。

Pex and Moles – Release Notes – Microsoft Research

v0.94.50921.0, 09/21/2010

Bug Fixes

  • Incorrect registration of MSBuild targets in Visual Studio 2008. The Moles MSBuild targets were not registered correctly for Visual Studio 2008.
  • Null Reference Exception when Assemblies could not be resolved. Moles would fail with a null reference when one of the dependent assembly was not resolved. Moles is still failing but with a nicer error message.

の最初の部分がこのblogで問題にした部分ですね。

中の人はこのblogでのパッチよりもうちっときれいな解決をしてますね。

<MolesBinPath Condition=”$(MolesBinPath) == ””>$(MSBuildThisFileDirectory)</MolesBinPath>

って事で同じディレクトリのを使えって形で変更されています。これで同様に直ってるはずって事で確認できましたのでみんな試してね!

お、64 bitマシンで開発してますね。えらい!、いまどきのサーバは64 bitしかないんだから、32 bit OSなんかで開発とかデバッグなんてできるわけねーよ、ですよね。

C:Program FilesMicrosoft Molesbin に置かれてる Microsoft.Moles.After.targets に原因が有ります。

オリジナルは以下の様になっています

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <!-- Begin Microsoft Moles -->
  <PropertyGroup Condition="'$(MolesImported)' != 'true'">
    <MolesInstallDir Condition="$(MolesInstallDir) == ''">$(ProgramFiles)Microsoft Moles</MolesInstallDir>
  </PropertyGroup>
  <Import Condition="'$(MolesImported)' != 'true'"
    Project="$(MolesInstallDir)binMicrosoft.Moles.targets"/>
  <!-- End Microsoft Moles -->
</Project>

VS2008は 32 bitプロセスなんで $(ProgramFiles) は C:Program Files (x86) になってしまい、隣にあるはずの Microsoft.Moles.targets の読み込みに失敗します。

PROCESSOR_ARCHITECTURE に応じて ProgramW6432 とProgramFiles の環境変数参照を切り替える様にします。

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <!-- Begin Microsoft Moles -->
  <PropertyGroup Condition="'$(MolesImported)' != 'true'">
    <MolesInstallDir Condition="$(MolesInstallDir) == '' And $(PROCESSOR_ARCHITECTURE)=='x86'">$(ProgramW6432)Microsoft Moles</MolesInstallDir>
    <MolesInstallDir Condition="$(MolesInstallDir) == '' And $(PROCESSOR_ARCHITECTURE)=='AMD64'">$(ProgramFiles)Microsoft Moles</MolesInstallDir>
  </PropertyGroup>
  <Import    Condition="'$(MolesImported)' != 'true'"
    Project="$(MolesInstallDir)binMicrosoft.Moles.targets"/>
  <!-- End Microsoft Moles -->
</Project>

#ぶっちゃけボンミスっぽいエラーだったりして、テスト支援ツール作っててこれは無いんじゃねーかなー、ちゃんとテストしてほしいなー>MSさま