19

のような単体テストができるツールを探しています

IPerson p = new Person();
p.Name = "Sklivvz";
Assert.AreEqual("Sklivvz", p.Name);

対応するスタブ クラスとインターフェイスを自動的に生成する

interface IPerson         // inferred from IPerson p = new Person();
{
    string Name 
    { 
        get;              // inferred from Assert.AreEqual("Sklivvz", p.Name);
        set;              // inferred from p.Name = "Sklivvz";
    }
}

class Person: IPerson     // inferred from IPerson p = new Person();
{
    private string name;  // inferred from p.Name = "Sklivvz";

    public string Name    // inferred from p.Name = "Sklivvz";
    {
        get
        {
            return name;  // inferred from Assert.AreEqual("Sklivvz", p.Name);
        }
        set
        {
            name = value; // inferred from p.Name = "Sklivvz";
        }
    }

    public Person()       // inferred from IPerson p = new Person();
    {
    }
}

ReSharper と Visual Studio がこれらのいくつかを実行することは知っていますが、実行する必要があることを自動的に推測する完全なツール (コマンド ラインなど) が必要です。そのようなツールがない場合、どのように作成しますか (たとえば、ReSharper をゼロから拡張し、どのライブラリを使用しますか)?

4

11 に答える 11

4

必要と思われるのは、言語 (Java) のパーサーと、名前と型のリゾルバーです。(「シンボル テーブル ビルダー」)。

ソース テキストを解析した後、コンパイラには通常、名前の定義とそれに対応する型を記録しようとする名前リゾルバーと、各式が有効な型であることを検証する型チェッカーがあります。

通常、名前/型リゾルバーは、定義が見つからない場合に文句を言います。やりたいことは、問題の原因となっている「未定義」のものを見つけて、その型を推測することです。

為に

 IPerson p = new Person();

名前リゾルバーは、「Person」と「IPerson」が定義されていないことを認識しています。もしそうなら

 Foo  p =  new Bar();

インターフェイスが必要だったという手がかりはありません。単に Foo が Bar のある種の抽象的な親 (クラスやインターフェイスなど) であるというだけです。そのため、どちらであるかの決定は、ツールに認識されている必要があります (「そのような構造を見つけたときはいつでも、Foo がインターフェースであると想定してください...」)。ヒューリスティックを使用できます。IFoo と Foo は、IFoo がインターフェイスであることを意味し、誰かがそのインターフェイスを実現するクラスとして Foo を定義する必要があります。ツールがこの決定を下したら、シンボル テーブルを更新して、他のステートメントに進むことができるようにする必要があります。

為に

 p.Name = "Sklivvz";

p が (前の推論により) Interface でなければならないとすると、Name はフィールド メンバーである必要があり、その型は代入から String であることがわかります。

それで、ステートメント:

 Assert.AreEqual("Sklivvz", p.Name);

名前とタイプは、それ以上問題なく解決されます。

IFoo および Foo エンティティの内容は、あなた次第です。get と set を使用する必要はありませんでしたが、それは個人的な好みです。

同じステートメントに複数のエンティティがある場合、これはうまく機能しません。

 x = p.a + p.b ;

