Contenu connexe Similaire à Tieto tdd from-dreams_to_reality_s.narkevicius_v.pozdniakov_2013 (1) (20) Plus de Agile Lietuva (20) Tieto tdd from-dreams_to_reality_s.narkevicius_v.pozdniakov_2013 (1)1. TDD – from dreams to reality
© 2013 Tieto Corporation
Saulius Narkevičius. Viačeslav Pozdniakov.
2. Viačeslav
Saulius
Programming architect
24 hours developer
(~ 23 years of programing)
(~ 9 years of programing)
University lector
University lector
Assembler, …, Java, ...
Scala, Haskell, Java, ...
Desktop / Web
Desktop / Web
UI / Middleware / Database
Databases / Middleware
Waterfall / Agile / Whatever
Agile / Whatever
© 2013 Tieto Corporation
3. Three TDD steps
© 2013 Tieto Corporation
1. Failing test
2. Production
code
3. Refactor
4. Drives simple
code design
Safety net for
refactoring
TDD dream
Fast
feedback
Keeps
developers head
“empty” –
everything is in
code
© 2013 Tieto Corporation
Documentation
6. Java solution 20 seconds later
© 2013 Tieto Corporation
int averageOf(int a, int b) {
return (a + b) / 2;
}
7. Does not compile –
No averageOf()
exists yet!
1. Red – write a failing test
© 2013 Tieto Corporation
@Test public void smokeTestAverage() {
assertThat(averageOf(2, 4), is(3));
}
8. Test passes
successfully
2. Green – just enough production code
@Test public void smokeTestAverage() {
assertThat(averageOf(2, 4), is(3));
}
© 2013 Tieto Corporation
int averageOf(int a, int b) {
return 3;
}
9. Nothing to
refactor yet
3. Refactor – make code cleaner
@Test public void smokeTestAverage() {
assertThat(averageOf(2, 4), is(3));
}
© 2013 Tieto Corporation
int averageOf(int a, int b) {
return 3;
}
10. Hmm, code is
really dumb…
Repeat: red, green, refactor
@Test public void smokeTestAverage() {
assertThat(averageOf(2, 4), is(3));
assertThat(averageOf(10, 20), is(15));
}
© 2013 Tieto Corporation
int averageOf(int a, int b) {
return (a == 10) ? 15 : 3;
}
11. Done!!!
Took longer with
tests :(
Let’s triangulate
@Test public void smokeTestAverage() {
assertThat(averageOf(2, 4), is(3));
assertThat(averageOf(10, 20), is(15));
assertThat(averageOf(-8, -16), is(-12));
}
© 2013 Tieto Corporation
int averageOf(int a, int b) {
return (a + b) / 2;
}
12. FAILED: Expected
2147483647 but
was -1
Edge cases
@Test public void edgeCasesForAverage() {
assertThat(averageOf(MAX, MAX), is(MAX));
assertThat(averageOf(MIN, MIN), is(MIN));
}
© 2013 Tieto Corporation
int averageOf(int a, int b) {
return (a + b) / 2;
}
13. Tests pass
successfully
Avoid overflow by using subtraction
© 2013 Tieto Corporation
@Test public void edgeCasesForAverage() {
assertThat(averageOf(MAX, MAX), is(MAX));
assertThat(averageOf(MIN, MIN), is(MIN));
}
int averageOf(int a, int b) {
int high = (a > b ? a : b);
int low = (a > b ? b : a);
return low + ((high - low) / 2);
}
14. FAILED:
Expected 0 but was
-2147483648
One more edge case
© 2013 Tieto Corporation
@Test public void edgeCasesForAverage() {
assertThat(averageOf(MAX, MAX), is(MAX));
assertThat(averageOf(MIN, MIN), is(MIN));
assertThat(averageOf(MIN, MAX), is(0));
}
int averageOf(int a, int b) {
int high = (a > b ? a : b);
int low = (a > b ? b : a);
return low + ((high - low) / 2);
}
15. When TDD shines
→ Clear requirements
→ Requirements do not change every hour
→ Sample tests are in place
→ Test execution is fast and one click away
→ Testing environment similar to production.
© 2013 Tieto Corporation
16. → What to test?
→ Building data sets for tests
TDD in the
real world
→ Sample tests to start from
→ Legacy code may not be testable
→ What not to test?
© 2013 Tieto Corporation
17. “What to test?” is a wrong question
→ We are not testing but specifying sample usage scenarios
→ What do you want to specify / describe?
→ Testing frameworks speak “Specs”:
•
RSpec, Cucumber, Jasmine, Concordion, ...
→ TDD thought leaders done this years ago:
•
Dan North, Dave Astels, Robert C Martin (a.k.a. Uncle Bob), ...
→ Naming is everything (see: Specification by Example)
© 2013 Tieto Corporation
18. Sample test
@Test public void testCreatBookWithFullData() {
tester.login();
tester.startPage(BookEditPage.class);
FormTester formTester = tester.newFormTester("newBookForm");
formTester.setValue("main.container:title", “Some book title");
formTester.setValue("main.container:author", “Some author");
formTester.setValue("main.container:year", "1999");
formTester.setValue("main.container:publisherPageUrl", "www.newBook.lt");
formTester.setValue("main.container:pages", "222");
formTester.setValue("main.container:publisherName", “Some publisher");
formTester.setValue("main.container:series", “Very interesting series");
formTester.setValue("main.container:originalName", “some original name");
formTester.submit("submit");
tester.assertRenderedPage(BookPage.class);
tester.assertLabel("title", " Some book title");
tester.assertLabel("authorPanel:authors:0:author.link:author", "Some author");
tester.assertContains("some original name");
tester.assertLabel("years.link:year", "1999");
tester.assertLabel("publisher.link:publisher.name", "Some publisher");
tester.assertLabel("pages", "222");
© 2013 Tieto Corporation
}
19. Same test as spec
public void creating_new_book_scenario() {
givenCurrentUserIsAnAdministrator();
Book newBook = createNewBook();
show(BookEditPage.class);
fillFormFieldsWith(newBook);
submitForm();
expectCurrentPageIs(BookPage.class);
expectCurrentPageDisplaysAttributesOf(newBook);
© 2013 Tieto Corporation
}
20. Data sets for specs
// create or load from test DB
© 2013 Tieto Corporation
interface TypicalUsers {
User admin();
User guest();
User reviewer();
User author();
}
interface TypicalBooks {
Book basicBook();
Book bookWithThreeAuthors();
Book bookWithReview();
}
21. Sample spec for persistence
© 2013 Tieto Corporation
@Test public void orm_mappings_are_ok () {
loadAndPrintSomeEntitiesOf(Book.class);
}
22. Sample spec for UI
© 2013 Tieto Corporation
@Test public void renders_successfully() {
new WicketTester().startPage(NewClientPage.class);
}
23. Sample spec for business logic (WS)
© 2013 Tieto Corporation
@Test public void extending_book_loan() {
process(requestToBookLoanHandler(”extend_loan_request.xml"));
expectResponse(”loan_approved_response.xml");
}
24. Writing testable code
Is writing tests easy?
Yes, it is.
The art is in writing testable production code!
→ See short guide: “Writing Testable Code”
© 2013 Tieto Corporation
25. What not to specify:
technical viewpoint
→ Getters, setters and member variables
→ One line functions
→ GUI – make as thin and dumb as possible
→ Frameworks – things you do not control
→ Things which are hard to code - by trial and error.
© 2013 Tieto Corporation
26. What not to specify:
process viewpoint
→ Accelerated Agile – buzzword from Dan North
→ Some ingredients of accelerated agile:
•
•
•
•
developers become domain experts
short iterations (days, hours) – less chance for bugs
deliver as soon as possible – even without specs
discover knowledge from real usage
→ Write specs for code which survived real usage
→ Works for some projects
© 2013 Tieto Corporation
27. Know what
to specify
Think
“specs”
not “tests”
© 2013 Tieto Corporation
Use TDD
wisely
Know what
not to
specify
TDD:
from DREAMS to
Simple smoke
REALITY
Simplify writing
specs by “Writing
Testable Code”
specs are a
good investment
Real specs
come from
real usage
Notes de l'éditeur SlxWho attended talk given by RaimondsSimanovskis?Who has written a single test last month?This talk is about things which are not covered in TDD-selling books Slx ir SlavaA lot of hand rising for reality check that we are not dreaming.We will together learn a lot from handrising.How many developers in the room?Add something fun SlavaWho practices pure TDD? SlavaWho would to live in such TDD dream? SlavaNuo 5 min. Slava Slava Slava Slava SlavaHere comes triangulation! You must have at least 2 examples before thinking about more generic approach. Slava Slava Slava Slava SlxWho works with really clear requirements?Saulesspinduliai, kumstis - liuks Slx - these items came out from face-to-face conversationsWho works with really clear requirements?Nuošiol prezentacijoje mes rupinsimes šiais klausimais. Slx - Who already thinks and talks about specs? Slx Slx SlavaTypical personas and entities are part of specificationOn the contrary: tests are encouradged to be isolated SlavaWho uses Object Relational Mapping framework?This is FAST FEEDBACK in the first place, and SPEC in a second place. SlavaWho uses web framework which allows such tests?NO LOGIC – just SAFETY NET SlavaWho uses web framework which allows such tests?NO LOGIC – just SAFETY NET SlxTest First approach make production code testable SlavaDo not test things which are tested indirectly SlxFrom TDD/BDD purists.Test are not thrown away – just written after feedback. Usually for the core part of the system.Who wrote nearly-bug-free software without tests?Baisusgreitis SlxFrom TDD/BDD purists.Test are not thrown away – just written after feedback. Usually for the core part of the system.Who wrote nearly-bug-free software without tests? SlavaWho uses web framework which allows such tests?NO LOGIC – just SAFETY NET