2012年4月22日,星期日

SharePoint 2010和单元测试(来自Visual Studio 2010 / MSTest.exe)

It’自VS2010 SP1起,就可以在Visual Studio 2010中运行SharePoint 2010的单元测试/集成测试,但是我’我开始怀疑实现这一目标的步骤是否广为人知。在写另一篇文章时,我进行了互联网搜索,但没有’在结果的第1页上找不到任何有用的指南。实际上,许多热门搜索结果中包含的信息现在已经过时,例如“使用SharePoint 2010开发进行单元测试”关于通常好的文章 www.nothingbutsharepoint.com。但是我赢了’不会是第一个写下这个的人,如果您真的要寻找的话,我怀疑信息在那里– but I’我会尽我所能,并在这里写下步骤。

此处的关键问题是能够从单元测试(通常称为集成测试)中调用SharePoint API。‘Pure’不调用SharePoint对象的单元测试一直很好。能够运行SharePoint集成测试的前提条件是:

从那里开始,请按照以下步骤操作。

过程-从Visual Studio 2010运行SP2010单元/集成测试

  1. 配置Visual Studio 2010 允许测试项目(即包含测试的VS项目)针对.NET 3.5(SharePoint 2010使用的框架版本):

    可以在项目属性中配置Visual Studio项目的框架版本,但我’ve总是需要执行一次性任务(针对每个开发VM)–编辑devenv.exe.config文件,以使VS重新定位测试项目。这些步骤在MSDN上列出,网址为 Possible Additional Steps to Enable Re-targeting of 测试项目s to .NET Framework 3.5,但为了完整起见,’我会在这里总结一下:

    -如果打开,请关闭Visual Studio
    -打开Windows资源管理器以找到C:\ Program Files(x86)\ Microsoft Visual Studio 10.0 \ Common7 \ IDE \
    -备份devenv.exe.config
    -在记事本中打开原始的devenv.exe.config文件
    -粘贴在‘可能的附加步骤’上面的链接。请注意,有一个 appSettings 关键以及主要的 bindingRedirect 参赛作品
    -保存配置文件
    -重新打开Visual Studio

  2.  创建一个测试项目,并确保它针对.NET 3.5:

    有几种方法可以做到这一点,这使得‘Test Project’以3.5为目标的模板列在一个易混淆的名称下方‘Test Documents’对话框中的标题。要么使用那个(并检查它是否针对3.5),要么使用main‘Test Project’模板,然后将其从.NET 4重新定位到.NET 3.5。一世’在这里显示该过程:

    CreateTestProject

    创建项目后,进入项目属性,然后在“应用程序”选项卡上,确保“目标框架”设置为‘.NET Framework 3.5’:

    RetargetTestProject

    您’将会看到一个对话框警告您必须关闭并重新打开项目– click ‘Yes’ to do this.

  3. 确保‘Platform target’项目的设置为‘Any CPU’:

    TestProject_AnyCPU
  4. 确保.testsettings文件指定测试应在64位进程中运行:

    现在,您的Visual Studio解决方案中应该有几个.testsettings文件。缺省的一个称为Local.testsettings,我们需要对其进行编辑–但请注意,如果您使用其他文件,’我也需要编辑在主机标签上,确保‘以32位或64位进程运行测试’选项设置为64位:

    TestSettings_64bit

结果

现在,您应该能够编写调用SharePoint API的测试。例如这里’s稍有理论性的测试,表明我可以调用一个使用 网站/网页 对象:

   1: [TestMethod()]
   2: public void GetRootTeamSiteTitleTest()
   3: {
   4:     string expected = "BVT test"; 
   5:     string actual;
   6:     actual = CobCiHelper.GetRootTeamSiteTitle();
   7:     Assert.AreEqual(expected, actual);
   8: }

