使用编码招式(Coding Katas)、BDD和VS2010项目模板

  通过编码招式和行为驱动开发,我受到了一些启迪,感觉良好。然而,当我意识到如果以后我就用这种方式编写单元测试、进行开发工作,那会相当痛苦,因为每次都要引入Eric Lee的ContextSpecification。如果我可以简单地选定一个BDD的单元测试项目,然后项目创建后我就拥有了所有项目所需的文件,那就容易多了。稍作查询之后,我找到了一些项目模板导出向导(Project Template Export Wizard)的参考资料,似乎这就是最适合我的解决方案。

  为了能试试这个例子,你要从Visual Studio Gallery上下载并安装Export Template Wizard(在Gallery站点上查询Export Template Wizard)。这是一个微软免费的Visual Studio扩展,可以将一个现有的项目导出成项目模板。

  在我们创建第一个模板前,先看看一些已有的模板,了解一下我们可能需要什么,这对我们来说是很重要的。

安装好Visual Studio后,它的模板位于以下目录:

\VisualStudioInstallationDirectory\Common7\IDE\ItemTemplates\Language\Locale\ \VisualStudioInstallationDirectory\Common7\IDE\ProjectTemplates\Language\Locale\

  例如,下面这个目录包含了英文版Visual Studio的项目模板:

C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\ItemTemplates\CSharp\1033\

  此外,当你安装一个模板的时候(通常通过双击.vsix文件——微软Visual Studio扩展文件),它会被安装到以下文件夹:

\User Documents and Settings Directory\Local Settings\Application Data\Microsoft\VisualStudio\10.0\Extensions

模板提示:

使用注册表编辑器,查看以下键,你会看到所有已安装的Visual Studio 2010扩展:

HKCU\Software\Microsoft\VisualStudio\10.0\ExtensionManager\EnabledExtensions

Visual Studio启动时会自动更新这里的注册项。如果我们删除掉某个扩展(比如,删除某个扩展的目录),Visual Studio下次启动时会更新注册表中的有关项。

  你会看到,所有模板的内容都存储在ZIP文件中,这有助于有条理地“把所有东西都放在一起”。当你检查这些ZIP文件时,你会注意到它们至少都包含一个.vstemplate文件,可以认为这就是模板的配置文件。

  考虑到我们的目的,我们对BasicUnitTest模板中的内容有所兴趣,此模板位于:

C:\Program Files\Microsoft Visual Studio 10.0\Common7

\IDE\ItemTemplates\CSharp\1033\BasicUnitTest.zip

  查看VS 2010中的现有模板时,会注意到在代码文件中(比如AssemblyInfo.cs),有一些特殊的关键字。在下面的代码示例中,高亮显示的文本说明了不同的模板参数关键字:

using System;

using System.Text;

using System.Collections.Generic;

$if$ ($targetframeworkversion$ == 3.5)using System.Linq;$endif$

$if$ ($targetframeworkversion$ == 4.0)using System.Linq;$endif$

using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace $rootnamespace$

{

[TestClass]

public class $safeitemname$

{

[TestMethod]

public void TestMethod1()

{

}

}

}

  关键字$rootnamespace$、$safeitemname$以及$safeprojectname$是保留的模板参数:

参数

描述

$rootnamespace$

当前项目的根命名空间。 在项目中添加新项时,此参数用来替换命名空间。

$safeprojectname$

在新建项目对话框中,用户输入的项目名(所有不安全的字符以及空格都会被移除)。

$safeitemname$

在添加新项对话框中,用户输入的名称(所有不安全的字符以及空格都会被移除)。

  查看关联的.vstemplate文件,我们可以看到引用代码文件的地方在ProjectItem元素里,而且ReplaceParameters属性的值被设置为true:

<TemplateContent>

...

<ProjectItem ReplaceParameters="true">UnitTest.cs</ProjectItem>

</TemplateContent>

  有了这些信息,模板向导就可以在指定文件中有效地搜索并替换所有的参数;如上例中的UnitTest.cs文件。简单地在.vstemplate文件中增加一个CustomParameter元素,就可以使用自定义参数了:

<TemplateContent>

...

<CustomParameters>

<CustomParameter Name="$TemplateParameter1$" Value="SomeValue"/>

<CustomParameter Name="$TemplateParameter2$" Value="SomeOtherValue"/>

</CustomParameters>

</TemplateContent>

  有了这些知识,我们可以把那些零散的东西放到一起,创建我们的BDD单元测试模板。

首先,我们要创建一个新项目,作为我们新项目模板的基础。根据我们的目的,最佳选项是单元测试项目:

