Презентацията от PlovdivConf 2014
За смъртта на TDDСтефан Кънев http://skanev.com/ @skanevPlovdivConf 17 май 2014 Пловдив
View Slide
DHH(David Heinemeier Hansson)
Кратката версия: греши
Риторика в две стъпки
Test-driven
Представя малка част зацялата картинка1.
нишови практики
Казва: въобще не са добраидеяИма предвид: не му вършатработа за Basecamp2.
Q.E.D.
все пак:повдига валиднипритеснения
Диалог
Дългата версия: …
GOOSMocksTest-induced design damageHexagonal ArchitectureTDD
xyz
Здравейте, аз съм Стефан
Twitter @skanevGitHub @skanevBlog skanev.com
1. test-first vs. test-after2. hexagonal architecture3. mocking & isolation4. валидните притесненияПлан1.2.3.4.
TEST-FIRST TEST-AFTER1.
“Ако имах повече време, щях данапиша по-кратко писмо” !— Паскал, Твен, Франклин, т.н.
“The essence of writingis rewriting”
При четимия код е същото:ревизирането е ключа е къмразбираемостта
ВХОД ИЗХОД
една история
1. Зареди си кода2. Изтрий всичко от базата3. Добави в една таблица4. Добави в другата5. Свържи гиСъздай .rb файл, в който:
пусканегрешкапромяна
Същата идея: малки стъпки счеста обратна връзка
кога не работи?
Кога не правя test-first: 1. Когато не пиша тестове2. Когато не съм многонеуверен в интерфейса
2.Hexagonal Architecture
hexagonalarchitecture
шестоъгълнаархитектура
Как са направим бизнеслогиката независима отGUI-то/базата/framework-а?
ControllerModelDatabaseViewБизнес логика
Бизнес логикаOrderTransactionUser<>ControllerView<>ModelDatabase
Основен trade-off: добавямеиндирекция за да спечелимнезависимост
клъстеризацияпо-сложно, но по-сигурно
Подходящо за определениситуации, но не е универсално
прост пример с код
Disclaimerтвърде просто за ⬡
class EmployeesController < ApplicationController!def create!@employee = Employee.new(params[:employee])!!if @employee.save!redirect_to @employee, notice: "#{@employee.name} created"!else!render :new!end!end!end!
class EmployeesController < ApplicationController!def create!CreateEmployee.run(params[:employee], {!success: -> (employee) {!redirect_to employee, notice: “#{employee.name} created"!},!failure: -> (employee) {!@employee = employee!render :new!}!})!end!end
моят опит
Дава добри решения за малкичасти (5%) от приложението
Добро попълнение за торбатас трикове, но далеч не иуниверсален инструмент
Mocks3.
оплетена терминология
mocks, stubs, doubles, у-аумишлено мърляв
ControllerModelDatabaseMailChimpTwitter APIViewInternal
Тестваме взаимодействието сколабораторите, а не резултатаот страничния им ефект
mocks + test-first = GOOS
GOOS, London School
пример
ControllerModelDatabase1. Създай потребител 2. Извикай контролера 3. Провери новото име в базатабез mock-ове
ControllerModelс mock-овеuser = mock('User')! User.stub find: user! user.should_receive(:update) .with(name: 'Jon')! post :create, name: ‘Jon'!
два проблема
1. “вложени mock-ове”
mock, който връща mock,който връща mock,който връща mock
проблем в приложението
структуриранопрограмиране
if {!if {!if {!...!} else {!if {!if {!...!} else {!...!}!}!}!} else {!...!}!} else {!...!}
Опитните mockist-и приемат товакато симптом. Или има твърде много coupling, т.е.проблем в дизайна… …или в този случай е приемливо итестваме в интеграция.
2. “пречи на refactoring”
“Искам да refactor-на кода, нотестовете ми пречат”. !Странно, обикновено е обратното.
Работи добре при стабилниинтерфейси. Не е подходящоза изменчиви такива.
Изводи4.
Извод №1!“Ако не правиш TDD, не сипрофесионалист” е лъжа
Извод №1.5!“Ако не правиш _____, не сипрофесионалист” е лъжа
Извод №2!TDD се научава и обясняватрудно. Трябва да се правивнимателно.
Извод №3!There is no silver bullet.Контекста е цар.