本地VS2022单元测试正常,流水线运行时加载StringEx类型失败
问题描述
本地使用Visual Studio 2022运行单元测试完全正常,但在Azure DevOps流水线执行相同测试时抛出以下错误:
[error]An exception occurred while invoking executor 'executor://mstestadapter/v2': Could not load type 'Microsoft.VisualStudio.TestTools.UnitTesting.StringEx' from assembly 'Microsoft.VisualStudio.TestPlatform.TestFramework, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.
完整堆栈跟踪:
##[debug]Processed: ##vso[task.logissue type=error;]An exception occurred while invoking executor 'executor://mstestadapter/v2': Could not load type 'Microsoft.VisualStudio.TestTools.UnitTesting.StringEx' from assembly 'Microsoft.VisualStudio.TestPlatform.TestFramework, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. ##[error]Stack trace: ##[debug]Processed: ##vso[task.logissue type=error;]Stack trace: ##[error] at Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.MSTestSettings.PopulateSettings(IDiscoveryContext context) ##[debug]Processed: ##vso[task.logissue type=error;] at Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.MSTestSettings.PopulateSettings(IDiscoveryContext context) ##[error] at Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.MSTestExecutor.RunTests(IEnumerable`1 sources, IRunContext runContext, IFrameworkHandle frameworkHandle) ##[debug]Processed: ##vso[task.logissue type=error;] at Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.MSTestExecutor.RunTests(IEnumerable`1 sources, IRunContext runContext, IFrameworkHandle frameworkHandle) ##[error] at Microsoft.VisualStudio.TestPlatform.Common.ExtensionDecorators.SerialTestRunDecorator.RunTests(IEnumerable`1 sources, IRunContext runContext, IFrameworkHandle frameworkHandle) ##[debug]Processed: ##vso[task.logissue type=error;] at Microsoft.VisualStudio.TestPlatform.Common.ExtensionDecorators.SerialTestRunDecorator.RunTests(IEnumerable`1 sources, IRunContext runContext, IFrameworkHandle frameworkHandle) ##[error] at Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Execution.RunTestsWithSources.InvokeExecutor(LazyExtension`2 executor, Tuple`2 executorUriExtensionTuple, RunContext runContext, IFrameworkHandle frameworkHandle) ##[debug]Processed: ##vso[task.logissue type=error;] at Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Execution.RunTestsWithSources.InvokeExecutor(LazyExtension`2 executor, Tuple`2 executorUriExtensionTuple, RunContext runContext, IFrameworkHandle frameworkHandle) ##[error] at Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Execution.BaseRunTests.<>c__DisplayClass46_0.<RunTestInternalWithExecutors>b__0() ##[debug]Processed: ##vso[task.logissue type=error;] at Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Execution.BaseRunTests.<>c__DisplayClass46_0.<RunTestInternalWithExecutors>b__0() ##[error] at Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.PlatformThread.<>c__DisplayClass0_0.<Run>b__0() ##[debug]Processed: ##vso[task.logissue type=error;] at Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.PlatformThread.<>c__DisplayClass0_0.<Run>b__0() ##[error]--- End of stack trace from previous location where exception was thrown --- ##[debug]Processed: ##vso[task.logissue type=error;]--- End of stack trace from previous location where exception was thrown --- ##[error] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() ##[debug]Processed: ##vso[task.logissue type=error;] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() ##[error] at Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.PlatformThread.Run(Action action, PlatformApartmentState apartmentState, Boolean waitForCompletion) ##[debug]Processed: ##vso[task.logissue type=error;] at Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.PlatformThread.Run(Action action, PlatformApartmentState apartmentState, Boolean waitForCompletion) ##[error] at Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Execution.BaseRunTests.TryToRunInStaThread(Action action, Boolean waitForCompletion) ##[debug]Processed: ##vso[task.logissue type=error;] at Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Execution.BaseRunTests.TryToRunInStaThread(Action action, Boolean waitForCompletion) ##[error] at Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Execution.BaseRunTests.RunTestInternalWithExecutors(IEnumerable`1 executorUriExtensionMap, Int64 totalTests) ##[debug]Processed: ##vso[task.logissue type=error;] at Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Execution.BaseRunTests.RunTestInternalWithExecutors(IEnumerable`1 executorUriExtensionMap, Int64 totalTests) [xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.4.1 (64-bit .NET Framework 4.8.4300.0)
流水线测试步骤配置:
- task: VSTest@2 displayName: 'Run unit tests' condition: and(succeeded(), eq('${{ parameters.enableTests }}', 'true')) inputs: #vstestLocationMethod: location #vstestLocation: 'C:\Program Files\PackageManagement\NuGet\Packages\Microsoft.TestPlatform.16.4.0\tools\net451\Common7\IDE\Extensions\TestPlatform' #vstestLocation: 'C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\Common7\IDE\Extensions\TestPlatform' testSelector: 'testAssemblies' vsTestVersion: 'toolsInstaller' testAssemblyVer2: '**\\*UnitTests*.dll' platform: '${{ parameters.buildPlatform }}' configuration: '${{ parameters.buildConfiguration }}' searchFolder: '$(build.ArtifactStagingDirectory)\\${{parameters.packageFolderName}}' codeCoverageEnabled: '${{ parameters.enableCodeCoverage }}' runInParallel: "true" testFiltercriteria: "TestCategory!=Manual"
已尝试调整MSTest.TestAdapter、MSTest.TestFramework版本及.NET SDK,但问题未解决。
解决方案
1. 统一MSTest适配器与测试框架版本到最新稳定版
确保项目中MSTest.TestAdapter和MSTest.TestFramework的版本完全一致,且升级到最新稳定版(比如2.2.10或更高)。在项目的NuGet包管理器中更新这两个包,避免版本不兼容导致的类型缺失。
2. 指定流水线使用与本地一致的VS测试平台版本
流水线中vsTestVersion: 'toolsInstaller'会自动安装最新测试平台,可能与本地VS2022使用的版本不匹配。可改为指定使用Visual Studio 2022的测试平台:
vsTestVersion: 'latest' # 或明确指定版本 # vsTestVersion: '17.x'
如果构建代理安装了VS2022 Build Tools,也可直接指定测试平台路径:
vstestLocationMethod: 'location' vstestLocation: 'C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\Common7\IDE\Extensions\TestPlatform'
3. 确保测试程序集的依赖文件被正确发布到流水线工件
检查构建步骤是否将MSTest.TestAdapter.dll、MSTest.TestFramework.dll等依赖文件复制到测试程序集所在目录。可添加Copy Files步骤:
- task: CopyFiles@2 displayName: 'Copy test dependencies' inputs: SourceFolder: '$(SolutionDir)\packages\MSTest.TestAdapter.*\build\_common' Contents: '**/*.dll' TargetFolder: '$(build.ArtifactStagingDirectory)\${{parameters.packageFolderName}}'
4. 临时禁用并行测试排查冲突
流水线开启的runInParallel: "true"可能引发依赖加载冲突,可临时禁用验证:
runInParallel: "false"
5. 检查测试程序集的目标框架版本
确保测试项目的目标框架与流水线使用的.NET SDK版本兼容,比如本地用.NET Framework 4.8,流水线也要匹配对应SDK版本,避免跨框架加载问题。
内容的提问来源于stack exchange,提问作者Raulster24
相关产品推荐
相关产品推荐