创建好这个项目后,我们就有了构建新模板的基础(当然,这种方法适用于所有的项目类型,不光是单元测试项目)。

记住,制作
新的项目模板时,该项目中所有的东西都会被包括进去,因此现在我们可以引入所有所需的代码文件了(在我的例子中,是来自Eric Lee的ContextSpecification.cs):
添加所需的程序集引用作为我们项目模板的一部分,在我的例子中,我想使用MSpec程序集:

模板提示:

需要特别注意的是,在部署这个模板的机器上,需要安装上相同的程序集;因此你应该把引用限制在.NET framework提供的程序集上,或者在GAC中的程序集。这或许意味着,作为你模板的一部分,你必须创建一个安装程序,以便将某些程序集安装到GAC 中——或者要求用户自行安装所需的程序集。

我们要使用适当的模板参数(先前我们查阅过的$safeprojectname$)来替换代码文件中出现的命名空间名。同时,我在引用System.Linq的地方,放上了“版本保镖”(译注:只在指定版本的.NET Framework上输出代码块): using System;

using System.Text;

using System.Collections.Generic;

$if$ ($targetframeworkversion$ == 3.5)using System.Linq;$endif$$if$ ($targetframeworkversion$ == 4.0)

using System.Linq;$endif$

using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace $safeprojectname$

{

...

} 由于我们将在我们的测试类中使用ContextSpecification,我们要添加一个using声明,并使用适当的模板参数添加基类的定义(这里,我在后面加上了Context这个词,以此我们可以将它同派生测试类区别开来): using System;

using System.Text;

using System.Collections.Generic;

$if$ ($targetframeworkversion$ == 3.5)using System.Linq;$endif$$if$ ($targetframeworkversion$ == 4.0)

using System.Linq;

$endif$

using Microsoft.VisualStudio.TestTools;

using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace $safeprojectname$

{

public class $safeitemname$Context : ContextSpecification

{

/// <summary>

/// The "Given some initial context" method

/// </summary>

protected override void Context()

{

// setup your class under test

}

}

...

} 下一步是重新定义代码文件中的测试类,让它继承于我们
刚刚增加的Context基类。我在这里使用的代码,来自于本文先前描述的保龄球招式解决方案,并用
合适的模板参数替换了类名和方法名。 /// <summary>

/// Summary description for $safeitemname$

/// </summary>

[TestClass]

public class $safeitemname$ : $safeitemname$Context

{

/// <summary>

/// The "When an event occurs" method

/// </summary>

protected override void BecauseOf()

{

//

// TODO: Add behavior setup (Action) here

//

}

/// <summary>

/// The "then ensure some outcome" method.

/// </summary>

[TestMethod]

public void TestMethod1()

{

//

// TODO: Add test logic here

//

}

} 对于文件AssemblyInfo.cs,我们要针对我们创建的项目,替换其中的一些引用(比如程序集的名字等等),然而这次我们可以从现存的模板“定义” 中拷贝已有的AssemblyInfo(我使用“C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\ProjectTemplates\CSharp\Test\1033\TestProject.zip”)到我们的项目中。 using System.Reflection;

using System.Runtime.CompilerServices;

using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following

// set of attributes. Change these attribute values to modify the information

// associated with an assembly.

[assembly: AssemblyTitle("$projectname$")]

[assembly: AssemblyDescription("")]

[assembly: AssemblyConfiguration("")]

[assembly: AssemblyCompany("$registeredorganization$")]

[assembly: AssemblyProduct("$projectname$")]

[assembly: AssemblyCopyright("Copyright ?? $registeredorganization$ $year$")]

[assembly: AssemblyTrademark("")]

