1

我有一个对象有很多我想测试的属性。我TestMethod为每个属性编写了一个,但问题是许多属性在设置时会操纵其他属性。我需要的是能够设置我的测试对象,操作其中一个变量,运行测试,将对象重置为其原始状态,然后重复该过程。这样,我就可以避免过多的冗余。

我研究过使用数据驱动方法(这是解决此问题的完美解决方案),但 Silverlight 测试框架似乎无法使用这种方法,因为我找不到使用该DataSource属性的方法。我想过尝试看看是否可以DataSource通过传统的 MSTest 框架访问,但可惜我只有 Visual Studio Express。

我曾想过尝试创建一个自定义测试工具,看看是否可以解决这个问题,但我想我会先四处寻求建议。

也许我应该把它吸起来,把所有不同的配置写成单独的TestInitialize方法,然后注释掉我不需要的那些。

任何帮助将不胜感激。

更新/澄清:

这是要测试的对象如何工作的示例。假设您有一个带有位置坐标和每边坐标的形状。当您更新位置或一侧的坐标时,所有其他坐标也必须更新。

这是正在测试的功能。我想做的是能够设置多个初始化(通过ClassInitialize或你有什么),我将设置我的对象的初始值和包含预期测试结果的模拟,然后更改有问题的属性之一。像这样的东西(这只是为了说明,所以请忽略任何不良做法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类来处理几乎所有的测试设置,因此我的MainPage(测试页)类中只需要一行。在 中TestManager,我添加了一个字符串变量,我TestSetup也从MainPage.

然后,我创建了另一个TestClass调用TestSetupClass并提供了两个静态字段:

private static Type childType;
private static TestSetupClass childInstance;

在它的构造函数中,我将底层类型与在 中指定的类名进行比较,TestManager并设置childTypeandchildInstance如果它们匹配:

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 回答