Test-Driven Development + Refactoring

Preview:

DESCRIPTION

Презентацията от WebTech 2010

Citation preview

Test-Driven Development

Refactoring

Стефан Къневhttp://skanev.com/@skanev

WebTech25 Април 2010Велико Търново

&

Sunday, April 25, 2010

за  мен

Sunday, April 25, 2010

програмистSunday, April 25, 2010

Sunday, April 25, 2010

♥Sunday, April 25, 2010

Sunday, April 25, 2010

първи  unit  testпърви  работен  ден

Sunday, April 25, 2010

презентационни  умения

Sunday, April 25, 2010

3Sunday, April 25, 2010

говоря  бързо

Sunday, April 25, 2010

210Sunday, April 25, 2010

Sunday, April 25, 2010

Аз ползвамVisual Source Safe

Sunday, April 25, 2010

Аз ползвамVisual Source Safe

Sunday, April 25, 2010

test-­‐driven  developmentrefactoring

Sunday, April 25, 2010

extreme  programming

Sunday, April 25, 2010

test-­‐driven  developmentrefactoring

Sunday, April 25, 2010

УебТех,  миналата  година

Sunday, April 25, 2010

Sunday, April 25, 2010

Sunday, April 25, 2010

Моя браузър е Гугъл, бабиното.

Sunday, April 25, 2010

Правя Test-Driven Development.

Sunday, April 25, 2010

Правя Test-Driven Development.

Пиша тестове

Sunday, April 25, 2010

конкретни  практики

Sunday, April 25, 2010

План

Sunday, April 25, 2010

План

1. Какво  е  test-­‐driven?

Sunday, April 25, 2010

План

1. Какво  е  test-­‐driven?

2. Малка  демонстрация  (видео!)

Sunday, April 25, 2010

План

1. Какво  е  test-­‐driven?

2. Малка  демонстрация  (видео!)

3. TDD  в  реалния  свят

Sunday, April 25, 2010

План

1. Какво  е  test-­‐driven?

2. Малка  демонстрация  (видео!)

3. TDD  в  реалния  свят

4. Въпроси  &  дискусия

Sunday, April 25, 2010

@skanev  Мога  да  прилагам  test-­‐drivendevelopment  извън  програмирането?Например  за  да  готвя  обяд?  #p2pvt

Sunday, April 25, 2010

План

1. Какво  е  test-­‐driven?

2. Малка  демонстрация  (видео!)

3. TDD  в  реалния  свят

4. Въпроси  &  дискусия

Sunday, April 25, 2010

refactor  |rēˈfaktər|verb

improving  the  design  of  codewithout  changing  its  behavior

Sunday, April 25, 2010

Sunday, April 25, 2010

не  добавяте  функционалност

Sunday, April 25, 2010

не  добавяте  функционалностподобрявете  код

Sunday, April 25, 2010

не  добавяте  функционалностподобрявете  кодмалки  стъпки

Sunday, April 25, 2010

защо  пишем  тестове?

Sunday, April 25, 2010

Sunday, April 25, 2010

Sunday, April 25, 2010

Sunday, April 25, 2010

Sunday, April 25, 2010

накратко,  за  да  спестимусилия  в  дългосрочен

план

Sunday, April 25, 2010

test-drivendevelopment

automatedtesting

Sunday, April 25, 2010

Инструмент

Автоматизирани тестове

Sunday, April 25, 2010

Подход

Test-DrivenDevelopment

Test-Driven Development

Sunday, April 25, 2010

“Test-­‐Driven  Development  is  not  about  testing”

—  Dan  North

Sunday, April 25, 2010

дизайн

Sunday, April 25, 2010

TDD=

Test-­‐Driven  Design

Sunday, April 25, 2010

на  практика

Sunday, April 25, 2010

Sunday, April 25, 2010

Добавяте тест1 ...за  несъществуващ  код

Sunday, April 25, 2010

Добавяте тест1 ...за  несъществуващ  код

Sunday, April 25, 2010

Добавяте тест1 ...за  несъществуващ  код

Пишете код2 ...колкото  тестът  да  мине

Sunday, April 25, 2010

Добавяте тест1 ...за  несъществуващ  код

Пишете код2 ...колкото  тестът  да  мине

Sunday, April 25, 2010

Добавяте тест1 ...за  несъществуващ  код

Пишете код2 ...колкото  тестът  да  мине

