www.machinelearningmastery.ru

Машинное обучение, нейронные сети, искусственный интеллект
Header decor

Home

Простое руководство по модульному тестированию в Голанге

Дата публикации Oct 3, 2019

фотоБлейк КоннеллинаUnsplash

Модульное тестирование является обязательным компонентом написания хорошего кода. Каждый разработчик должен знать, как писать хорошие модульные тесты. Поскольку все больше и больше организаций используют Golang, крайне важно, чтобы, как разработчики, мы узнали о написании красивых модульных тестов для наших функций Golang.

Это руководство является основным введением в модульное тестирование Golang. Он не охватывает сложные темы, такие как издевательства, бенчмаркинг и идемпотентность. Я постараюсь осветить эти темы в будущем.

Итак, начнем.


Код

Функциональность, которую мы тестируем сегодня, довольно проста. У нас есть интерфейсOperatorкоторый имеет два метода.

Generateберет два целых числа и создает ключ на основе некоторого шаблона, иDegenerateберет ключ и декодирует целые числа, из которых ключ был создан.

Если ключ недействителен,Degenerateвыдает ошибку.

Теперь давайте создадим реализацию этого интерфейса под названиемkeyOp,

Логика в этом довольно проста.

Мы предоставляем функциюGetKeyOperator, который создает новыйkeyOpэкземпляр с шаблоном%v_%v,

Generate()объединяет два целых числа в шаблон.

Degenerate()демарширует ключ в соответствующие два целых числа. Если ключ не соответствует структуре шаблона, которая определяется положением_символ, мы возвращаем ошибку.

Основная функция теперь может использовать эти методы, чтобы увидеть функциональность.

Как и ожидалось, на выходе это:

key=2_3, a=2, b=3

Теперь, когда мы установили функциональность. Давайте приступим к тестированию.


тестирование

Сначала мы создадим файл с именемoperators_test.goв том же каталоге, что иoperators.go, Go автоматически ищет файлы в каталоге с_testсуффикс при запускеgo testкоманда.

Теперь давайте напишем контрольные примеры для нашегоGenerate()а такжеDegenerate()функции.

Для тестовых функций запустите имя функции сTest_, а затем предоставил структуру для этого теста. Тогда вы захотите написать название метода. Например, наши методы испытаний будут названыTest_keyOp_Generateа такжеTest_keyOp_Degenerateсоответственно.

Все методы испытаний должны принятьtesting.Tпараметр.Tтип, передаваемый в функции тестирования для управления состоянием теста и поддержки отформатированных журналов испытаний.

Итак, подпись метода такова:

func Test_keyOp_Generate(t *testing.T)

Аргументы заGenerateдва целых числа. Итак, давайте определимсяargsхранить эти два целых числа.

type args struct {
x int
y int
}

Теперь давайте определимся с требованиями нашего теста.

Мы структурируем тесты по их названию, а также по аргументам теста и желаемому результату. Мы также добавим несколько таких тестов:

tests := []struct {
name string
args args
want string
}{
{
name: "success",
args: args{
x: 5,
y: 50,
},
want: "5_50",
},
{
name: "success large integers",
args: args{
x: 50000,
y: 999999,
},
want: "50000_999999",
},
}

Как видите, мы добавили два теста. Один для общего успеха, а другой для тестирования больших входных размеров. Мы также определили правильный результат для этих тестов.

Теперь мы можем просто перебратьtestнарезать и запустить тесты.

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
kp := GetKeyOperator()
if got := kp.Generate(tt.args.x, tt.args.y); got != tt.want {
t.Errorf("keyOp.Generate() = %v, want %v", got, tt.want)
}
})
}

Мы используемRunметод, представленный наtesting.TSTRUCT.Runпринимает имя теста и функцию (func (t *testing.T)) в качестве входных параметров и возвращаетbool, Он запускает функцию, предоставленную во втором параметре, в отдельной программе и блокируется до тех пор, пока не вернется.

вifусловие, мы создаем и экземплярkpизkeyOpи проверить, получили ли мы ожидаемый результат или нет, проверивgot!=want, Если тест не пройден, мы записываем сообщение об ошибке вtesting.Tиспользование объектаt.Errorf()и правильно структурировать наше сообщение об ошибке.

Наша полная функция тестирования дляGenerateэто здесь.

Теперь давайте попробуем сделать то же самое дляDegenerate()метод. Изменения здесь будутargsпримет только одинstringв качестве параметра.

Кроме того, так как мы возвращаем три результата изDegenerate()мы проверим ихwantX,wantY, а такжеwantErrпеременные.wantErrэтоboolкоторый обнаружит, получили ли мы ненулевую ошибку от тестируемого метода.

type args struct {
s string
}
tests := []struct {
name string
args args
wantX int
wantY int
wantErr bool
}{
{
name: "success",
args: args{
s: "40_99",
},
wantX: 40,
wantY: 99,
},
{
name: "failure",
args: args{
s: "4099",
},
wantErr:true,
},
}

Как видите, мы добавили два простых тестовых случая: один для успешного тестирования, а другой с неверным вводом для неудачного тестирования. вsuccessтест, мы проверяем правильные значенияxа такжеyс помощьюwantXа такжеwantYв то время как вfailureтест, мы проверяем на ненулевую ошибку, используяwantErr,

Мы снова пишем цикл for, перебирая кусочки тестов и проверяя совпадения на ожидаемые результаты. На этот раз мы проверяем все три параметра. Полная функция тестирования дляDegenerateэто здесь:


Запуск тестовых случаев

Мы можем запустить наши тесты, используяtestкоманда.go testимеет множество функций, которые можно найти в его подробной документацииВот,

Самое простое использованиеgo testэто запустить все тесты в текущем каталоге и всех подкаталогах. Это можно сделать, выполнив следующую команду:

go test ./...

Вывод

Я надеюсь, что это руководство послужит простым введением в модульное тестирование методов Голанга.

Оригинальная статья

Footer decor

© www.machinelearningmastery.ru | Ссылки на оригиналы и авторов сохранены. | map