Во время параллельного unit-теста Go race detector сообщает о конфликтующих чтениях и записи общей переменной. Какой механизм он обнаруживает и что означает такой отчёт?
База Hintsage
Тестирование
Unit-тесты, table-driven tests, mocks, race detector и benchmarks.
Практика
Вопросы: Тестирование
Как в Go benchmark отделить время подготовки тестовых данных от времени измеряемой операции?
В unit-тесте Go зависимость заменена mock-объектом: по какому критерию решить, что вызов зависимости нужно проверять?
В проекте с параллельными subtests таблица кейсов обрабатывается в цикле: почему замыкание над переменной цикла может дать неверные результаты?
Разберите, почему этот unit-тест может завершиться до фиксации ошибки и как корректно сообщить о ней:
func TestLoad(t *testing.T) {
go func() {
if err := load(); err != nil {
t.Fatal(err)
}
}()
}
Представьте: общий помощник проверки в Go при падении указывает на свою строку. Что в нём нужно изменить, чтобы отчёт показывал место вызова теста?
Какой порядок сообщений и очистки даст этот тест, и почему параллельный subtest не начинает выполнять тело сразу?
package config
import (
"fmt"
"testing"
)
func TestConfig(t *testing.T) {
t.Cleanup(func() { fmt.Println("parent cleanup") })
t.Run("parallel", func(t *testing.T) {
t.Parallel()
t.Cleanup(func() { fmt.Println("child cleanup") })
fmt.Println("child body")
})
fmt.Println("parent body")
}
Вам дали benchmark, в котором результат вычисления нигде не используется. Какой риск это создаёт для достоверности измерения?
package checksum
import "testing"
func sum(data []byte) uint64 {
var result uint64
for _, value := range data {
result += uint64(value)
}
return result
}
func BenchmarkSum(b *testing.B) {
data := make([]byte, 1024)
for i := 0; i < b.N; i++ {
sum(data)
}
}
В unit-тесте Go вызов изменения переменной окружения выполняется после перевода теста в параллельный режим. Какое ограничение это нарушает и почему?
Зачем оборачивать каждый кейс table-driven теста Go в отдельный subtest, если важно получить независимые результаты всех кейсов?
После рефакторинга функция начала добавлять контекст к sentinel-ошибке. Какую проверку следует использовать здесь, чтобы сохранить смысл теста?
package service
import (
"errors"
"fmt"
"testing"
)
var ErrNotFound = errors.New("not found")
func load() error {
return fmt.Errorf("load config: %w", ErrNotFound)
}
func TestLoad(t *testing.T) {
if err := load(); err != ErrNotFound {
t.Fatalf("got %v", err)
}
}
Представьте, что в benchmark Go нужно сравнить реализации по числу выделений памяти на одну операцию, а не по времени. Как получить такой показатель?
При параллельном запуске Go-тестов несколько кейсов работают с файлами: какое свойство даёт каждому кейсу отдельный каталог через t.TempDir?
Тестовый набор Go полностью проходит под race detector. Какой единственный обоснованный вывод можно сделать о наличии гонок?
В table-driven тесте Go один кейс изменяет входной срез, из-за чего результат следующего зависит от порядка запуска. Какой механизм создаёт эту связанность и как сделать кейсы независимыми?
В benchmark Go нагрузка распределяется через RunParallel. Как интерпретировать SetParallelism и почему его значение нельзя считать числом одновременно выполняющихся горутин?
Представьте сервис, чей mock полностью повторяет поведение реальной зависимости. Какой риск это создаёт для достоверности unit-теста?
После запуска вложенного теста родитель должен решить, продолжать ли сценарий. Что именно сообщает булево значение, возвращаемое t.Run, и как его правильно интерпретировать?
На собеседовании вас спрашивают: что означает b.N в benchmark Go, если фреймворк сам меняет его значение между запусками?
В table-driven тесте кейсы хранятся в map, а сбой появляется только для некоторых порядков выполнения. Какой вывод следует сделать о самом тесте?
Показано 1–20 из 50