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()
的东西吗?
我应该如何对泛型类进行测试?仅使用一种通用类型进行测试?我一直在使用int
s,因为它们易于使用,但我是否也应该使用不同类型的对象进行测试?您通常如何处理这个问题?
我看到有一个名为 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 2010 和测试驱动开发的主要内容,如果未能解决你的问题,请参考以下文章
visual studio 2010可用的sqlite驱动程序(实体数据模型使用)
没有 TFS 的 Visual Studio 测试代理? (2010)
有啥建议如何为像 Visual Studio 2010 测试这样的 NUnit 测试部署依赖项吗?