Visual Studio 2010 和测试驱动开发

Posted

技术标签:

【中文标题】Visual Studio 2010 和测试驱动开发【英文标题】:Visual Studio 2010 and Test Driven Development 【发布时间】:2010-05-16 17:33:25 【问题描述】:

我正在使用 Visual Studio 进行测试驱动开发的第一步。我有一些关于如何使用 VS 2010 实现泛型类的问题。

首先,假设我想实现我自己的 ArrayList 版本。 我首先创建以下测试(在本例中我使用的是 MSTest):

[TestMethod]
public void Add_10_Items_Remove_10_Items_Check_Size_Is_Zero() 
    var myArrayList = new MyArrayList<int>();

    for (int i = 0; i < 10; ++i) 
        myArrayList.Add(i);
    

    for (int i = 0; i < 10; ++i) 
        myArrayList.RemoveAt(0); //should this mean RemoveAt(int) or RemoveAt(T)?
                                 //VS doesn't know. Any work arounds?
    

    int expected = 0;
    int actual = myArrayList.Size;
    Assert.AreEqual(expected, actual);

我用的是VS 2010的能力打

ctrl + .

让它随时随地实现类/方法。

    在实现泛型类时遇到了一些麻烦。例如,当我定义一个.Add(10) 方法时,VS 不知道我是打算使用泛型方法(因为该类是泛型的)还是Add(int number) 方法。有什么办法可以区分吗? 同样的情况也可能发生在返回类型上。假设我正在实现一个MyStack 堆栈,并且我想测试在我推送和元素并弹出它之后,堆栈是否仍然是空的。我们都知道 pop 应该返回一些东西,但是通常,这个测试的代码不应该关心它。然后,Visual Studio 会认为 pop 是一种 void 方法,实际上这不是人们想要的。如何处理?对于每种方法,我是否应该首先进行“非常具体”的测试,例如很明显该方法应该返回一些东西,这样我就不会得到这种歧义?即使不使用结果,我应该有类似int popValue = myStack.Pop() 的东西吗? 我应该如何对泛型类进行测试?仅使用一种通用类型进行测试?我一直在使用ints,因为它们易于使用,但我是否也应该使用不同类型的对象进行测试?您通常如何处理这个问题? 我看到有一个名为 TestDriven for .NET 的流行工具。随着 VS 2010 的发布,它是否仍然有用,或者它的许多功能现在已经成为 VS 2010 的一部分,使其变得有点无用? 每当我在测试代码中定义一个新属性并要求 VS 为我生成该方法存根时,它都会生成一个 getter 和一个 setter。如果我有 int val = MyClass.MyProperty 之类的东西,我想了解(至少现在)我只想定义一个吸气剂。

谢谢

【问题讨论】:

对于#4,您是指从 Visual Studio 内部运行测试,还是一般运行测试? 如果您有 5 个独立的问题,将每个问题作为单独的问题发布不是让每个人的生活更轻松吗? 它们的主题差不多。 【参考方案1】:

我看到有一个名为 TestDriven for .NET 的流行工具。随着 VS 2010 的发布,它仍然有用吗,还是它的许多功能现在已经成为 VS 2010 的一部分,使其变得有点无用?

如果您使用多种不同的单元测试框架之一(nunit、mbunit、xunit、csunit 等),它仍然很有用。

还有其他工具(如 Visual Nunit)为运行单元测试提供 Visual Studio 集成。

【讨论】:

从我在 Channel9 上看到的,你也可以在 VS 2010 中使用几个框架。但我没有尝试过测试。 @devoured elysium:我已经让 Visual Studio 测试运行程序运行 NUnit 测试。您可能(或可能不会)遇到的 MSTest 问题是,如果您想要一个持续集成服务器(如 TeamCity 或 CruiseControl.NET),您将无法运行 MSTest 单元测试,而无需在服务器上安装 Visual Studio(其中有点烦人的要求)。 您是否有一篇关于如何使用 Visual NUnit 在 VS2010 内部运行 NUnit 测试的博文? :) 我遇到了一些问题,所以想研究其他选项。【参考方案2】:

对于你的代码示例,你为什么会有一个方法RemoveAt(T obj)

您可以改为使用RemoveAt(int index)Remove(T obj)。查看 Microsoft 的 API(例如,for List<T>),了解他们如何为通用集合设置 Remove 方法。

现在你的观点:

1:Add(int number) 会做什么?如果我正确理解您的意图,Add(10) 只能解释为“在我的收藏末尾添加值 10”。如果您想在特定索引处添加值,您可以(并且可能应该)将该方法命名为 Insert:Insert(int index, T value)

2:当然,Visual Studio 最初会将该方法解释为 void,但您可以将其编辑为类似

public class MyStack<T>

    public T Pop() 
    
    

Ctrl+. 构建的存根是一种方便,但不是福音。您不必总是为变量分配返回值。如果您在测试中不需要它,请不要这样做。如果您希望 VS 选择 void 以外的返回类型,您可以编写不同的单元测试(例如 Pop() 返回最后推送的值)。

3:我会使用我在代码中最常使用的类型进行测试。如果您正在编写公共 API,请使用尽可能多的类型进行测试。如果您使用的是 NUnit,请考虑使用 [TestCase] 属性来帮助您避免编写一些重复的代码。

4:我仍然使用 TestDriven,但我没有尝试过不使用它,所以我无法进行有用的比较。

5:如果不需要,只需删除 setter。 ReSharper 等一些插件框架支持更高级的代码生成,包括只读属性。

【讨论】:

重读问题。你完全偏离了重点。我想要一个 RemoveAt(int),但由于我使用的是 MyArrayList(),Visual Studio 不知道我想要实现哪种方法.. @devoured elysium:你的 MyArrayList 类是如何定义的?在这种情况下,不应该在实现哪种方法之间产生任何混淆,因为只有一个 RemoveAt() 并且它接受数组的索引。如果你想从列表中删除一个整数值,你可以使用 Remove() 代替。 我的问题主要与 VS 2010 存根生成功能有关,而不是关于如何开发类。无论如何,我想要一个 Add(T element) 和 RemoveAt(int index)。 好吧,我当然可以更改方法存根的返回类型,因为我也可以在不使用 VS 2010 存根生成功能的情况下手动实现所有功能。我只是想知道是否有避免额外工作的方法。 @devoured elysium:啊啊啊,我明白你的意思了。我不认为 Visual Studio 现在能够在您生成存根方法时了解您的类是通用的这一事实。不幸的是,调整这些类型必须是手动步骤,无论您是使用 int 或 string 还是任何其他类型的 T。

以上是关于Visual Studio 2010 和测试驱动开发的主要内容,如果未能解决你的问题,请参考以下文章

visual studio 2010可用的sqlite驱动程序(实体数据模型使用)

没有 TFS 的 Visual Studio 测试代理? (2010)

Visual Studio 2010 性能测试

有啥建议如何为像 Visual Studio 2010 测试这样的 NUnit 测试部署依赖项吗?

为 WCF 负载测试加载 UI Vs Visual Studio 2010 [关闭]

如何在 Visual Studio 2010 中设置单独的 Boost 测试项目