测试Golang Goroutine

7

我一直在搜索相关内容,但目前只找到了Ariejan de Vroom在这里写的类似文章。

我想知道是否可以将goroutine引入单元测试中,以确切地计算正在运行的并发goroutine数量,并告诉我它们是否按我所述正确地生成了指定数量的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
}

1
你到底想要验证什么?你是想启动16个goroutine吗?我还不太明白你试图解决的问题。 - sberry
为什么你要将int发送到jobs通道?这似乎有两种设计。 - LenW
链接已损坏。 - Ali Behzadian Nejad
2个回答

1
作为我理解的,您希望限制同时运行例程的数量并验证其是否正常工作。我建议编写一个函数,该函数将以例程为参数,并使用模拟例程进行测试。
在以下示例中,spawn函数运行fn例程count次,但同时不要超过limit个例程。我将其包装在主函数中以在playground上运行,但您可以对测试方法使用相同的方法。
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")
    }
}

游乐场


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接