【问题标题】:Test Golang Goroutine测试 Golang 协程
【发布时间】:2015-05-06 06:37:27
【问题描述】:

我一直在四处寻找,但到目前为止只有 Ariejan de Vroom here 写的类似文章。

我想知道我是否可以将 goroutine 带入单元测试中,这样它就可以精确地计算并发运行的 goroutines 的数量,并可以告诉我它们是否是正确生成的 goroutine 在我所说的数量中。

例如,我有以下代码..

import (
    "testing"
    "github.com/stretchr/testify/assert"
)

func createList(job int, done chan bool) {
    time.Sleep(500)
    // do something
    time.Sleep(500)
    done <- true
    return
}

func TestNewList(t *testing.T) {
  list := NewList()
  if assert.NotNil(t, list) {
    const numGoRoutines = 16
    jobs := make(chan int, numGoRoutines)
    done := make(chan bool, 1)

    for j := 1; j <= numGoRoutines; j++ {
        jobs <- j
        go createList(j, done)
        fmt.Println("sent job", j)
    }
    close(jobs)
    fmt.Println("sent all jobs")
    <-done
}

【问题讨论】:

  • 您到底想验证什么?你正在启动 16 个 goroutine?我没有完全关注您要解决的问题。
  • 为什么要将 int 发送到工作频道?那里好像有 2 个设计。
  • 链接失效

标签: unit-testing go tdd goroutine


【解决方案1】:

据我了解,您愿意限制同时运行的例程数量并验证其是否正常工作。我建议编写一个函数,它将一个例程作为参数并使用模拟例程来测试它。
在以下示例中,spawn 函数同时运行 fn 例程 count 次,但不超过 limit 例程。我将它包装到 main 函数中以便在操场上运行它,但您可以对测试方法使用相同的方法。

package main

import (
    "fmt"
    "sync"
    "time"
)

func spawn(fn func(), count int, limit int) {
    limiter := make(chan bool, limit)

    spawned := func() {
        defer func() { <-limiter }()
        fn()
    }

    for i := 0; i < count; i++ {
        limiter <- true
        go spawned()
    }
}

func main() {

    count := 10
    limit := 3

    var wg sync.WaitGroup
    wg.Add(count)

    concurrentCount := 0
    failed := false

    var mock = func() {
        defer func() {
            wg.Done()
            concurrentCount--
        }()

        concurrentCount++
        if concurrentCount > limit {
            failed = true // test could be failed here without waiting all routines finish
        }

        time.Sleep(100)
    }

    spawn(mock, count, limit)

    wg.Wait()

    if failed {
        fmt.Println("Test failed")
    } else {
        fmt.Println("Test passed")
    }
}

Playground

【讨论】:

    【解决方案2】:

    一种可能的方法是使用runtime.Stack() 或分析runtime.debug.PrintStack() 的输出,以便查看给定时间的所有goroutine。

    这些选项在“How to dump goroutine stacktraces?”中有详细说明。

    【讨论】:

      猜你喜欢
      • 2022-01-06
      • 1970-01-01
      • 2019-08-23
      • 1970-01-01
      • 1970-01-01
      • 2021-08-04
      • 1970-01-01
      • 1970-01-01
      • 2022-07-05
      相关资源
      最近更新 更多