Правите подобрения3 ...докато  премахнете  повторенията

Sunday, April 25, 2010

Добавяте тест1 ...за  несъществуващ  код

Пишете код2 ...колкото  тестът  да  мине

Правите подобрения3 ...докато  премахнете  повторенията

Sunday, April 25, 2010

Добавяте тест1 ...за  несъществуващ  код

Пишете код2 ...колкото  тестът  да  мине

Правите подобрения3 ...докато  премахнете  повторенията

Sunday, April 25, 2010

Добавяте тест1 ...за  несъществуващ  код

Пишете код2 ...колкото  тестът  да  мине

Правите подобрения3 ...докато  премахнете  повторенията

Sunday, April 25, 2010

Добавяте тест1 ...за  несъществуващ  код

Пишете код2 ...колкото  тестът  да  мине

Правите подобрения3 ...докато  премахнете  повторенията

• Тествате кода, който бихте искали да имате

Sunday, April 25, 2010

Добавяте тест1 ...за  несъществуващ  код

Пишете код2 ...колкото  тестът  да  мине

Правите подобрения3 ...докато  премахнете  повторенията

• Тествате кода, който бихте искали да имате

• Няма да се компилира (липсващи методи/класове)

Sunday, April 25, 2010

Добавяте тест1 ...за  несъществуващ  код

Пишете код2 ...колкото  тестът  да  мине

Правите подобрения3 ...докато  премахнете  повторенията

• Тествате кода, който бихте искали да имате

• Няма да се компилира (липсващи методи/класове)

• Пускате го и гледате как се проваля

Sunday, April 25, 2010

Добавяте тест1 ...за  несъществуващ  код

Пишете код2 ...колкото  тестът  да  мине

Правите подобрения3 ...докато  премахнете  повторенията

• Тествате кода, който бихте искали да имате

• Няма да се компилира (липсващи методи/класове)

• Пускате го и гледате как се проваля

• Имате червен тест проверяващ функционалността

Sunday, April 25, 2010

Добавяте тест1 ...за  несъществуващ  код

Пишете код2 ...колкото  тестът  да  мине

Правите подобрения3 ...докато  премахнете  повторенията

Sunday, April 25, 2010

Добавяте тест1 ...за  несъществуващ  код

Пишете код2 ...колкото  тестът  да  мине

Правите подобрения3 ...докато  премахнете  повторенията

• Добавяте достатъчно код за да мине теста

Sunday, April 25, 2010

Добавяте тест1 ...за  несъществуващ  код

Пишете код2 ...колкото  тестът  да  мине

Правите подобрения3 ...докато  премахнете  повторенията

• Добавяте достатъчно код за да мине теста

• Нито ред повече

Sunday, April 25, 2010

Добавяте тест1 ...за  несъществуващ  код

Пишете код2 ...колкото  тестът  да  мине

Правите подобрения3 ...докато  премахнете  повторенията

• Добавяте достатъчно код за да мине теста

• Нито ред повече

• Най-простото решение, което ви хрумва

Sunday, April 25, 2010

Добавяте тест1 ...за  несъществуващ  код

Пишете код2 ...колкото  тестът  да  мине

Правите подобрения3 ...докато  премахнете  повторенията

• Добавяте достатъчно код за да мине теста

• Нито ред повече

• Най-простото решение, което ви хрумва

• Имате работещ код и зелен тест, който го потвърждава

Sunday, April 25, 2010

Добавяте тест1 ...за  несъществуващ  код

Пишете код2 ...колкото  тестът  да  мине

Правите подобрения3 ...докато  премахнете  повторенията

Sunday, April 25, 2010

Добавяте тест1 ...за  несъществуващ  код

Пишете код2 ...колкото  тестът  да  мине

Правите подобрения3 ...докато  премахнете  повторенията

• Не добавяте функционалност

Sunday, April 25, 2010

Добавяте тест1 ...за  несъществуващ  код

Пишете код2 ...колкото  тестът  да  мине

Правите подобрения3 ...докато  премахнете  повторенията

• Не добавяте функционалност

• Подобрявате кода/дизайна

Sunday, April 25, 2010

Добавяте тест1 ...за  несъществуващ  код

Пишете код2 ...колкото  тестът  да  мине

Правите подобрения3 ...докато  премахнете  повторенията

• Не добавяте функционалност

• Подобрявате кода/дизайна

• Премахвате повторенията

Sunday, April 25, 2010

