Тестирование и интеграция
Часть раздела Объектно-ориентированное программирование путешествия по GO на Coddy — урок 104 из 107.
Задание
ЛегкоДавайте доведем нашу систему управления библиотекой до совершенства, написав тесты, которые подтвердят, что все работает правильно! Вы создадите тестовый файл для проверки основной функциональности вашей библиотеки — убедитесь, что книги можно правильно брать и возвращать, а ошибочные ситуации обрабатываются корректно.
Вы организуете свой код в пяти файлах:
book.go: Ваша структураBookс полямиID,Title,Author,ISBNиAvailable. Включите конструкторNewBook, который инициализирует книги как доступные.user.go: Ваша структураUserс полямиID,Name,EmailиBorrowedBooks. Включите конструкторNewUser.library.go: Ваша структураLibraryс картами (maps) для книг и пользователей, а также методамиNewLibrary,AddBook,AddUser,BorrowиReturn. МетодBorrowдолжен возвращать ошибки для случаев: неверный пользователь, неверная книга или недоступная книга. МетодReturnдолжен возвращать ошибки для случаев: неверный пользователь, неверная книга или книга не была взята.library_test.go: Здесь вы напишете свои тестовые функции! Создайте тесты, которые проверяют:TestBorrowSuccess— Убедитесь, что заимствование доступной книги проходит успешно (ошибка не возвращается), книга становится недоступной, а ID книги добавляется в список заимствованных книг пользователя.TestBorrowUnavailable— Убедитесь, что попытка взять уже занятую книгу возвращает ошибку.TestBorrowInvalidUser— Убедитесь, что заимствование с несуществующим ID пользователя возвращает ошибку.TestReturnSuccess— Убедитесь, что возврат заимствованной книги проходит успешно, книга снова становится доступной, а ID книги удаляется из списка заимствованных книг пользователя.
Каждый тест должен настраивать свою собственную библиотеку с необходимыми книгами и пользователями, выполнять операцию и проверять результаты с помощью
t.Errorилиt.Errorfв случае провала проверок.main.go: Запустите свои тесты вручную и сообщите о результатах. Считайте название теста для выполнения (borrow_success,borrow_unavailable,borrow_invalid_userилиreturn_success). В зависимости от названия теста настройте соответствующий сценарий и выведитеPASS, если все проверки пройдены, илиFAIL: [reason], если какая-либо проверка не удалась.
Будут предоставлены следующие входные данные:
- Название теста:
borrow_success,borrow_unavailable,borrow_invalid_userилиreturn_success
Для каждого теста используйте эти стандартные тестовые данные:
- Книга: ID
B001, TitleGo Programming, AuthorJohn Doe, ISBN123-456 - Пользователь: ID
U001, NameAlice, Emailalice@test.com
Например, если дано:
borrow_successВаш вывод должен быть:
PASSИ если дано:
borrow_unavailableВаш вывод должен быть:
PASSИ если дано:
borrow_invalid_userВаш вывод должен быть:
PASSИ если дано:
return_successВаш вывод должен быть:
PASSДля borrow_success: Создайте библиотеку, добавьте книгу и пользователя, возьмите книгу, проверьте отсутствие ошибки, убедитесь, что книга недоступна, убедитесь, что книга есть в списке заимствованных у пользователя.
Для borrow_unavailable: Создайте библиотеку, добавьте книгу и пользователя, установите Available книги в false, попытайтесь взять книгу, убедитесь, что возвращена ошибка.
Для borrow_invalid_user: Создайте библиотеку, добавьте только книгу (без пользователя), попытайтесь взять книгу, используя ID пользователя U001, убедитесь, что возвращена ошибка.
Для return_success: Создайте библиотеку, добавьте книгу и пользователя, сначала возьмите книгу, затем верните ее, проверьте отсутствие ошибки, убедитесь, что книга снова доступна, убедитесь, что список заимствованных книг пользователя пуст.
Написание тестов гарантирует правильную работу вашей библиотечной системы и дает вам уверенность при внесении изменений без нарушения существующей функциональности!
Попробуйте сами
package main
import (
"bufio"
"fmt"
"os"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin)
testName, _ := reader.ReadString('\n')
testName = strings.TrimSpace(testName)
// Стандартные тестовые данные
// Book: ID "B001", Title "Go Programming", Author "John Doe", ISBN "123-456"
// User: ID "U001", Name "Alice", Email "alice@test.com"
switch testName {
case "borrow_success":
// TODO: Проверить, что выдача доступной книги проходит успешно
// 1. Создать библиотеку, добавить книгу и пользователя
// 2. Взять книгу
// 3. Проверить: нет ошибки, книга недоступна, у пользователя книга в списке
// Вывести "PASS", если все проверки пройдены, или "FAIL: [причина]", если какая-то не прошла
fmt.Println("FAIL: not implemented")
case "borrow_unavailable":
// TODO: Проверить, что выдача недоступной книги возвращает ошибку
// 1. Создать библиотеку, добавить книгу и пользователя
// 2. Установить Available книги в false
// 3. Попытаться взять книгу
// 4. Проверить, что возвращена ошибка
fmt.Println("FAIL: not implemented")
case "borrow_invalid_user":
// TODO: Проверить, что выдача несуществующему пользователю возвращает ошибку
// 1. Создать библиотеку, добавить только книгу (без пользователя)
// 2. Попытаться взять книгу, используя ID пользователя "U001"
// 3. Проверить, что возвращена ошибка
fmt.Println("FAIL: not implemented")
case "return_success":
// TODO: Проверить, что возврат взятой книги проходит успешно
// 1. Создать библиотеку, добавить книгу и пользователя
// 2. Сначала взять книгу
// 3. Вернуть книгу
// 4. Проверить: нет ошибки, книга доступна, список пользователя пуст
fmt.Println("FAIL: not implemented")
default:
fmt.Println("FAIL: unknown test")
}
}
Все уроки раздела Объектно-ориентированное программирование
1Основы ООП в Go
Внешние файлыРабочее пространство и модули GoПакеты и импортыЭкспортируемые и неэкспортируемые именаВведение в ООП в GoСтруктуры как классыОпределение методов структурПолучатели-указатели и получатели-значенияИнициализация структурФункции-конструкторыИтоги — Простой калькулятор4Интерфейсы
Введение в интерфейсыНеявная реализацияИнтерфейс как контрактПустой интерфейс (any)Утверждение типаПереключатель типовКомпозиция интерфейсовИнтерфейсы Stringer и ErrorПовторение: Калькулятор фигур7Инкапсуляция
Экспортируемые и неэкспортируемые поляИнкапсуляция на уровне пакетовГеттеры и сеттерыСокрытие информации в GoИтоги — Записи о студентах10Обобщения (Generics) (Go 1.18+)
Введение в GenericsПараметры типовОграничения типовОбобщенные структурыОбходной путь для обобщенных методовИтоги — Обобщенная коллекция13Паттерны проектирования. Часть 1
Введение в паттерны проектированияПаттерн SingletonПаттерн FactoryПаттерн Abstract FactoryПаттерн ObserverПаттерн Strategy2Глубокое погружение в типы и структуры
Базовые и составные типыОпределение пользовательских типовТеги структурАнонимные структурыВложенные структурыНулевые значения и значения по умолчаниюПовторение — Контактная книга5Композиция вместо наследования
Почему в Go нет наследованияОсновы встраивания структурПродвижение методовВстраивание нескольких структурВстраивание против агрегацииЗатенение встроенных методовИтоги — Иерархия сотрудников8Обработка ошибок и ООП
Интерфейс errorПользовательские типы ошибокОбертывание ошибок (fmt.Errorf)Sentinel-ошибкиerrors.Is() и errors.As()Panic, Defer и RecoverИтоги — Парсер файлов11Стандартная библиотека и ООП
io.Reader и io.Writersort.InterfaceИнтерфейс fmt.Stringerencoding/json со структурамиИнтерфейс http.HandlerПовторение: модели REST API14Паттерны проектирования. Часть 2
Паттерн КомандаПаттерн АдаптерПаттерн ДекораторПаттерн Шаблонный методПаттерн СостояниеПаттерн КомпоновщикMiddleware как Декоратор3Указатели и память
Основы указателей в GoУказатели на структурыПередача по значению и по ссылкеФункция new()Сборка мусора в GoПовторение: Конструктор связного списка6Полиморфизм в Go
Полиморфизм через интерфейсыУтиная типизация в GoПравила реализации интерфейсовПолиморфные коллекцииВнедрение зависимостейИтоги — Обработчик платежей9Конкурентность и ООП
Основы горутинКаналы и взаимодействиеБуферизованные и небуферизованные каналыОператор selectsync.Mutex и sync.RWMutexsync.WaitGroupПроектирование потокобезопасных структурПовторение — Worker Pool12Продвинутые концепции ООП
Паттерн функциональных опцийПаттерн Builder в GoЦепочки вызовов методовПсевдонимы и определения типовОсновы рефлексииОбзор генерации кода15Проект: Управление библиотекой
Обзор и структура проектаСтруктуры Book и User