1

テストしたいプロパティがたくさんあるオブジェクトがあります。TestMethodプロパティごとにを記述しましたが、問題は、プロパティの多くが設定時に他のプロパティを操作することです。必要なのは、テストオブジェクトを設定し、変数の1つを操作し、テストを実行し、オブジェクトを元の状態にリセットしてから、プロセスを繰り返すことができるようにすることです。そうすれば、冗長性をあまり持たないようにすることができます。

DataSourceデータドリブンアプローチ(この問題の完璧な解決策)を使用することを検討しましたが、属性を使用する方法が見つからないため、Silverlightテストフレームワークでは使用できないようです。従来のMSTestフレームワークを介してにアクセスできるかどうかを確認しようと考えましたDataSourceが、残念ながら、私はVisualStudioExpressしか持っていません。

この問題を解決できるかどうかを確認するために、カスタムテストハーネスの作成を検討しようと考えましたが、最初に提案を求めたいと思いました。

たぶん、私はそれを吸い上げて、すべての異なる構成を別々のTestInitializeメソッドとして書き、必要のないものをコメントアウトする必要があります。

どんな助けでも大歓迎です。

更新/明確化:

テストするオブジェクトがどのように機能するかの例を次に示します。位置座標と各辺の座標を持つ形状があるとします。位置またはいずれかの辺の座標を更新するときは、他のすべての座標も更新する必要があります。

これはテスト中の機能です。ClassInitialize私がやりたいのは、オブジェクトの初期値と期待されるテスト結果を含むモックを設定し、問題のプロパティの1つを変更する、複数の初期化を(または何を使用して)設定できるようにすることです。このようなもの(これは説明のみを目的としているため、不適切な慣行xDは無視してください):

// class under test (mock has the same properties & constructor)
public class MySquare
{
    public Vector2 XYPosition;
    public int Width;
    public int Height;
    public float TopSidePosition;
    public float RightSidePosition;
    ...

    public MySquare(float x, float y, int width, int height)
    {
        // set up all properties
    }
}

// test object container
public class Container
{
    public static MySquare square;
    public static MySquareMock squareMock;
}

// desired test class initializations (it would be nice to be able to run each of these
// as well as the TestMethods and then reset to the next TestSetupClass)
[TestClass]
public class TestSetupClass1
{
    [ClassInitialize]
    public void SetupTest()
    {
        // set up initial value and expected result
        Container.square = new MySquare(0, 0, 5, 5);
        Container.squareMock = new MySquareMock(1, 1, 5, 5);

        Container.square.XYPosition = new Vector2(1, 1);
    }
}

[TestClass]
public class TestSetupClass2
{
    [ClassInitialize]
    public void SetupTest()
    {
        // set up initial value and expected result
        Container.square = new MySquare(0, 0, 5, 5);
        Container.squareMock = new MySquareMock(1, 0, 5, 5);

        Container.square.RightSidePosition = 6;
    }
}

// test methods
[TestClass]
public class TestMethods
{
    [TestMethod]
    public void TestPosition()
    {
        Assert.AreEqual(Container.squareMock.XYPosition, Container.square.XYPosition);
    }

    [TestMethod]
    public void TestTopSidePosition()
    {
        Assert.AreEqual(Container.squareMock.XYTopSidePosition, Container.square.TopSidePosition);
    }

    // test method for each property
}
4

1 に答える 1

0

当初の目標を達成するための完全に自動化された方法は見つかりませんでしたが、かなり簡単な方法を思いつきました。

最初に、ほぼすべてのテストセットアップを処理するシングルトンクラスを作成したので、 (テストページ)クラスTestManagerに必要なのは1行だけです。MainPage内に、からクラスTestManagerの名前も割り当てる文字列変数を追加しました。TestSetupMainPage

次に、別のTestClass呼び出しを作成しTestSetupClass、2つの静的フィールドを指定しました。

private static Type childType;
private static TestSetupClass childInstance;

そのコンストラクターで、基になる型をで指定されたクラス名と比較し、それらが一致する場合はTestManagerを設定しchildTypeます。childInstance

Type thisType = GetType().UnderlyingSystemType;

if (thisType.Name.Equals(TestManager.Instance.SetupClassName))
{
    childType = thisType;
    childInstance = this;
}

次に、属性TestSetupClassを持つに仮想メソッドを追加しました。AssemblyInitialize私のセットアップクラスはすべて、TestSetupClassこのメソッドを継承してオーバーライドします。メソッド内で、を使用して、子のオーバーライドされたメソッドの実装childTypeを取得し、 :MethodInfoを使用して呼び出します。childInstance

MethodInfo childSetup = childType.GetMethod("Setup");
childSetup.Invoke(childInstance, null);

そして出来上がり!すべてのテストを実行する前に特定のセットアップを実行する場合は、MainPageを使用してそのクラス名を指定するだけTestManagerです。

これを改善できた場所が他にもいくつかあることは知っていますが、うまくいくので、何ができるでしょうか。

于 2013-04-19T02:36:45.633 に答える