[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible

// to COM components. If you need to access a type in this assembly from

// COM, set the ComVisible attribute to true on that type.

[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM

[assembly: Guid("$guid1$")]

// Version information for an assembly consists of the following four values:

//

// Major Version

// Minor Version

// Build Number

// Revision

//

// You can specify all the values or you can default the Build and Revision Numbers

// by using the '*' as shown below:

[assembly: AssemblyVersion("1.0.0.0")]

[assembly: AssemblyFileVersion("1.0.0.0")] 现在我们准备运行Template Export Wizard,选择文件->将模板导出为VSIX…:
这会打开“将模板导出为VSIX”向导对话框,在这个对话框里,我们可以选择创建一个项目模板(从解决方案中的项目),或者创建一个新项模板(从所选项目或解决方案中的某个文件)——为了导出一个项目模板,我们选择解决方案中唯一的项目。单击下一步>:
在向导的下一个界面里,我们可以设置在Visual Studio的“新建项目”对话框中,如何显示这个模板。适当
填写一些字段并单击下一步>:

模板提示:

假如不填写“图标图片”和“预览图片”这两个字段,向导会自动帮你生成图片,你可能会不喜欢这些图片(看起来像代码窗口的快照——缩小了的)。建议你创建你自己的图片,并在这两个字段中引用你的图片。
在本例中,我准备了下面这种尺寸的图片(大小与向导生成的图片一致):

在下一个窗口里,填写好“产品细节”,我们就完成了所有选项。尤其需要注意模板的输出目录,以及对话框底下的两个复选框。

当你单击完成按钮的时候,VSIX文件会生成到输出目录。

复选框“自动将模板导入Visual Studio”会指示向导是否在导出模板后安装模板——取决于你想如何创建你的模板, 你可以酌情考虑是否勾选上这一项。眼下我让它勾选上,因为我想马上看到结果。

如果你没有记下输出路径,那就有必要勾选上“在资源管理器窗口中显示输出文件目录”——我个人喜欢选上这一项。填写相应的字段并单击完成:
一旦完成这个过程,打开新建项目对话框(要么通过菜单文件->新建->项目,要么通过按下CTRL + Shift + N)并选择Visual C#项目类型,你会找到新建的BDD Unit Test项目:
创建一个BDD Unit Test类型的项目,并打开UnitTest1.cs文件。你会发现从类名继承的模板参数(unittest1Context and unittest1)是小写的,在我看来这不太理想: using System;

using System.Text;

using System.Collections.Generic;

using System.Linq;

using Microsoft.VisualStudio.TestTools;

using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace BDDUnitTest1

{

public class unittest1Context : ContextSpecification

{

...

}

/// <summary>

/// Summary description for unittest1

/// </summary>

[TestClass]

public class unittest1 : unittest1Context

{

...

}

} 回顾一下Visual Studio扩展文件(.vsix)的格式,我们可以将项目模板导出向导生成的文件重新命名成.ZIP文件:


打开这个ZIP文件,我们会看到以下这种结构;内部的zip文件(在下面例子中是 - BddUnitTest.zip)是我们所关心的,因此在合适的位置解压缩重命名的zip文件:
解压缩所有的相应的ZIP文件,使用Visual Studio“以…方式打开”的功能打开.vstemplate文件(当提示编辑器类型时选择XML(文本)编辑器):

在Visual Studio的XML编辑器中打开.vstemplate文件,你会注意到每个文件对应的ProjectItem元素的TargetFileName属性都是小写的,尽管实际的文件名使用的是骆驼命名法: <?xml version="1.0"?>

<VSTemplate xmlns:xsi="http://www.w3.org/2001/XMLSchema-

instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"Type="Project" Version="3.0.0" xmlns="http://sc

hemas.microsoft.com/developer/vstemplate/2005">

<TemplateData>

<Name>BDD Unit Test</Name>

<Description>A Test project based on Behavior Driven Development (BDD) principles</Description>

<Icon>__Template_small.png</Icon>

<PreviewImage>__Template_large.png</PreviewImage>

<ProjectType>CSharp</ProjectType>

<ProjectSubType />

<SortOrder>1000</SortOrder>

<DefaultName>BDDUnitTest</DefaultName>

<ProvideDefaultName

时间: 2024-07-30 09:58:26

使用编码招式(Coding Katas)、BDD和VS2010项目模板的相关文章

一起谈.NET技术,使用编码招式(Coding Katas)、BDD和VS2010项目模板

通过编码招式和行为驱动开发,我受到了一些启迪,感觉良好.然而,当我意识到如果以后我就用这种方式编写单元测试.进行开发工作,那会相当痛苦,因为每次都要引入Eric Lee的ContextSpecification.如果我可以简单地选定一个BDD的单元测试项目,然后项目创建后我就拥有了所有项目所需的文件,那就容易多了.稍作查询之后,我找到了一些项目模板导出向导(Project Template Export Wizard)的参考资料,似乎这就是最适合我的解决方案. 为了能试试这个例子,你要从Visu

使用编码招式(Coding Katas)、BDD和VS“.NET研究”2010项目模板

通过编码招式和行为驱动开发,我受到了一些启迪,感觉良好.然而,当我意识到如果以后我就用这种方式编写单元测试.进行开发工作,那会相当痛苦,因为每次都要引入Eric Lee的ContextSpecification.如果我可以简单地选定一个BDD的单元测试项目,然后项目创建后我就拥有了所有项目所需的文件,那就容易多了.稍作查询之后,我找到了一些项目模板导出向导(Project Template Export Wizard)的参考资料,似乎这就是最适合我的解决方案. 为了能试试这个例子,你要从Visu

蚂蚁金服技术专家总结:性能优化的常见招式

本文主要会介绍性能评估的一些简单概念以及性能压测/性能瓶颈的识别方法和一些常见的优化方式.虽然内容很多,但是目的在于让大家有个全局的认识:本文虽然深入度上面稍微欠缺,但是足以应对日常的性能分析. 为什么大家觉得性能优化难? 很多人觉得性能优化难的原因,其实主要是不知道怎么去做评估,主要表现在一下几个方面 1.不知道性能是什么? 2.不知性能的评估标准是什么? 3.不知道影响性能的相关元素是什么? 4.不知道性能问题的带来的现象是什么? 性能优化,必须知道的几个概念 关于性能的几个基础概念就像一把

《GRANAGE》韩国终测登场强调动感打击招式

韩国 NHN 上周五宣布,旗下 2D 横向滚动条动作角色扮演游戏<GRANAGE>将于 12 月 2 日在韩国展开最终测试,并释出最终测试宣传影片,展现游戏实际内容. 由 Logiware 研发的<GRANAGE>最终测试,是研发团队历经第二次封闭测试后接受了玩家多样化 意见.加以进化后所推出的游戏内容,此次最终测试将针对游戏的稳定性与新内容,于 12 月 2 日至 5 日在韩国举行. <GRANAGE>结合可爱的角色风格.动态视觉表现打击感与招式特效,让玩家可以依照战

中国富豪挖掘第一桶金九招式

中国富豪挖掘第一桶金的方法不下50种 据<科学投资>研究,中国富豪挖掘第一桶金的方法不下50种.以读者习惯的武林招式来比喻,也就是不下50式.<科学投资>总结出其中活色生香,可供创业者活学活用之9式,贡献 如下. 第1式:快半拍 典型代表:杨斌 第一桶金:2000万美元 可效仿指数:★★★☆ 2001年,当杨斌出现在当年的<福布斯>中国富豪排行榜上,并且排名高居第二时,许多人吃了一惊,因为在此之前,杨斌是一个谁都不曾听闻过的名字.将杨斌视为一匹财富黑马实不过分.杨斌现在

小企业向大品牌学习假日营销4招式

圣诞节,元旦,春节这些喜庆的节日一波又一波,而商家却开始绞尽脑汁用此良机增强与消费者的关系.但是当我们被五花八门的店面和促销活动搞的头晕目眩时,除了恐慌,又有几家企业让我们为之驻足惊叹?无一例外,节假日成了商家的狂欢PK台,而手段过于同质化,打折.降价.送赠品,司空见惯的传统手段让商家的活动成为鸡肋.近几日认真阅读SocialBeta发布的可口可乐礼花瓶,西捷航空圣诞老人的案例,让我不禁大赞商家运用社会化思维来解决节假日营销方案的创意.而这也给小企业操刀反戈提供了新的思路.作者:@滕宏磊反思:小

《剑灵OL》放出新职业拳士招式引入中国武术

多玩网讯( 继上次<剑灵>官方透漏剑士的<以气驭剑>系统后 不久前 官方透漏了关于"拳士"的2个技能信息.虽然官方透漏出2个拳士的最为重要的技能,但2个技能却与中国的拳功有关. 很显然官方所解释的信息不够详细.因此东方找遍中国有关此技术的历史记录并结合官方的内容. OK 到底什么技能居然与中国的历史有关呢?现在开始东方给大家介绍此相关技能信息. 铁山靠武术介绍 姑且不论其流派及历史,八极拳基本上是一套以简单朴实.爽快直接.崩撼突击等要诀的强身武术,与形意拳.太极

PHP编码规范-php coding standard

standard|编码|规范 目录 介绍 标准化的重要性 解释 认同观点 项目的四个阶段 命名规则 合适的命名 缩写词不要全部使用大写字母 类命名 类库命名 方法命名 类属性命名 方法中参数命名 变量命名 引用变量和函数返回引用 全局变量 定义命名 / 全局常量 静态变量 函数命名 php文件扩展名 文档规则 评价注释 Comments Should Tell a Story Document Decisions 使用标头说明 Make Gotchas Explicit Interface an

PHP数组常用招式

//读取数组 $arr=array("xx"=>"叉叉","yy"=>"歪歪"); echo "读出第一个:".$arr[xx];//统计数组个数 $array=array(aaa,bbb,ccc,ddd); echo "数组个数为:".count($array)."n"; //计算数组单元数目或对象中属性个数 等同sizeof()//快速创建数组 $ar