当前位置: 首页 > 知识库问答 >
问题:

当连续执行多个多线程测试时,测试运行停止

公良育
2023-03-14

我有一个带有静态ConcurrentQueue的类。一个类接收消息并将其放入队列中,而这个类上的另一个线程从该队列中读取消息并一次处理一个。使用cancellationtoken中止该方法。

清空队列的方法如下所示:

public async Task HandleEventsFromQueueAsync(CancellationToken ct, int pollDelay = 25)
{
    while (true)
    {
        if (ct.IsCancellationRequested)
        {
            return;
        }

        if(messageQueue.TryDequeue(out ConsumeContext newMessage))
        {
            handler.Handle(newMessage);
        }

        try
        {
            await Task.Delay(pollDelay, ct).ConfigureAwait(true);
        } 
        catch (TaskCanceledException)
        {
            return;
        }
    }
}

我的测试方法如下:

CancellationToken ct = source.Token;
Thread thread = new Thread(async () => await sut.HandleEventsFromQueueAsync(ct));
thread.Start();

EventListener.messageQueue.Enqueue(message1);
EventListener.messageQueue.Enqueue(message2);
await Task.Delay(1000);
source.Cancel(false);

mockedHandler.Verify(x => x.Handle(It.IsAny<ConsumeContext>()), Times.Exactly(2));

因此,我在自己的线程中启动我的出列方法,并使用一个新的取消令牌。然后我将一些消息排队,给进程一秒钟时间来处理它们,然后使用源代码。Cancel(false)结束线程并使方法返回。然后我检查处理程序被调用的次数是否正确。当然,我在几个变体中测试了这一点,使用不同的消息类型和中止出列方法的不同时间。

问题是,当我单独运行任何html" target="_blank">测试时,它们都会成功。但是,当我尝试将它们作为一个组运行时,VisualStudio并没有运行所有的测试。没有错误消息,并且它确实运行的测试成功,但是运行在第二次测试之后就停止了。

我不知道为什么会这样。我的测试在结构上都是一样的。我每次都会正确地中止退出队列的线程。

什么可以迫使VisualStudio停止测试运行,而不抛出任何类型的错误?

共有2个答案

干永丰
2023-03-14

我已经解决了自己的问题。结果表明,新创建的线程抛出了一个异常,当线程抛出异常时,这些异常会被忽略,但它们仍然会阻止单元测试的发生。在修复导致异常的问题后,测试工作正常。

查宜民
2023-03-14

您正在将异步lambda传递给线程构造函数。线程构造函数不理解异步委托(不接受函数

建议:

  1. 使用任务而不是线程。这样,在退出测试之前,你就可以等待一些东西了
CancellationToken ct = source.Token;
Task consumerTask = Task.Run(() => sut.HandleEventsFromQueueAsync(ct));

EventListener.messageQueue.Enqueue(message1);
EventListener.messageQueue.Enqueue(message2);
await Task.Delay(1000);
source.Cancel(false);
await consumerTask; // Wait the task to complete

mockedHandler.Verify(x => x.Handle(It.IsAny<ConsumeContext>()), Times.Exactly(2));

考虑使用BlockingCollection或像Channel这样的异步队列,而不是Conoline tQueue。轮询是一种笨拙而低效的技术。使用阻塞或异步队列,您不必执行循环等待新消息到达。您可以进入等待状态,并在新消息到达时立即通知。

使用ConfigureAwait(false)配置等待ConfigureAwait(true)是默认值,不执行任何操作。

考虑通过抛出<代码>操作取消定义> /代码>来传播取消。这是在中传播取消的标准方式。网因此,与其说:

if (ct.IsCancellationRequested) return;

...最好这样做:

ct.ThrowIfCancellationRequested();

 类似资料:
  • 问题内容: 我想同时运行多个Selenium测试(在Jenkins服务器上)。 当前,由于ChromeDriver似乎通过特殊端口进行通讯,因此一次仅运行一次测试。因此,以某种方式,我想我必须通过Selenium将某种端口设置传递给ChromeDriver,以启动多个测试。 不幸的是,Selenium网站上的该主题为空:http : //docs.seleniumhq.org/docs/04_we

  • 我试图创建一起使用JBehave和TestNG的概念验证。我想做的是在多个线程中同时运行一个故事,以测试我的代码的线程安全性。 我有一个简单的类,它只做一件事,在给定的整数值上计算模7。我已经为这个类创建了一个简单的BDD测试。我已经按照JBehave“入门”文档中的描述设置了BDD测试。唯一的区别是,在我的JUnitStory文件中,我没有使用JUnit的@Test注释,而是使用了TestNG的

  • 22.13.1.执行测试 测试从main构建过程中分离出来的,运行在一个单独的JVM中执行.Test任务允许控制这些如何发生. 有许多属性用于控制测试过程如何启动.这包括使用诸如系统属性,JVM参数和Java可执行文件。 可以指定是否要并行执行测试.Gradle通过同时运行多个测试进程提供并行执行测试.每个测试进程在同一时间只能执行一个测试,为了充分利用这一特性,一般不需要为tests任务做什么特

  • 我目前正在使用testng selenium来自动化我的测试,我有以下场景: 我需要从excel文件中读取数据,转换对象中的每一行,并为每一行运行一个测试。我试图使用annotation@DataProvider返回一个对象数组,但是它只能返回迭代器和对象[]。是否有任何变通方法可用于从数据提供程序返回客户机对象数组?我尝试了以下代码,但它只打印来自Client2的数据: 编辑1:客户类别: 在控

  • 我试图在Eclipse中使用Selenium运行TestNG。 当类文件作为TestNG测试运行时,我得到的测试Run=0。 问题会是什么? 我有testNg插件 testng。xml文件: 类: WebDriverTest类: BrowserInstance类: 注: 当我将testing.xml文件作为TestNG Suite运行时,结果是: 当我运行. java文件作为TestNG测试时,结

  • 我的自动化测试有一些问题。我的EclipseIDE中大约有50个测试用例。所有测试用例都在不同的类中。另外,我还有一个基类,它包含@beforeclass和@afterclass。在@beforeclass中,浏览器打开,URL打开,网站URL打开,然后执行登录过程。然后我的测试用例工作。它们都以@Test注释开始。我使用TestNG套件将它们连接起来。基类:我的基类。java类MyBaseCla