TestMethod: async Task TestSth()不能在.NET 4.0中运行。

7

我正在尝试使用.NET 4.0 BCL Async和MsTest运行异步测试方法。

似乎这种设置无法处理由于测试用例资源管理器中缺少条目而产生的[TestMethod] async Task TestSth()。将签名更改为async void后,我可以运行测试用例,但结果不正确(根本不会报告任何错误)。

我看到有人尝试过使用TFS 2010运行异步任务单元测试,但我认为应该有更好的方法来解决这个问题。

有什么建议吗?


2
VS2010没有内置支持异步 [TestMethod]。你认为除了Stephen提到的解决方案之外,VS2010还有更好的方法吗?使用VS2012+(因此使用TFS2012+),就有内置支持。 - noseratio - open to work
1
感谢您的评论!我已经在使用VS 2013,但是由于目标是.NET 4.0,因此无法使用async Task方式。这就是我所说的“缺少条目”的意思-我无法启动测试用例。@Noseratio:Stephen的解决方案很好-我只是在寻找另一个“神奇”的NuGet-Package或类似的解决方案,而不是包装每个测试方法;-) - Philipp P
@PhilippP,我不明白为什么不可能。async关键字不会改变方法的签名,它只是一个返回Task的方法,在.NET 4.5或.NET 4.0中都可以使用。你的单元测试项目的.NET目标版本是什么? - noseratio - open to work
@Noseratio,async关键字不是问题——问题似乎在于Task返回值。我的测试项目针对.NET 4.0,使用了async-BCL NuGet扩展。 - Philipp P
1
@Noseratio,是的,如果我将目标设为4.5,它可以工作-不幸的是,整个项目我们必须使用.NET 4.0 :-( 看起来没有其他方法,比如使用Task.Wait()这样的解决办法,就像Stephen的解决方案一样。谢谢你的帮助! - Philipp P
显示剩余3条评论
2个回答

1
您只能在针对.NET 4.5的MSTest引用类库中使用async关键字。
如果由于某种原因无法使用.NET 4.5,则只能手动等待任务完成。
即使生产代码(即受测试代码控制的代码)不能使用.NET 4.5,为什么测试项目不能使用呢? 如果您已经可以使用VS 2012+,则.NET 4.5将安装在您的开发机器上。

0

以下是适用于我的解决方法。它需要一些技巧才能找到,但最终我所有.NET 4.0库的单元测试都被检测到并显示在Test Explorer中,运行并通过测试,并且它们全部编写为普通的 async Task 方法,而没有使用任何特殊的测试运行程序、包装器或第三方依赖。

  1. 将单元测试项目的目标框架更改为.NET 4.5。
    • 是的,即使您要测试的项目引用了.NET 4.0,也必须这样做。
  2. 从您的单元测试项目中删除Microsoft.BclMicrosoft.Bcl.BuildMicrosoft.Bcl.Async NuGet包引用。如果您尚未添加这些引用,则不要将它们添加到您的单元测试项目中。
  3. 在项目的根目录中将System.Runtime.dllSystem.Threading.Tasks.dll作为链接文件添加到您的单元测试项目中。
    1. 在“解决方案资源管理器”中右键单击您的单元测试项目
    2. 添加 > 现有项...
    3. 浏览到您的解决方案的包文件夹,并找到Microsoft.Bclnet40包文件夹;例如:...\packages\Microsoft.Bcl.1.1.10\lib\net40\
    4. 在文件类型下拉菜单中选择所有文件(*.*)
    5. 按住Ctrl键,左键单击System.Runtime.dllSystem.Threading.Tasks.dll以选择它们。
    6. 单击添加按钮上的小下拉箭头。(不要单击添加按钮。)
    7. 添加按钮的下拉菜单中,单击添加为链接。现在两个程序集都可在您的项目根目录下看到。
      • 您必须将程序集链接保留在项目的根目录。不要将它们移动到子文件夹中。
      • 如果您的项目在源代码控制下,则您可能会注意到这些链接文件被标记为已排除(如果它们没有被排除,那么它们应该被排除)。NuGet packages文件夹,其中包含这些文件,不应被检入源代码控制。由于它们只是链接文件,在恢复其NuGet包后,任何拉取您更改的人都不应该有任何问题。
  4. 在“解决方案资源管理器”中选择这两个链接的程序集文件(Ctrl+左键单击),或者仅对每个文件执行以下步骤。
  5. 右键单击所选文件之一,然后选择属性。打开属性窗口。
  6. 复制到输出目录字段设置为如果较新则复制

你的单元测试项目文件现在应该包含类似于以下内容。

<ItemGroup>
  <Content Include="..\..\packages\Microsoft.Bcl.1.1.10\lib\net40\System.Runtime.dll">
    <Link>System.Runtime.dll</Link>
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
  </Content>
  <Content Include="..\..\packages\Microsoft.Bcl.1.1.10\lib\net40\System.Threading.Tasks.dll">
    <Link>System.Threading.Tasks.dll</Link>
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
  </Content>
</ItemGroup>

就是这样了!

请记住,您的单元测试项目针对 .NET 4.5(或更高版本,如果您愿意),因此单元测试可以使用 async 方法和任何其他 .NET 4.5 特性。您正在测试的 .NET 4.0 程序集不应该有任何冲突,但如果您发现冲突,那么很可能是因为您已经重新定义了一些较新框架/C#功能的类型并将它们设为公共,从而在您尝试在单元测试中使用这些类型时引起冲突。最好的解决方案是将这些类型直接设置为要测试的项目的内部类型。

编辑:
按照这些步骤后,您可能会收到一些构建警告:

所有引用 My.csproj 的项目都必须安装 NuGet 包 Microsoft.Bcl.Build。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=317569
{root}\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets

为了避免这些警告,只需编辑单元测试项目并向每个指向引用了Microsoft.Bcl.Build的项目引用添加以下元数据元素即可。
<Properties>SkipValidatePackageReferences=true</Properties>

例如:

<ProjectReference Include="..\pcl\pcl.csproj">
  <Project>{664a9e98-fac7-4567-a046-0dde95fddb48}</Project>
  <Name>pcl</Name>
  <Properties>SkipValidatePackageReferences=true</Properties>
</ProjectReference>

完整的解释可以在附带Microsoft.Bcl.Build包的注释.targets文件中找到。以下是完整的注释,供您参考。

BclBuildValidateNugetPackageReferences

此目标验证当前项目中安装的任何Nuget包是否也安装在引用当前项目的项目中。

这是必要的,因为Nuget包不仅包含简单的引用。安装包确保:
1. 添加了目标框架的正确引用
2. 应用配置文件转换
3. 运行项目安装脚本

对于在packages config中列出为当前项目安装的所有包,如果包ID与@(ValidatePackages)中指定的一个匹配,则确保在引用项目中安装了相同的包。

可以通过为引用设置SkipValidatePackageReferences=true来禁用此目标:

<ProjectReference Include="..\pcl\pcl.csproj">
  <Project>{664a9e98-fac7-4567-a046-0dde95fddb48}</Project>
  <Name>pcl</Name>
  <Properties>SkipValidatePackageReferences=true</Properties>
</ProjectReference>

可以通过添加以下内容来禁用所有对项目的引用:

这个目标可以通过添加以下内容来禁用所有对项目的引用:

<PropertyGroup>
  <SkipValidatePackageReferences>true</SkipValidatePackageReferences>
</PropertyGroup>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接