Добавяте тест1 ...за  несъществуващ  код

Пишете код2 ...колкото  тестът  да  мине

Правите подобрения3 ...докато  премахнете  повторенията

• Не добавяте функционалност

• Подобрявате кода/дизайна

• Премахвате повторенията

• На всяка стъпка пускате теста

Sunday, April 25, 2010

1 2 3TDD =

Sunday, April 25, 2010

Sunday, April 25, 2010

Discla

imer

Sunday, April 25, 2010

1 2 3Кодът,  който  искате  да  имате

describe "Message" do it "should support initialization" do message = Message.new('fry@foo.bg', 'bender@foo.bg', 'Hi!') message.from.should == 'fry@foo.bg' message.to.should == 'bender@foo.bg' message.title.should == 'Hi!' endend

Sunday, April 25, 2010

1 2 3Кодът,  който  искате  да  имате

describe "Message" do it "should support initialization" do message = Message.new('fry@foo.bg', 'bender@foo.bg', 'Hi!') message.from.should == 'fry@foo.bg' message.to.should == 'bender@foo.bg' message.title.should == 'Hi!' endend

F

1)NameError in 'Message should support initialization'uninitialized constant Message/work/message/spec/message_spec.rb:5:

Finished in 0.009336 seconds

1 example, 1 failure

Sunday, April 25, 2010

1 2 3Най-­‐простата  имплементация

class Message attr_reader :from, :to, :title def initialize(from, to, title) @from = from @to = to @title = title endend

Sunday, April 25, 2010

1 2 3Най-­‐простата  имплементация

class Message attr_reader :from, :to, :title def initialize(from, to, title) @from = from @to = to @title = title endend

.

Finished in 0.009999 seconds

1 example, 0 failures

Sunday, April 25, 2010

1 2 3Пас

class Message attr_reader :from, :to, :title def initialize(from, to, title) @from = from @to = to @title = title endend

Всичко  изглежда  ок,  няма  нужда  от  рефакториране

Sunday, April 25, 2010

1 2 3Изразявате  новата  функционалност  в  тест

describe 'Message' do # ... it "should validate 'from'" do # bacon.should be_valid ⇔ assert bacon.valid? Message.new('fry@foo.bg', 'bender@foo.bg', 'Hi!').should be_valid Message.new('foo.bg', 'bender@foo.bg', 'Hi!').should_not be_valid Message.new('fry@foo', 'bender@foo.bg', 'Hi!').should_not be_valid endend

Sunday, April 25, 2010

1 2 3Изразявате  новата  функционалност  в  тест

describe 'Message' do # ... it "should validate 'from'" do # bacon.should be_valid ⇔ assert bacon.valid? Message.new('fry@foo.bg', 'bender@foo.bg', 'Hi!').should be_valid Message.new('foo.bg', 'bender@foo.bg', 'Hi!').should_not be_valid Message.new('fry@foo', 'bender@foo.bg', 'Hi!').should_not be_valid endend

.F

