Правильное именование пакетов для тестирования на языке Go - программирование
Подтвердить что ты не робот

Правильное именование пакетов для тестирования на языке Go

Я видел несколько различных стратегий именования тестовых пакетов в Go и хотел узнать, что за плюсы и минусы каждого из них и какой я должен использовать.

Стратегия 1:

Имя файла: github.com/user/myfunc.go

package myfunc

Имя тестового файла: github.com/user/myfunc_test.go

package myfunc

См. bzip2 для примера.

Стратегия 2:

Имя файла: github.com/user/myfunc.go

package myfunc

Имя тестового файла: github.com/user/myfunc_test.go

package myfunc_test

import (
    "github.com/user/myfunc"
)

См. wire для примера.

Стратегия 3:

Имя файла: github.com/user/myfunc.go

package myfunc

Имя тестового файла: github.com/user/myfunc_test.go

package myfunc_test

import (
    . "myfunc"
)

См. strings для примера.

Стандартная библиотека Go Go, похоже, использует смесь стратегий 1 и 2. Какую из трех я должен использовать? Это боль, добавляющая package *_test к моим тестовым пакетам, так как это означает, что я не могу проверить свои частные методы пакета, но, возможно, есть скрытое преимущество, о котором я не знаю?

4b9b3361

Ответ 1

Фундаментальное различие между тремя перечисленными вами стратегиями заключается в том, находится ли тестовый код в том же пакете, что и тестируемый код. Решение использовать package myfunc или package myfunc_test в тестовом файле зависит от того, хотите ли вы выполнить white-box или black-box.

Нет ничего плохого в использовании обоих методов в проекте. Например, вы могли бы иметь myfunc_whitebox_test.go и myfunx_blackbox_test.go.

Сравнение пакетов тестового кода

  • Тестирование Black-box: Используйте package myfunc_test, который гарантирует, что вы используете только экспортированные идентификаторы.
  • Тестирование белого ящика: Используйте package myfunc, чтобы у вас был доступ к неэкспортированным идентификаторам. Хорошо для модульных тестов, требующих доступа к неэкспортированным переменным, функциям и методам.

Сравнение стратегий, перечисленных в вопросе

  • Стратегия 1: В файле myfunc_test.go используется package myfunc. В этом случае тестовый код в myfunc_test.go будет в том же пакете, что и код, протестированный в myfunc.go, который myfunc в этом примере.
  • Стратегия 2: В файле myfunc_test.go используется package myfunc_test - в этом случае тестовый код в myfunc_test.go "будет скомпилирован как отдельный пакет, а затем связан и запущен с основным тест двоичный." [Источник: строки 58-59 в test.go исходный код]
  • Стратегия 3: В файле myfunc_test.go используется package myfunc_test, но импортируется myfunc с использованием точечной нотации. Это вариант стратегии 2, но использует точечную нотацию для импорта myfunc.

Ответ 2

Это зависит от объема ваших тестов. Тесты высокого уровня (интеграция, приемка и т.д.), Вероятно, должны быть размещены в отдельном пакете, чтобы гарантировать, что вы используете пакет через экспортированный API.

Если у вас большой пакет с множеством внутренних компонентов, которые нужно подвергнуть тестированию, используйте тот же пакет для своих тестов. Но это не приглашение для ваших тестов на доступ к любому частному состоянию. Это сделало бы рефакторинг кошмаром. Когда я пишу structs в go, я часто реализую интерфейсы. Это те методы интерфейса, которые я вызываю из своих тестов, а не все вспомогательные методы/функции по отдельности.

Ответ 3

Вы должны использовать стратегию 1, когда это возможно. Вы можете использовать специальное имя пакета foo_test, чтобы избежать циклов импорта, но в основном там, поэтому стандартная библиотека может быть протестирована с помощью того же механизма. Например, strings не может быть протестирован со стратегией 1, поскольку пакет testing зависит от strings. Как вы сказали, со стратегией 2 или 3 у вас нет доступа к частным идентификаторам пакета, поэтому обычно лучше не использовать его, если вам не нужно.

Ответ 4

Я не могу комментировать, потому что у меня нет 50 представителей... (как хромает). Итак, чтобы ответить на вопрос @PickBoy выше:

Я видел, что сильный пакет использует Стратегию 3, но я не могу понять, в чем смысл? - 2 дня назад

Я раздвоил пакет и внес изменения, и теперь все мои тесты пытаются импортировать исходное хранилище вместо моего раздвоенного пакета. В Стратегии 3 мне не нужно менять "github.com/original/link" на "github.com/my/fork", потому что он просто ссылается на "." вместо.