Upload
andrey-volobuev
View
177
Download
0
Embed Size (px)
Citation preview
Unit тестирование iOS приложений
Андрей Волобуев
Что такое unit тесты
Для чего тестировать
Когда тестировать
Виды unit тестов
Двойники для тестов
Управление зависимостями
Лучшие практики
Тезисы
Что такое unit тесты ?
Модульное тестирование, или юнит-тестирование (англ. unit testing) — процесс в программировании, позволяющий проверить на корректность отдельные модули исходного кода программы.
Википедия
Что такое unit тесты ?Класс Тест класс
Метод 1
Метод 2
Тест метод 1.2
Тест метод 2.1
Тест метод 1.1
.
.
.
Для чего тестировать ?
Уверенность в корректности работы программы
Возможность рефакторинга
Исполняемая документация
Исполняемые требования
Работа с CI системами
Доказательство что баг исправлен
Когда тестировать ?TDD - сначала пишется тест
Refactor
Red
Green
Когда тестировать ?
Обычное тестирование - тесты пишутся после кода
Когда тестировать
Вопрос в том насколько после
Виды unit тестов
Возвращаемый результат
Состояние
Поведение
Двойники для тестов
Клиент Официант Повар
Ресторан
Двойники для тестов
Клиент Официант Тест повар
Ресторан
Двойники для тестов
Stub - возвращают заранее предопределенный результат
Mock - содержат логику для проверки поведения
Управление зависимостями
Dependency injection
// Менеджер ресторана должен сказать нам какой стол свободен struct Manager{ // Он обращается к сервису реализующему протокол var tablesService: FreeTableProvider func getFreeTable() -> Int{ let tableId = tablesService.getTable() return tableId } // Constructor injection init(tablesService: FreeTableProvider = ProductionTableProvider()){ self.tablesService = tablesService } } // Протокол для сервиса protocol FreeTableProvider{ func getTable() -> Int }
struct ProductionTableProvider: FreeTableProvider{ func getTable() -> Int { let tableId = makeLongRunningRequestAndReturnTable() return tableId } private func makeLongRunningRequestAndReturnTable() -> Int { . . . } }
class StubFreeTableProvider: FreeTableProvider{ func getTable() -> Int { return 42 } }
class ManagerTests: XCTestCase {
override func setUp() { super.setUp() } override func tearDown() {
super.tearDown() } func testManagerRetunsFreeTable(){ let stubFreeTableProvider = StubFreeTableProvider() let manager = Manager(tablesService: stubFreeTableProvider) let tableId = manager.getFreeTable() XCTAssertEqual(tableId, 42, "Менеджер возвращает столик полученный от сервиса") } }
protocol OrderExecutor{ func executeOrder() } // Теперь мы тестируем внутреннее состояние официанта struct Waiter{
// Столик с которым работает официант var currentTableId: Int?
var cook: OrderExecutor func excecuteOrder(){ cook.executeOrder() } // Функция позвать официанта к столику mutating func call(toTable tableId: Int){ currentTableId = tableId }
init(orderExecutor: OrderExecutor){ self.cook = orderExecutor } }
class WaiterUnitTests: XCTestCase { override func setUp() { super.setUp() } override func tearDown() {
super.tearDown() } func testWaiterServesTableAfterCalling(){ var waiter = Waiter() let tableId = 42 waiter.call(toTable: tableId) XCTAssertEqual(tableId, waiter.currentTableId, "Официанта приходит к столику") } }
// Тот кто реализует этот протокол может исполнять заказы protocol OrderExecutor{ func executeOrder() } // Теперь поведение официанта struct Waiter{
var currentTableId: Int?
// Тот кто реализует этот протокол может исполнять заказы var cook: OrderExecutor
// Функция передать заказ повару func excecuteOrder(){
cook.executeOrder() } mutating func call(toTable tableId: Int){ currentTableId = tableId }
// Constructor injection init(orderExecutor: OrderExecutor = ProductionOrderExecutor()){
self.cook = orderExecutor } }
class MockCook: OrderExecutor{ var isOrederExecuted = false func executeOrder() { isOrederExecuted = true } }
class WaiterUnitTests: XCTestCase {
func testWaiterGivesOrderToCook(){ let mockCook = MockCook() let waiter = Waiter(orderExecutor: mockCook) waiter.excecuteOrder() XCTAssertTrue(mockCook.isOrederExecuted, "Официант отдал заказ повару”) } }
Лучшие практики DRY
if, switch, for, while
Сложные setUp
Вычисляемые ожидаемые значения
Много assert на тест
Мало тестов
Много тестов
ВОПРОСЫ?