..在其中被调用的CobCiHelper类中的代码如下所示:

   1: public static string GetRootTeamSiteTitle()
   2: {
   3:     string title= null;
   4:     using (SPSite site = new 网站(Urls.Homepage))
   5:     {
   6:         using (SPWeb web = site.RootWeb)
   7:         {
   8:             title= web.Title;
   9:         }
  10:     }
  11:     return title;
  12: }

如果您的考试通过,您’会看到类似这样的内容(但是无论哪种方式,您的文本都应成功执行):

考试通过了

在TFS自动版本中运行SharePoint集成测试

上面的过程可以帮助您从Visual Studio中手动运行测试,但是请注意,如果您想从自动化版本中运行相同的测试,则无济于事。 不幸的是,Team Foundation Server 2010 / Visual Studio 2010当前不支持调用SharePoint API的集成测试。 ‘Pure’单元测试,或使用诸如Typemock之类的模拟框架的单元测试 能够 虽然被使用。让’希望这一挑战在下一波技术中消失。

6条评论:

说过...

感谢您提供详细信息。我很生气,因为应用SP1没有任何区别。我会说几乎所有开发人员都必须手动编辑desenv.exe.config,而'至少有一个插件或插件?

One detail: the link you provided (Additional steps...) points to the VS 2012 article, where that section does not exist. The correct link is thus http://msdn.microsoft.com/en-us/library/gg601487(v=vs.100).aspx

西风说过...

克里斯

好帖子..我的单元测试越来越严格,因为我的客户越来越多地要求我围绕许多sp2010的短处进行编码;-)/。在沿着帖子中描述的路线走之前,您是否亲自(键入)模拟内容?
顺便说一句18号见。

未知说过...

感谢您提供的信息。我有两个"devenv.exe.config"文件,与"带GUID的devenv.exe.config". i done the "可能的其他步骤"在第二个和它的工作。

非常感谢。

马腾说过...

克里斯,你好

感谢本文。一世'我试图在VS2012环境中实施单元测试。似乎针对正确的框架是'在此版本的VS中存在问题。

创建一个获得对SPSite引用的单元测试的工作原理(I'm using a 'fake'SPContext并使用新的SPSite(url,site.UserToken)构造函数)。但是,当我尝试在单元测试中更新SPListItem时,我收到了众所周知的信息。 '当前不允许GET请求进行更新。' 错误。

一种解决方案是通过添加'web.allowunsafeupdates = true'行,但是,它没有'不能更改原始代码,以进行单元测试。

您有解决该问题的想法吗?

谢谢!

克里斯·奥'Brien说过...

@Maarten,

我同意,修改正在测试的代码不是't ideal. Actually I'我很惊讶您在单元测试中遇到此错误-HttpContext是否设置为null?如果不是,请尝试执行此操作,然后查看是否仍然出现错误。

如果我没记错的话,安全检查确实会在HttpContext中寻找内容。

干杯,

克里斯。

马腾 said...

克里斯,你好

感谢您的回复!

在我当前的解决方案中,将HTTPContext设置为null是'绝对不是一个选择。我故意创建一个'fake'在我的测试中使用HTTPContext,以便可以使用它'的内部属性来存储网络对象,并使用该属性来检索'fake' SPContext in my application. I create the 假 context like this:

========

HttpRequest请求=新的HttpRequest("", web.Url, "");
request.Browser = new HttpBrowserCapabilities();
HttpContext.Current =新的HttpContext(请求,新的HttpResponse(新的StringWriter()));

// SPContext基于SPControl.GetContextWeb(),在这里
如果(HttpContext.Current.Items ["HttpHandlerSPWeb"] == null)
HttpContext.Current.Items ["HttpHandlerSPWeb"] = web;

返回SPContext.Current;

========

将HTTPContext设置为NULL会导致我的应用程序中有一个nullreference,这在测试浏览器中给了我一个大的红点:-)

您是否还有其他建议可以解决'当前不允许GET请求进行更新。'错误,或如何创建'fake'spcontext不需要HTTPContext吗?

谢谢!