[БЕЗ СЛОВ] В этом видео мы напишем тесты к нашей программе,
которая локализирует поток ввода, который подается ей на вход.
Для того чтобы это сделать, нам нужно нашу программу немножко «прифакторить»,
потому что сейчас она не очень подходит для написания тестов,
разве что какими-то внешними программами.
Для начала давайте вынесем весь наш код в отдельную функцию,
которая будет просто принимать параметры.
И уже тестировать будем именно эту функцию.
Назовем нашу функцию, как ни странно, uniq.
Наша функция должна принимать на вход поток,
из которого мы будем читать и поток, куда мы будем писать результат.
Это все реализуется через интерфейс Reader и Writer.
Для этого нам понадобится пакет io.
И тут мы теперь будем принимать параметры.
Input для входящего потока io.Reader
и output для вывода io.
Writer.
И для случая ошибки мы можем вернуть ошибку в этой программе — error.
Теперь переместим нашу программу в новую функцию и читать
мы теперь будем не из стандартного потока,
а из под поданного во вход Reader.
Заменяем.
Теперь нам нужно писать опять-таки не в стандартный вывод,
а в output, который нам передали.
Для этого в пакете fmt есть специальная функция: fmt.Println,
который первым аргументом принимает на вход в Reader.
Почти всё.
Теперь нам хорошо бы не паниковать, а просто возвращать ошибку,
что всё плохо: return fmt.
Errof.
Теперь возвращаем ошибку.
И последний штрих, нам нужно в конце нашей программы вернуть nill,
чтобы сказать, что никакой ошибки не было.
Вот тут nill.
Вот, вроде бы наша программа выглядит так, как надо.
Теперь давайте вызовем эту функцию.
err := uniq (os.Stdin,
и на выход os.Stdout).
И проверим ошибку.
И будем паниковать в случае, если нам что-то вернулось плохое.
if err != nul.
Просто паникуем.
panic(err.Error()) Вроде бы мы закончили.
И давайте посмотрим, работает ли наша программа.
$ go run
[БЕЗ СЛОВ] Нет,
не работает.
Errorf Отлично, наша программа заработала.
То есть она действительно выводит стандартный тот поток, который мы ей дали.
Теперь давайте посмотрим, работает ли она корректно.
Да, действительно, мы подали на вход дату,
в которой были дублирующие значения и она их отфильтровала нормально.
Всё хорошо.
Теперь давайте попробуем приступить к написанию непосредственно тестов.
Пакеты, тесты
в go должны лежать в пакете, который имеет суффикс test.
То есть main_test.go.
Давайте начнем.
package main.
Мы должны будем находиться в том же пакете.
Нам понадобятся некоторые функции из стандартных пакетов.
Давайте их импортируем.
import.
Нам понадобится strings, bytes и testing
— непосредственно пакет для тестирований.
Все тесты в go начинаются с префикса test.
Test (давайте напишем) Ok.
И принимает на вход единственный параметр тестирующего модуля.
(t *testing.T)
Теперь нам надо вызвать нашу
программу с чем-то: err :=
uniq () if err != nii.
Теперь мы должны сказать, если нам err,
если наша программа вернула какую-то ошибку,
то мы должны сказать, что тест свебился: t.Errorf
("test for OK Failed").
Теперь нужно что-то подать на вход.
Для начала нам нужны какие-то тестовые данные.
Давайте их создадим.
var testOk (используем «бэктики» для того,
чтобы у нас сохранялся перевод строки) 1 2 3
4 5 Теперь создадим новый Reader,
[БЕЗ СЛОВ] NewReader,
который принимает (strings.
NewReader).
А в него уже передадим нашу строку.
Вот так.
То есть ввод у нас готов.
Передаём его в uniq.
Теперь нам нужен вывод.
Воспользуемся функцией New и создадим просто буфер-байт,
куда будет писаться вывод: new(bytes.
Buffer) — новый буфер.
И будем писать его.
Хорошо.
Теперь наша программа вроде бы должна заработать — наш тест.
Давайте попробуем его запустить: $ go test − v.
v — это значит verbals.
Мы хотим видеть результаты: какие тесты заработали, а какие закончились неудачей.
main_test.go.
Что-то я импортировал неправильно.
Var.
Ага, Var не нужен.
Итератор короткого присваивания.
Отлично, теперь запустим.
undefined: uniq.
Тут fails.
Давайте без ничего.
Просто тест − v.
Отлично, наш тест прошел корректно.
То есть никакой ошибки не было.
Однако мы не проверили то, что нам записалось в вывод.
Это значит, что наша программа могла отработать,
ошибку не вернуть, но в вывод записать что-то неправильно.
Это нужно исправить.
Для этого я, собственно, делал out,
куда будет записываться результат работы программы.
Теперь нам нужен эталон результата, с которым мы будем сравнивать.
Давайте его создадим: var testOkResult
= 1 2 3 4
5 Хорошо, теперь проверяем.
if out.
String () результат в виде строки, который записался в наш буфер.
Если он не равен нашему эталонному результату testOkResult,
то мы должны сказать, что тест вернулся плохой.
("test for Ok Failed- error") ("test for
Ok Failed- results not match") Давайте попробуем запустить.
Смотрите, мы что-то вывели неправильно.
Давайте попробуем посмотреть, что (%v %v).
В данном случае я пытаюсь вывести те данные,
которые к нам приходят и результат.
result := out.String () result,
result и testOkResult.
Запускаем.
И что нам выводится?
1 2 3 4 5 Вроде бы все должно быть нормально.
[БЕЗ СЛОВ]
1 2 3 4 5 6
1 2 3 4 5 6 Ага,
дело в том, что мы использовали Println,
который в конце выводит перевод строки.
Нам также нужно вывести в нашем результате перевод строки, чтобы понять, что не так.
Давайте попробуем запустить еще раз.
И теперь наши тесты проходят корректно.
Отлично.
Но это не все, что можно сделать.
Еще у нас остался случай, когда мы должны вернуть ошибку в случае,
если поток ввода не отсортирован.
Давайте напишем еще один тест.
func testFor Error()t.
"testing.T) [БЕЗ СЛОВ] var.
Теперь нам нужны какие-то входящие данные,
на которых наша программа просто заругается.
Давайте их создадим.
Например, 1
var testFail
= 1 2 1 И на самом деле этого будет достаточно,
чтобы проверить, что программа выходит с ошибкой, если вход не отсортирован.
Теперь на самом деле нам достаточно скопировать фактически то же самое.
И теперь мы должны ругаться только на том случае,
если нам программа не вернула никакую ошибку в нашу функцию.
Давайте теперь будем ругаться, что если вернулся nill в ошибке,
то в этом случае мы ругаемся.
Запустим еще раз.
Test должен быть с большой буквы.
err 1 2
3 Смотрите, нам вернулась какая-то ошибка.
Давайте посмотрим, что там.
[БЕЗ СЛОВ]
[БЕЗ СЛОВ]
Ага.
[БЕЗ СЛОВ] err
!= [БЕЗ
СЛОВ] Давайте
теперь укажем правильные входящие данные.
Вот теперь всё, программа должна отрабатывать корректно.
Давайте запустим еще раз.
И наша программа успешно выполняется.
Это значит, что мы написали не просто программу,
которая уникализирует в стандартный вход, но и написали тесты к ней.
Это значит, что мы будем уверены, что завтра,
когда мы будем вносить изменения в эту программу, то ничего не сломается.
У нас есть тесты, которые в случае, если мы допустили какие-то ошибки,
эти тесты запустятся и нам отсигналят.