如果单独运行 MSTest 测试成功,如果与其他测试一起运行则失败
Posted
技术标签:
【中文标题】如果单独运行 MSTest 测试成功,如果与其他测试一起运行则失败【英文标题】:MSTest tests succeed if run in isolation, fail if run with other tests 【发布时间】:2016-05-27 20:10:36 【问题描述】:我遇到了一个非常奇怪的情况,如果我一起运行所有测试,某些测试会失败(其中大约 7 个)。但是如果我只在类内运行测试(它们都是同一个类的一部分),那么它们就通过了。测试项目是 Windows Phone 8.1 MSTest,我尝试使用 Resharper 测试运行器和 MSTest 测试运行器运行它,它们都显示相同的问题。这是我的 TestInitialize 代码:
[TestInitialize]
public void Init()
ResolveDependencies();
var adsApiService = ServiceLocator
.Current
.GetInstance<IApiService<ListAdsReply, PublicAdsEndPoint>>();
var navigationService = new NavigationServiceMock();
var mainPageTrackingService = ServiceLocator
.Current
.GetInstance<IMainPageTrackingService>();
var adInsertionTrackingService = ServiceLocator
.Current
.GetInstance<IAdInsertionTrackingService>();
var connectionService = ServiceLocator
.Current
.GetInstance<IConnectionService>();
_windowsApiService = new WindowsApiServiceMock();
var contactAboutTrackingService = ServiceLocator
.Current
.GetInstance<IContactAboutTrackingService>();
var filtersTrackingService = ServiceLocator
.Current
.GetInstance<IFiltersTrackingService>();
var filtersService = ServiceLocator
.Current
.GetInstance<IFiltersService>();
var messageHelperMock = new MessageHelperMock();
_mainPageViewModel = new MainPageViewModel(adsApiService, navigationService, mainPageTrackingService, adInsertionTrackingService, connectionService, _windowsApiService, contactAboutTrackingService,filtersTrackingService, filtersService, messageHelperMock);
ResolveDependencies
方法除了在 Unity 容器中注册依赖项、使用 ServiceLocator.SetLocatorProvider
注册它并进行一些 Automapper 配置之外,并没有做任何特别的事情。那里没有异步代码。
[TestMethod]
public async Task GivenParameterIsProvidedThenFetchDataShouldReturnValidData()
_mainPageViewModel
.SearchParams
.Add(new KeyValuePair<string, string>("lim", "5"));
var searchParams = _mainPageViewModel.SearchParams;
await _mainPageViewModel.FetchData(searchParams);
var list = _mainPageViewModel.AdsList;
Assert.IsNotNull(list);
这是失败的测试之一。
public async Task<ListAdsReplyViewModel> FetchData(List<KeyValuePair<string, string>> parameters)
_cancellationTokenSource = new CancellationTokenSource();
_cancellationTokenSource
.CancelAfter(Constants.TimeToCancelAsyncOperations);
AddSearchKeywordToSearchParams();
var result = await _listAdsReplyApiService
.GetWithParametersAsync(_cancellationTokenSource, parameters);
var vm = new ListAdsReplyViewModel
Ads = new List<AdInfoViewModel>()
;
foreach (var listAd in result.ListAds)
var listAdDto = Mapper.Map<ListAdDto>(listAd);
var adInfo = new AdInfoViewModel(_navigationService, _mainPageTrackingService)
ListAdDto = listAdDto
;
vm.Ads.Add(adInfo);
vm.NextPage = result.NextPage;
vm.ConfigEtag = result.ConfigEtag;
vm.Sorting = result.Sorting;
TotalAds = result.ListAdsCounterMap.AllAds;
return vm;
private void AddSearchKeywordToSearchParams()
if (!string.IsNullOrEmpty(SearchKeyWord))
var searchKeyword = SearchParams
.FirstOrDefault(x => x.Key == "q");
if (!searchKeyword.Equals(null))
SearchParams.Remove(searchKeyword);
SearchParams.Add(new KeyValuePair<string, string>("q", SearchKeyWord));
这是正在测试的方法。调用foreach((var listAd in result.ListAds)
时似乎会出现问题。就像 GetWithParametersAsync(_cancellationTokenSource, parameters);
没有被等待,因为我收到以下失败测试的错误:
Test method App.Tests.Integration.App.Shared.ViewModels.MainPageViewModelTests.GivenParameterIsProvidedThenFetchDataShouldReturnValidData threw exception:
AutoMapper.AutoMapperMappingException:
Mapping types:
ListAd -> ListAdDto
Core.Api.Models.PublicAds.ListAd -> Core.Dto.ListAdDto
Destination path:
ListAdDto
Source value:
Core.Api.Models.PublicAds.ListAd ---> System.NullReferenceException: Object reference not set to an instance of an object.
at Core.Bootstrap.AutoMapperConfiguration.<>c__DisplayClass0_0.<Configure>b__12(ListAd src, ListAdDto dest)
at AutoMapper.Internal.MappingExpression`2.<>c__DisplayClass57_0.<AfterMap>b__0(Object src, Object dest)
at AutoMapper.TypeMap.<get_AfterMap>b__40_0(Object src, Object dest)
at AutoMapper.Mappers.TypeMapObjectMapperRegistry.PropertyMapMappingStrategy.Map(ResolutionContext context, IMappingEngineRunner mapper)
at AutoMapper.Mappers.TypeMapMapper.Map(ResolutionContext context, IMappingEngineRunner mapper)
at AutoMapper.MappingEngine.AutoMapper.IMappingEngineRunner.Map(ResolutionContext context)
--- End of inner exception stack trace ---
at App.ViewModels.MainPageViewModel.<FetchData>d__34.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at App.Tests.Integration.App.Shared.ViewModels.MainPageViewModelTests.<GivenParameterIsProvidedThenFetchDataShouldReturnValidData>d__7.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
有什么想法吗?
【问题讨论】:
当您运行任何其他测试或仅在运行某个测试时,这会中断吗? (即,是导致故障的任何测试组合还是仅导致问题出现的某个组合/某个测试?)其次,您是否启动了调试器并跟踪步骤以查看哪里出了问题?异常说你有一个空引用错误。它看起来也可能与自动映射器有关。在那里试试。 您是否考虑到 MSTest 将多线程运行您的测试 - 并且通过执行单个测试您会强制使用单线程?请非常小心,您的所有测试都是 UNIT 测试,并且在执行顺序或共享资源可能已经被并行运行的另一个测试实例化(或正在实例化过程中)的可能性上,彼此之间没有依赖关系. @Becuzz 当我运行整个测试时测试会中断(400 多个测试,我有单元和集成测试)。如果我只运行失败的测试,这些测试恰好在同一个类中,那么它们就会通过。 PhillipH 有一点,看起来测试正在多线程运行,但映射 ListAdDto 的代码正在运行并且没有按应有的等待,因此抛出 NullRef 异常 @PhillipH 你是对的,这可能是正在发生的事情,它正在运行多线程。这些测试是集成测试,指向一个实时的 api,并且由于某种原因没有被等待。除了在TestInitilialize
中找到的那些之外,我没有找到任何依赖项或共享资源。
【参考方案1】:
由于这在 cmets 中已被接受,因此我已将其重新发布为答案;
“您是否考虑过 MSTest 将多线程运行您的测试 - 并且通过执行单个测试您强制使用单线程?要非常小心,您的所有测试都是 UNIT 测试并且不依赖于每个测试其他,在执行顺序中,或者共享资源可能已经被另一个并行运行的测试实例化(或正在实例化过程中)的可能性。"
【讨论】:
以上是关于如果单独运行 MSTest 测试成功,如果与其他测试一起运行则失败的主要内容,如果未能解决你的问题,请参考以下文章
Visual Studio 2015 MSTest 无法运行负载测试
是啥导致在单元测试(NUnit 或 MSTest)中从 C# 调用的 C++ 函数与在控制台应用程序中运行的相同代码产生不同的结果?