a と b がフィールドである可能性が高いことはわかっていますが、実際に数値であるか、文字列であるかを推測することはできません (これは Java の文字列では有効ですが、C# についてはわかりません)。C++ の場合、「+」が何を意味するかさえわかりません。Bar クラスの演算子である可能性があります。したがって、「a は不定の数または文字列」などの制約を収集する必要があり、ツールが証拠を収集するにつれて、可能な制約のセットが絞り込まれます。(これは、「ジョーには 7 人の息子がいます。ジェフはサムより背が高いです。ハリーはサムの後ろに隠れることができません。ジェフの双子は誰ですか?」という単語の問題と同じように機能します。ここでは、証拠を集めて不可能を取り除く必要があります)。また、矛盾が生じる場合も心配する必要があります。

p.a+pb のケースを除外することはできますが、単体テストを無罪で作成することはできません。免責が必要な場合は、標準の制約ソルバーがあります。(なんてコンセプト)。

OK、アイデアはありますが、これを実際に行うことはできますか?

この最初の部分では、パーサーと、曲げ可能な名前と型のリゾルバーが必要です。制約ソルバー、または少なくとも「定義された値が未定義の値に流れる」操作(自明な制約ソルバー)が必要です。

Java フロント エンドを備えたDMS ソフトウェア リエンジニアリング ツールキットは、おそらくこれを行うことができます。DMS は、コンピューター言語を任意の方法で処理するツールを構築したい人のためのツール構築ツールです。(「数値ではなくプログラムの断片で計算する」と考えてください)。

DMS は汎用の構文解析機構を提供し、与えられたフロント エンド (たとえば、Java と C# フロント エンド) のツリーを構築できます。私が Java を選んだ理由は、私たちの Java フロント エンドには名前と型の解決機構がすべてあり、それを曲げることができるようにソース形式で提供されているからです。自明な制約ソルバーに固執した場合は、おそらく Java 名前リゾルバーを曲げて型を把握できます。DMS を使用すると、コード フラグメントに対応するツリーを組み立てて、それらをより大きなツリーに結合できます。ツールがシンボル テーブルのファクトを収集すると、プリミティブ ツリーを構築できます。

どこかで、あなたは自分が終わったと決心しなければなりません。ツールがインターフェイス全体を認識する前に、何回の単体テストを確認する必要がありますか? (私はそれがあなたが提供するものをすべて食べると思いますか?)。完了すると、さまざまなメンバーのフラグメントがアセンブルされ、インターフェイスの AST が構築されます。DMS はその prettyprinter を使用して、お見せしたように AST をソース コードに戻すことができます。

私たちの Java フロントエンドには名前と型の解決があるので、ここでは Java をお勧めします。私たちの C# フロントエンドはそうではありません。これは野心の「単なる」問題です。誰かがそれを書かなければなりませんが、それはかなりの作業です (少なくともそれは Java の場合であり、C# が実際に異なるとは思えません)。

しかし、DMS を使用すると、原則としてこのアイデアはうまく機能します。

これは、パーサーと曲げ可能な名前と型のリゾルバーにアクセスできる他のインフラストラクチャを使用して行うことができます。C# の場合、これを実現するのはそれほど簡単ではないかもしれません。MS は、パーサーと、名前と型の解決へのアクセスを提供する可能性があると思いますが、それを変更する方法はありません。多分Monoが答えですか?

コード フラグメントを生成してアセンブルするには、引き続き was が必要です。文字列のハッキングによってこれを行うことができます。プログラムのビットを一緒に接着することに関する私の(長い)経験は、文字列でそれを行うと、最終的にそれを台無しにするということです。文法が許す方法でのみ結合できる既知のタイプのコードフラグメントを表す断片が本当に必要です。DMSはそれを行うため、混乱はありません。

于 2012-04-02T01:39:27.873 に答える
3

あなたが求めていたものに対して誰も実際に何も与えなかったのは驚くべきことです.

答えはわかりませんが、私の考えを述べます。

私がこのようなものを自分で書こうとすると、おそらく resharper プラグインについて目にするでしょう。私がそう言う理由は、あなたが言ったように、リシャーパーはそれを行うことができますが、個々のステップでできるからです. したがって、私は行ごとに何かを書き、適切なリシャーパー作成メソッドを連鎖して適用しました。

私はリシャーパー用に何も構築したことがないので、これを行う方法さえ知りませんが、それが私がやろうとしていることです。それができることは論理的に理にかなっています。

また、コードを作成する場合は、それを投稿してください。スケルトン全体を 1 つのステップで生成できるので、これも便利だと思います。非常に便利。

于 2008-09-27T09:47:28.623 に答える
1

独自の実装を作成する場合は、NVelocity (C#) またはVelocity (Java) テンプレート エンジンを検討することをお勧めします。

以前にコード ジェネレーターでこれらを使用したことがあり、作業が非常に簡単になることがわかりました。

于 2008-09-18T11:13:12.850 に答える
0

DevExpressのCodeRushが好きです。彼らは巨大なカスタマイズ可能なテンプレートエンジンを持っています。そして、私にとって最良の方法は、ダイアログボックスがないことです。また、存在しないインターフェイスからメソッドとインターフェイスおよびクラスを作成する機能もあります。

于 2008-09-20T10:06:09.037 に答える
0

あなたが探しているのは、ファジング ツール キット (https://en.wikipedia.org/wiki/Fuzz_testing) だと思います。

私が使ったことがないのは大変ですが、Randoop.NETに「単体テスト」を生成する機会を与えるかもしれませんhttp://randoop.codeplex.com/

于 2012-04-08T09:03:15.330 に答える
0

まだ研究中の Pex 、単体テストに関するマイクロソフトのプロジェクトを見てみてください

research.microsoft.com/en-us/projects/Pex/

于 2009-08-22T14:47:48.797 に答える
-1

Visual Studio には、ここで役立ついくつかの機能が付属しています。

メソッド スタブを生成します。存在しないメソッドへの呼び出しを記述すると、メソッド名に小さなスマート タグが付けられます。これを使用して、渡すパラメーターに基づいてメソッド スタブを生成できます。

あなたがキーボードの人なら(私はそうです)、閉じ括弧を入力した直後に、次のことができます:

  • Ctrl-. (スマートタグを開くため)
  • ENTER (スタブを生成するため)
  • F12 (定義に移動し、新しいメソッドに移動します)

スマート タグは、一致するメソッドがないと IDE が判断した場合にのみ表示されます。スマート タグが起動していないときに生成する場合は、Edit->Intellisense->Generate Method Stubに移動できます。

スニペット。共通コードのビットを簡単に生成できる小さなコード テンプレート。単純なものもあります ("if[TAB][TAB]" を試してください)。複雑なものもあります ('switch' は列挙型のケースを生成します)。自分で書くこともできます。あなたの場合は、「クラス」と「小道具」を試してください。

GMS のコンテキストでの情報スニペットについては、「「Generate Method Stub」を変更して NotImplementedException をスローする方法」も参照してください。

自動小道具。プロパティはもっと単純になる可能性があることに注意してください。

public string Name { get; set; }

クラスを作成します。ソリューション エクスプローラーで、プロジェクト名またはサブフォルダーを右クリックし、Add->Classを選択します。新しいクラスの名前を入力します。ENTERを押します。正しい名前空間などでクラス宣言を取得します。

インターフェイスを実装します。クラスにインターフェイスを実装する場合は、インターフェイス名の部分を記述し、スマート タグを有効にして、いずれかのオプションを選択してインターフェイス メンバーのスタブを生成します。

これらは、あなたが探している 100% 自動化されたソリューションではありませんが、適切な軽減策だと思います。

于 2008-09-18T14:57:14.170 に答える
-2

このようなコード生成ツールが必要なときはいつでも、おそらくもう少し汎用的にできるコードを書いているので、一度書くだけでよいことがわかりました。あなたの例では、これらのゲッターとセッターはコードに値を追加していないようです-実際、C#のゲッター/セッターメカニズムが機能していると主張しているだけです。

この種のテストを作成する動機が何であるかを理解する前に、そのようなツールを作成すること (または使用すること) を控えたいと思います。

ところで、あなたはNBehaveを見たいと思うかもしれませんか?

于 2008-09-18T11:09:49.253 に答える
-2

シンプルなスタブが必要な場合は、Rhino Mocks を使用します。

http://www.ayende.com/wiki/Rhino+Mocks+-+Stubs.ashx

于 2008-09-18T11:15:23.250 に答える