在 VS 中运行单元测试与调试单元测试时,我应该期待啥区别?

Posted

技术标签:

【中文标题】在 VS 中运行单元测试与调试单元测试时,我应该期待啥区别?【英文标题】:What difference should I expect when running a unit test vs debugging a unit test in VS?在 VS 中运行单元测试与调试单元测试时,我应该期待什么区别? 【发布时间】:2021-11-01 07:21:17 【问题描述】:

背景

我有一个 ViewModel,我想使用 Visual Studio 的内置测试框架对其进行单元测试。

public async Task RefreshEntries(string rootID)

    _isCurrentlyFetchingEntries = true; 
    if (_entriesCollectionSource == null)
        _entriesCollectionSource = new ObservableCollection<ExplorerDisplayEntryDTO>();
    _entriesCollectionSource.Clear();
    Entries = CollectionViewSource.GetDefaultView(_entriesCollectionSource);
    var entries = await Task.Run(() =>
    
        var toReturn = (...) // Fetch plenty of things in my repo
        return toReturn;
    );

    foreach (var entry in entries)
    
        _entriesCollectionSource.Add(entry);
       
    Entries.Filter = _customizedFilter;
    _isCurrentlyFetchingEntries = false;

我编写了一个单元测试,它将间接await 这个特定任务(通过围绕 ViewModel 的多次调用)。

运行单元测试时,(CTRL+R,T)它没有问题地通过。

调试单元测试时,上面sn-p第16行抛出异常

运行程序正常(调试和发布模式)时,该方法不会触发任何错误。

System.NotSupportedException 这种类型的 CollectionView 不支持从不同于 Dispatcher 线程的线程更改其 SourceCollection

我查看了并行堆栈窗口,似乎在正常运行时(我怀疑在运行单元测试时),该行由主线程执行。而它似乎在调试测试时由其他线程执行。

问题

运行单元测试与调试单元测试相比,我应该期待什么样的行为变化?

【问题讨论】:

您是否在 STAThread 中运行测试?您使用的是 WPF 应用程序对象吗?尝试将 GetDefaultView 行放在 Filter 行之前。我的猜测是,在调试器之外运行时也存在该错误;只是没有报道。我添加了一个 WPF 标签。 如果你的 Task.Run 上有一个ConfigureAwait(false) 就会有这个问题。 好吧,我没有注意到在运行测试而不是调试它时吞下了异常。所以它可能在测试运行期间抛出(如你所说),但在测试调试期间明确提出。我尝试在测试中添加[STAThread]注解,并添加ConfigureAwait(false)但调试时仍然抛出异常。 你能展示一下测试的代码吗? 在缩小我的测试代码以找出导致上述代码的确切指令时,我发现我向INotifyPropertyChangedPropertyChanged 注册了一个async void 方法。然后,此方法将调用上面显示的代码。我会深入研究,因为我怀疑这可能导致至少部分问题。如果我怀疑是真的,将更新问题/发布答案。 【参考方案1】:

听起来很简单,VS 中单元测试和调试单元测试的主要区别在于:在代码级别找到确切的根本原因以修复在测试过程中发现的错误和错误

【讨论】:

为什么它会改变我的代码的行为? @ArthurAttout,您说您的代码在正常运行程序时运行完美,没有错误。调试时收到 System.NotSupportedException 错误。你的代码的功能没有任何改变,所有的故事都是VS试图告诉你如果你想在调试模式下运行你的程序,你需要修复这个 System.NotSupportedExpection 错误。尝试在此链接中阅读有关此错误的 Microsoft 文档。 docs.microsoft.com/en-us/dotnet/api/… 如果在上面的 sn-p 中抛出异常,并且考虑到我从不使用 Task.Run 而没有 await,那么即使在运行测试时也不应该升级异常吗?除非我弄错了,否则如果 VS 测试遇到未处理的异常,测试应该会失败。因此,如果在运行模式下没有出现未处理的异常,但在调试模式下发生了未处理的异常,我只能得出结论,代码的行为正在发生变化。 @ArthurAttout,请允许我阐明一个事实,即程序和代码行为(功能)不会自行改变,如果你告诉你的代码/程序等待它会,如果你告诉它要启动它,所有命令都一样,这就是它被称为指令的原因。现在关于您的代码,以及关于您使用 await 尝试使用 Async 的部分

以上是关于在 VS 中运行单元测试与调试单元测试时,我应该期待啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

VS Code 无法识别 Flutter 中的单元测试

防止 VS C# 单元测试因异常而中断

运行所有测试时单元测试失败,但调试时通过

签入前运行单元测试

使用 ReSharper,如何在长时间运行的单元测试期间显示调试输出?

VS 2017 中的创建单元测试在哪里?