英文:
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
}
如何编写单元测试来检查 Read
和 Write
方法是否是线程安全的?
我认为已经存在针对这种情况的模式,但我没有找到相关的资料。
我了解到 -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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论