如何编写单元测试来检查方法是否是线程安全的

huangapple go评论83阅读模式
英文:

How to write unit tests to check that methods are thread-safe

问题

我有一个像这样的对象:

type Store struct {
    mutex sync.RWMutex
    data  map[string]int
}

func (s *Store) Read(key string) (int, error) {
    // ...
    defer s.mutex.RUnlock()
    s.mutex.RLock()
    // ...
    return val, nil
}

func (s *Store) Write(key string, value int) error {
    // ...
    defer s.mutex.Unlock()
    s.mutex.Lock()
    // ...
    return nil
}

如何编写单元测试来检查 ReadWrite 方法是否是线程安全的?

我认为已经存在针对这种情况的模式,但我没有找到相关的资料。

我了解到 -race 标志:

只有在运行代码时触发时,竞态检测器才能检测到竞争条件,这意味着在真实工作负载下运行启用了竞态检测的二进制文件非常重要。

我的问题是如何编写模拟真实工作负载的单元测试。

英文:

I have an object like this:

type Store struct {
    mutex sync.RWMutex
    data  map[string]int
}

func (s * Store) Read(key string) int, error {
    // ...
    defer s.mutex.RUnlock()
    s.mutex.RLock()
    // ...
    return val, nil
}

func (s * Store) Write(key string, value int) error {
    // ...
    defer s.mutex.Unlock()
    s.mutex.Lock()
    // ...
    return nil
}

How should unit-tests to look like for methods Read & Write to check that they are thread safe?

I think there are already exists patterns for cases like this, but I didn't find anything.

I read about -race flag:

> the race detector can detect race conditions only when they are actually triggered by running code, which means it's important to run race-enabled binaries under realistic workloads

My question is how to write unit-test which emulates realistic workloads.

答案1

得分: 5

使用Race detector来运行你的测试。简而言之,运行以下命令:

go test -race

或者如果要构建一个普通的二进制文件,比如在一个暂存服务器上运行,可以使用:

go build -race

但是还有很多其他选项,最好去详细了解一下 如何编写单元测试来检查方法是否是线程安全的

如果你的目标是在真实负载下进行测试,最好的选择是使用go build -race编译你的代码,然后在真实负载下运行它。这可能意味着在一个暂存服务器上运行。但是不要将其与单元测试混淆!

单元测试是用于测试单元——通常是单个函数的小代码片段。负载/竞争测试是一种不同的测试方式,需要不同的工具和完全不同的方法。

Go可以轻松地使用竞争检测器运行单元测试,这很好,并且通常可以捕获到竞争条件。但是它不会、也不应该期望能够捕获到所有的竞争条件,因为单元测试的执行方式与生产环境的执行方式完全不同。

英文:

Run your tests with the Race detector. In short, run:

go test -race

Or to build a normal binary, such as to run on a staging server, use:

go build -race

But there are many more options, so best to read up on it 如何编写单元测试来检查方法是否是线程安全的

If your goal is to test under realistic load, your best option is to compile your code with go build -race, then run it under realistic load. This probably means on a staging server. But don't confuse this with unit testing!

Unit testing is for testing units--small parts of code, usually individual functions. Load/race testing is a different beast, and requires different tools and an entirely different approach.

The fact that Go will easily run unit tests with the race detector is nice, and often catches races. But it will not, nor should not be expected to, catch all races, since the nature of unit test execution is entirely different from that of production execution.

huangapple
  • 本文由 发表于 2017年6月24日 02:53:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/44728201.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定