1)NoMethodError in 'Message should validate 'from''undefined method `valid?' for #<Message:0x100327e08>/work/message/spec/message_spec.rb:13:

Finished in 0.010847 seconds

2 examples, 1 failure

Sunday, April 25, 2010

1 2 3Прост  регулярен  израз

class Message attr_reader :from, :to, :title def initialize(from, to, title) @from = from @to = to @title = title end def valid? @from =~ /^[a-z]+@[a-z]+(\.[a-z]+)+$/ endend

Sunday, April 25, 2010

1 2 3Прост  регулярен  израз

class Message attr_reader :from, :to, :title def initialize(from, to, title) @from = from @to = to @title = title end def valid? @from =~ /^[a-z]+@[a-z]+(\.[a-z]+)+$/ endend

..

Finished in 0.011689 seconds

2 examples, 0 failures

Sunday, April 25, 2010

1 2 3Отново  пас

class Message attr_reader :from, :to, :title def initialize(from, to, title) @from = from @to = to @title = title end def valid? @from =~ /^[a-z]+@[a-z]+(\.[a-z]+)+$/ endend

Все  още  всичко  е  ОК

Sunday, April 25, 2010

1 2 3Отново,  почвате  с  тест  преди  кода

describe 'Message' do # ... it "should validate 'to'" do Message.new('fry@foo.bg', 'bender@foo.bg', 'Hi!').should be_valid Message.new('fry@foo.bg', 'bender', 'Hi!').should_not be_valid Message.new('fry@foo.bg', 'bender@foo', 'Hi!').should_not be_valid endend

Sunday, April 25, 2010

1 2 3Отново,  почвате  с  тест  преди  кода

describe 'Message' do # ... it "should validate 'to'" do Message.new('fry@foo.bg', 'bender@foo.bg', 'Hi!').should be_valid Message.new('fry@foo.bg', 'bender', 'Hi!').should_not be_valid Message.new('fry@foo.bg', 'bender@foo', 'Hi!').should_not be_valid endend

..F

1)'Message should validate 'to'' FAILEDexpected valid? to return false, got 0/work/message/spec/message_spec.rb:20:

Finished in 0.009825 seconds

3 examples, 1 failure

Sunday, April 25, 2010

1 2 3Най-­‐простата  имплементация

class Message attr_reader :from, :to, :title def initialize(from, to, title) @from = from @to = to @title = title end def valid? @from =~ /^[a-z]+@[a-z]+(\.[a-z]+)+$/ and @to =~ /^[a-z]+@[a-z]+(\.[a-z]+)+$/ endend

Sunday, April 25, 2010

1 2 3Най-­‐простата  имплементация

class Message attr_reader :from, :to, :title def initialize(from, to, title) @from = from @to = to @title = title end def valid? @from =~ /^[a-z]+@[a-z]+(\.[a-z]+)+$/ and @to =~ /^[a-z]+@[a-z]+(\.[a-z]+)+$/ endend

...

Finished in 0.010058 seconds

3 examples, 0 failures

Sunday, April 25, 2010

class Message attr_reader :from, :to, :title def initialize(from, to, title) @from = from @to = to @title = title end def valid? @from =~ /^[a-z]+@[a-z]+(\.[a-z]+)+$/ and @to =~ /^[a-z]+@[a-z]+(\.[a-z]+)+$/ endend

1 2 3Повторение

Sunday, April 25, 2010

class Message attr_reader :from, :to, :title def initialize(from, to, title) @from = from @to = to @title = title end def valid? @from =~ /^[a-z]+@[a-z]+(\.[a-z]+)+$/ and @to =~ /^[a-z]+@[a-z]+(\.[a-z]+)+$/ end private def email_valid?(address) address =~ /^[a-z]+@[a-z]+(\.[a-z]+)+$/ endend

1 2 3Малки  стъпки

Sunday, April 25, 2010

class Message attr_reader :from, :to, :title def initialize(from, to, title) @from = from @to = to @title = title end def valid? @from =~ /^[a-z]+@[a-z]+(\.[a-z]+)+$/ and @to =~ /^[a-z]+@[a-z]+(\.[a-z]+)+$/ end private def email_valid?(address) address =~ /^[a-z]+@[a-z]+(\.[a-z]+)+$/ endend

1 2 3Малки  стъпки

...

Finished in 0.010158 seconds

3 examples, 0 failures

Sunday, April 25, 2010

class Message attr_reader :from, :to, :title def initialize(from, to, title) @from = from @to = to @title = title end def valid? email_valid?(@from) and @to =~ /^[a-z]+@[a-z]+(\.[a-z]+)+$/ end private def email_valid?(address) address =~ /^[a-z]+@[a-z]+(\.[a-z]+)+$/ endend

1 2 3Ама  наистина  малки  стъпки

Sunday, April 25, 2010

class Message attr_reader :from, :to, :title def initialize(from, to, title) @from = from @to = to @title = title end def valid? email_valid?(@from) and @to =~ /^[a-z]+@[a-z]+(\.[a-z]+)+$/ end private def email_valid?(address) address =~ /^[a-z]+@[a-z]+(\.[a-z]+)+$/ endend

1 2 3Ама  наистина  малки  стъпки

...

Finished in 0.010001 seconds

3 examples, 0 failures

Sunday, April 25, 2010

class Message attr_reader :from, :to, :title def initialize(from, to, title) @from = from @to = to @title = title end def valid? email_valid?(@from) and email_valid?(@to) end private def email_valid?(address) address =~ /^[a-z]+@[a-z]+(\.[a-z]+)+$/ endend

1 2 3Готово

Sunday, April 25, 2010

class Message attr_reader :from, :to, :title def initialize(from, to, title) @from = from @to = to @title = title end def valid? email_valid?(@from) and email_valid?(@to) end private def email_valid?(address) address =~ /^[a-z]+@[a-z]+(\.[a-z]+)+$/ endend

1 2 3Готово

...

Finished in 0.009903 seconds

3 examples, 0 failures

Sunday, April 25, 2010

Sunday, April 25, 2010

пример  за  интерфейса

Sunday, April 25, 2010

принуждава  ви  да  измислите  дизайн

Sunday, April 25, 2010

дизайнът  е  основан  наобратна  връзка,  а  не

на  спекулация

Sunday, April 25, 2010

гарантира  ви  че  имате  тест

Sunday, April 25, 2010

тестовете  се  забравят

Sunday, April 25, 2010

Sunday, April 25, 2010

false  positive

Sunday, April 25, 2010

гарантира,  чекодът  е  тестваем

Sunday, April 25, 2010

sans  debugging

Sunday, April 25, 2010

Scope  creep

Sunday, April 25, 2010

Y.A.G.N.I.Y! ain’t gonna need it

Sunday, April 25, 2010

Защо?

•обратна  връзка

•мързел

•тестваем  код

•debugging

•scope  creep

Sunday, April 25, 2010

План

1. Какво  е  test-­‐driven?

2. Малка  демонстрация  (видео!)

3. TDD  в  реалния  свят

4. Въпроси  &  дискусия

Sunday, April 25, 2010

EPIC FAIL

Sunday, April 25, 2010

План

1. Какво  е  test-­‐driven?

2. Малка  демонстрация  (видео!)

3. TDD  в  реалния  свят

4. Въпроси  &  дискусия

Sunday, April 25, 2010

Терминологията  е  оплетена

Sunday, April 25, 2010

червеножълтозеленосиньо

червеносиньожълтозеленосиньо

Sunday, April 25, 2010

РитъмSunday, April 25, 2010

ДисциплинаSunday, April 25, 2010

Sunday, April 25, 2010

тестовете  трябва  да  правятприложението  по-­‐лесно  за

поддръжка

лошото  прилагане  натестове  може  да  го  направипо-­‐трудно  за  поддържане

Sunday, April 25, 2010

тестовете  трябва  да  правятприложението  по-­‐лесно  за

поддръжка

лошото  прилагане  натестове  може  да  го  направипо-­‐трудно  за  поддържане

Голям

проблем

Sunday, April 25, 2010

тестовете  са  примеркак  се  работи  с  

кодът  ви

Sunday, April 25, 2010

example-­‐driven  development

Sunday, April 25, 2010

assert  ➡  expectationtest  method  ➡  exampletest  case  ➡  example  group

Sunday, April 25, 2010

Тестовете като документацияSunday, April 25, 2010

“Test-­‐Driven  Development  is  not  about  testing”

—  Dan  North

Sunday, April 25, 2010

user  stories

Sunday, April 25, 2010

CucumberFeature: User accounts Scenario: Changing your password Given my password is "zero cool" And I just logged in When I go to the settings page And I fill in "Password" with "secret" And I fill in "Password confirmation" with "secret" And I press "Save password" Then my password should be "secret"

Sunday, April 25, 2010

CucumberFeature: User accounts ... Scenario: Confirmation fail on password change Given my password is "zero cool" And I just logged in When I go to the settings page And I fill in "Password" with "secret" But I fill in "Password confirmation" with "tetris" And I press "Save password" Then I should see "Password and confirmation didn't match" And my password should be "zero cool"

Sunday, April 25, 2010

behavior-­‐driven  development

Sunday, April 25, 2010

прилага  идеите  на  TDDвърху  feature-­‐ите*  на

приложението

*  чуждиците  не  са  куул

Sunday, April 25, 2010

1

red

red

greenrefactor

greenrefactor

2

3

45

67

RSpec

Cucumber

Sunday, April 25, 2010

continuous  testing

Sunday, April 25, 2010

ресурси

Sunday, April 25, 2010

Sunday, April 25, 2010

Sunday, April 25, 2010

Sunday, April 25, 2010

Software  Craftsmanship  Bulgaria

Sunday, April 25, 2010

http://groups.google.com/group/software_craftsmanship

Sunday, April 25, 2010

just  google  it

Sunday, April 25, 2010

План

1. Какво  е  test-­‐driven?

2. Малка  демонстрация  (видео!)

3. TDD  в  реалния  свят

4. Въпроси  &  дискусия

Sunday, April 25, 2010

Recommended