SlideShare a Scribd company logo
1 of 64
Download to read offline
Test driven development
The right way
Paweł Głasek
@PawelGlasek
The right way?
Czym TDD nie jest
Napisaniem testów wszystkich obiektów, przed
implementacją funkcjonalności.
Czym TDD nie jest
Wszystkie testy przed implementacją
● Ciężko zaprojektować odpowiedni design oraz zmieniać
go w trakcie kodowania
● Ciężko przewidzieć zmiany w obiektach klas już obecnych
w systemie
● Ciężko przewidzieć współdziałanie komponentów
● Niektóre warunki brzegowe nigdy nie występują – zbyt
duża ilość niepotrzebnych testów
● Często niepełne pokrycie
Czym TDD nie jest
Sztuką pisania unit testów
Czym TDD nie jest
Just Unit tests
● Błyskawicznie prowadzi do „przemockowania”
● Nie testuje współdziałania poszczególnych obiektów
● Pomimo zmian w powiązanych, ale zmockowanych
klasach testy przechodzą
● Niektóre warunki brzegowe nigdy nie występują – zbyt
duża ilość niepotrzebnych testów
● Brak motywacji do pisania testów
Czym TDD nie jest
Napisaniem testów po zakończeniu pisania kodu
produkcyjnego.
Czym TDD nie jest
Testy po napisaniu kodu produkcyjnego
● Brak motywacji do pisania testów po fakcie
● Wiele przypadków pozostaje nieprzetestowanych
● Niektóre warunki brzegowe nigdy nie występują
● Brak poczucia sensu pisania testów w ten sposób
● Częste problemy z testowalnością napisanego kodu
● Nuda
The right way
TDD
Agile'owa technika wytwarzania
programowania
Kent Beck
Test Driven
Development
By Example
Red – green – refactor
Zasady wujka Boba:
1. Nie wolno pisać kodu produkcyjnego, dopóki nie istnieje
failujący test.
2. Nie wolno napisać więcej testów, niż jest to niezbędne
do faila (niekompilujący się kod również uznajemy jako
fail).
3. Nie wolno pisać więcej kodu produkcyjnego niż jest to
niezbędne, by testy przechodziły.
Powiedz mi, a zapomnę.
Pokaż mi, a zapamiętam.
Rozkład liczby na czynniki
pierwsze
TDD style
Prime factorization – TDD style
class TestPrimeFactors(unittest.TestCase):
"""
Prime factors test suite.
"""
def test_prime_factors(self):
self.assertListEqual([], prime_factors(1))
Prime factorization – TDD style
>> nose2 test.prime_factors
==================================================
ERROR: test_prime_factors (test.prime_factors.TestPrimeFactors)
----------------------------------------------------------------------
NameError: global name 'prime_factors' is not defined
----------------------------------------------------------------------
Ran 1 test in 0.000s
FAILED (errors=1)
Prime factorization – TDD style
def prime_factors(number):
"""
Performs prime factorization.
:param number: Number to be factorized.
:type number: int
:rtype: list
"""
return []
Prime factorization – TDD style
>>nose2 test.prime_factors
.
----------------------------------------------------------------------
Ran 1 test in 0.001s
OK
Prime factorization – TDD style
class TestPrimeFactors(unittest.TestCase):
"""
Prime factors test suite.
"""
def test_prime_factors(self):
self.assertListEqual([], prime_factors(1))
self.assertListEqual([2], prime_factors(2))
Prime factorization – TDD style
>>nose2 test.prime_factors
F
================================================
FAIL: test_prime_factors (test.prime_factors.TestPrimeFactors)
----------------------------------------------------------------------
AssertionError: Lists differ: [2] != []
----------------------------------------------------------------------
Ran 1 test in 0.001s
FAILED (failures=1)
Prime factorization – TDD style
def prime_factors(number):
return []
def prime_factors(number):
factors = []
if number > 1:
factors.append(2)
return factors
Prime factorization – TDD style
>>nose2 test.prime_factors
.
----------------------------------------------------------------------
Ran 1 test in 0.001s
OK
Prime factorization – TDD style
class TestPrimeFactors(unittest.TestCase):
"""
Prime factors test suite.
"""
def test_prime_factors(self):
self.assertListEqual([], prime_factors(1))
self.assertListEqual([2], prime_factors(2))
self.assertListEqual([3], prime_factors(3))
Prime factorization – TDD style
>>nose2 test.prime_factors
F
================================================
FAIL: test_prime_factors (test.prime_factors.TestPrimeFactors)
----------------------------------------------------------------------
AssertionError: Lists differ: [3] != [2]
----------------------------------------------------------------------
Ran 1 test in 0.001s
FAILED (failures=1)
Prime factorization – TDD style
def prime_factors(number):
factors = []
if number > 1:
factors.append(2)
return factors
def prime_factors(number):
factors = []
if number > 1:
factors.append(number)
return factors
Prime factorization – TDD style
>>nose2 test.prime_factors
.
----------------------------------------------------------------------
Ran 1 test in 0.001s
OK
Prime factorization – TDD style
class TestPrimeFactors(unittest.TestCase):
"""
Prime factors test suite.
"""
def test_prime_factors(self):
self.assertListEqual([], prime_factors(1))
self.assertListEqual([2], prime_factors(2))
self.assertListEqual([3], prime_factors(3))
self.assertListEqual([2, 2], prime_factors(4))
Prime factorization – TDD style
>>nose2 test.prime_factors
F
================================================
FAIL: test_prime_factors (test.prime_factors.TestPrimeFactors)
----------------------------------------------------------------------
AssertionError: Lists differ: [2, 2] != [4]
----------------------------------------------------------------------
Ran 1 test in 0.001s
FAILED (failures=1)
Prime factorization – TDD style
def prime_factors(number):
factors = []
if number > 1:
factors.append(number)
return factors
def prime_factors(number):
factors = []
if number > 1:
if number % 2 == 0:
factors.append(2)
number /= 2
factors.append(number)
return factors
Prime factorization – TDD style
>>nose2 test.prime_factors
F
================================================
FAIL: test_prime_factors (test.prime_factors.TestPrimeFactors)
----------------------------------------------------------------------
AssertionError: Lists differ: [2] != [2, 1]
----------------------------------------------------------------------
Ran 1 test in 0.001s
FAILED (failures=1)
Prime factorization – TDD style
def prime_factors(number):
factors = []
if number > 1:
if number % 2 == 0:
factors.append(2)
number /= 2
factors.append(number)
return factors
def prime_factors(number):
factors = []
if number > 1:
if number % 2 == 0:
factors.append(2)
number /= 2
if number > 1:
factors.append(number)
return factors
Prime factorization – TDD style
>>nose2 test.prime_factors
.
----------------------------------------------------------------------
Ran 1 test in 0.001s
OK
Prime factorization – TDD style
def prime_factors(number):
factors = []
if number > 1:
if number % 2 == 0:
factors.append(2)
number /= 2
if number > 1:
factors.append(number)
return factors
def prime_factors(number):
factors = []
if number > 1:
if number % 2 == 0:
factors.append(2)
number /= 2
if number > 1:
factors.append(number)
return factors
Prime factorization – TDD style
>>nose2 test.prime_factors
.
----------------------------------------------------------------------
Ran 1 test in 0.001s
OK
Prime factorization – TDD style
class TestPrimeFactors(unittest.TestCase):
"""
Prime factors test suite.
"""
def test_prime_factors(self):
self.assertListEqual([], prime_factors(1))
self.assertListEqual([2], prime_factors(2))
self.assertListEqual([3], prime_factors(3))
self.assertListEqual([2, 2], prime_factors(4))
self.assertListEqual([5], prime_factors(5))
Prime factorization – TDD style
>>nose2 test.prime_factors
.
----------------------------------------------------------------------
Ran 1 test in 0.001s
OK
Prime factorization – TDD style
class TestPrimeFactors(unittest.TestCase):
"""
Prime factors test suite.
"""
def test_prime_factors(self):
self.assertListEqual([], prime_factors(1))
self.assertListEqual([2], prime_factors(2))
self.assertListEqual([3], prime_factors(3))
self.assertListEqual([2, 2], prime_factors(4))
self.assertListEqual([5], prime_factors(5))
self.assertListEqual([2, 3], prime_factors(6))
Prime factorization – TDD style
>>nose2 test.prime_factors
.
----------------------------------------------------------------------
Ran 1 test in 0.001s
OK
Prime factorization – TDD style
class TestPrimeFactors(unittest.TestCase):
"""
Prime factors test suite.
"""
def test_prime_factors(self):
self.assertListEqual([], prime_factors(1))
self.assertListEqual([2], prime_factors(2))
self.assertListEqual([3], prime_factors(3))
self.assertListEqual([2, 2], prime_factors(4))
self.assertListEqual([5], prime_factors(5))
self.assertListEqual([2, 3], prime_factors(6))
self.assertListEqual([7], prime_factors(7))
Prime factorization – TDD style
>>nose2 test.prime_factors
.
----------------------------------------------------------------------
Ran 1 test in 0.001s
OK
Prime factorization – TDD style
class TestPrimeFactors(unittest.TestCase):
"""
Prime factors test suite.
"""
def test_prime_factors(self):
self.assertListEqual([], prime_factors(1))
self.assertListEqual([2], prime_factors(2))
self.assertListEqual([3], prime_factors(3))
self.assertListEqual([2, 2], prime_factors(4))
self.assertListEqual([5], prime_factors(5))
self.assertListEqual([2, 3], prime_factors(6))
self.assertListEqual([7], prime_factors(7))
self.assertListEqual([2, 2, 2], prime_factors(8))
Prime factorization – TDD style
>>nose2 test.prime_factors
F
================================================
FAIL: test_prime_factors (test.prime_factors.TestPrimeFactors)
----------------------------------------------------------------------
AssertionError: Lists differ: [2, 2, 2] != [2, 4]
----------------------------------------------------------------------
Ran 1 test in 0.001s
FAILED (failures=1)
Prime factorization – TDD style
def prime_factors(number):
factors = []
if number > 1:
if number % 2 == 0:
factors.append(2)
number /= 2
if number > 1:
factors.append(number)
return factors
def prime_factors(number):
factors = []
if number > 1:
while number % 2 == 0:
factors.append(2)
number /= 2
if number > 1:
factors.append(number)
return factors
Prime factorization – TDD style
>>nose2 test.prime_factors
.
----------------------------------------------------------------------
Ran 1 test in 0.001s
OK
Prime factorization – TDD style
class TestPrimeFactors(unittest.TestCase):
def test_prime_factors(self):
self.assertListEqual([], prime_factors(1))
self.assertListEqual([2], prime_factors(2))
self.assertListEqual([3], prime_factors(3))
self.assertListEqual([2, 2], prime_factors(4))
self.assertListEqual([5], prime_factors(5))
self.assertListEqual([2, 3], prime_factors(6))
self.assertListEqual([7], prime_factors(7))
self.assertListEqual([2, 2, 2], prime_factors(8))
self.assertListEqual([3, 3], prime_factors(9))
Prime factorization – TDD style
>>nose2 test.prime_factors
F
================================================
FAIL: test_prime_factors (test.prime_factors.TestPrimeFactors)
----------------------------------------------------------------------
AssertionError: Lists differ: [3, 3] != [9]
----------------------------------------------------------------------
Ran 1 test in 0.001s
FAILED (failures=1)
Prime factorization – TDD style
def prime_factors(number):
factors = []
if number > 1:
while number % 2 == 0:
factors.append(2)
number /= 2
if number > 1:
factors.append(number)
return factors
def prime_factors(number):
factors = []
if number > 1:
while number % 2 == 0:
factors.append(2)
number /= 2
while number % 3 == 0:
factors.append(3)
number /= 3
if number > 1:
factors.append(number)
return factors
Prime factorization – TDD style
>>nose2 test.prime_factors
.
----------------------------------------------------------------------
Ran 1 test in 0.001s
OK
Prime factorization – TDD style
def prime_factors(number):
factors = []
if number > 1:
while number % 2 == 0:
factors.append(2)
number /= 2
while number % 3 == 0:
factors.append(3)
number /= 3
if number > 1:
factors.append(number)
return factors
def prime_factors(number):
factors = []
divisor = 2
while number > 1:
while number % divisor == 0:
factors.append(divisor)
number /= divisor
divisor += 1
if number > 1:
factors.append(number)
return factors
Prime factorization – TDD style
>>nose2 test.prime_factors
.
----------------------------------------------------------------------
Ran 1 test in 0.001s
OK
Prime factorization – TDD style
def prime_factors(number):
factors = []
divisor = 2
while number > 1:
while number % divisor == 0:
factors.append(divisor)
number /= divisor
divisor += 1
if number > 1:
factors.append(number)
return factors
def prime_factors(number):
factors = []
divisor = 2
while number > 1:
while number % divisor == 0:
factors.append(divisor)
number /= divisor
divisor += 1
return factors
Prime factorization – TDD style
>>nose2 test.prime_factors
.
----------------------------------------------------------------------
Ran 1 test in 0.001s
OK
Prime factorization – TDD style
class TestPrimeFactors(unittest.TestCase):
"""
Prime factors test suite.
"""
def test_prime_factors(self):
self.assertListEqual([], prime_factors(1))
self.assertListEqual([2], prime_factors(2))
self.assertListEqual([3], prime_factors(3))
self.assertListEqual([2, 2], prime_factors(4))
self.assertListEqual([5], prime_factors(5))
self.assertListEqual([2, 3], prime_factors(6))
self.assertListEqual([7], prime_factors(7))
self.assertListEqual([2, 2, 2], prime_factors(8))
self.assertListEqual([3, 3], prime_factors(9))
self.assertListEqual([2, 2, 3, 3, 5, 7 , 11, 13], prime_factors(2*2*3*3*5*7*11*13))
Prime factorization – TDD style
>>nose2 test.prime_factors
.
----------------------------------------------------------------------
Ran 1 test in 0.001s
OK
Clean code that works
Zalety TDD
● Prostota iteracji designu
● Pokrycie testami
● Możliwość refactoringu
● Zdecouplowany, testowalny kod
● Nietrywialny design
● Ograniczenie wykorzystania debugera
● Brak strachu przez zmianami w kodzie
Problemy z TDD
● Konieczność zmiany stylu myślenia
● Początkowo mało intuicyjna technika
● Pokusa pisania kodu produkcyjnego bez testów
Pytania
Dziękuję

More Related Content

Similar to Test driven development - the right way

Solit 2012, TDD и отдельные аспекты тестирования в Java, Антонина Шафранская
Solit 2012, TDD и отдельные аспекты тестирования в Java, Антонина ШафранскаяSolit 2012, TDD и отдельные аспекты тестирования в Java, Антонина Шафранская
Solit 2012, TDD и отдельные аспекты тестирования в Java, Антонина Шафранская
solit
 
Agile Developer Immersion Workshop, LASTconf Melbourne, Australia, 19th July ...
Agile Developer Immersion Workshop, LASTconf Melbourne, Australia, 19th July ...Agile Developer Immersion Workshop, LASTconf Melbourne, Australia, 19th July ...
Agile Developer Immersion Workshop, LASTconf Melbourne, Australia, 19th July ...
Victoria Schiffer
 
Performance Optimization of Rails Applications
Performance Optimization of Rails ApplicationsPerformance Optimization of Rails Applications
Performance Optimization of Rails Applications
Serge Smetana
 

Similar to Test driven development - the right way (20)

TDD reloaded - JUGTAA 24 Ottobre 2012
TDD reloaded - JUGTAA 24 Ottobre 2012TDD reloaded - JUGTAA 24 Ottobre 2012
TDD reloaded - JUGTAA 24 Ottobre 2012
 
Test Driven Development
Test Driven DevelopmentTest Driven Development
Test Driven Development
 
Test driven development in .Net - 2010 + Eclipse
Test driven development in .Net - 2010 + EclipseTest driven development in .Net - 2010 + Eclipse
Test driven development in .Net - 2010 + Eclipse
 
GlobalLogic Test Automation Online TechTalk “Test Driven Development as a Per...
GlobalLogic Test Automation Online TechTalk “Test Driven Development as a Per...GlobalLogic Test Automation Online TechTalk “Test Driven Development as a Per...
GlobalLogic Test Automation Online TechTalk “Test Driven Development as a Per...
 
prohuddle-utPLSQL v3 - Ultimate unit testing framework for Oracle
prohuddle-utPLSQL v3 - Ultimate unit testing framework for Oracleprohuddle-utPLSQL v3 - Ultimate unit testing framework for Oracle
prohuddle-utPLSQL v3 - Ultimate unit testing framework for Oracle
 
Introduction to unit testing in python
Introduction to unit testing in pythonIntroduction to unit testing in python
Introduction to unit testing in python
 
Solit 2012, TDD и отдельные аспекты тестирования в Java, Антонина Шафранская
Solit 2012, TDD и отдельные аспекты тестирования в Java, Антонина ШафранскаяSolit 2012, TDD и отдельные аспекты тестирования в Java, Антонина Шафранская
Solit 2012, TDD и отдельные аспекты тестирования в Java, Антонина Шафранская
 
Test Driven Development
Test Driven DevelopmentTest Driven Development
Test Driven Development
 
Behaviour Driven Development and Thinking About Testing
Behaviour Driven Development and Thinking About TestingBehaviour Driven Development and Thinking About Testing
Behaviour Driven Development and Thinking About Testing
 
Bdd and-testing
Bdd and-testingBdd and-testing
Bdd and-testing
 
Test Driven Development - The art of fearless programming
Test Driven Development - The art of fearless programmingTest Driven Development - The art of fearless programming
Test Driven Development - The art of fearless programming
 
Agile Developer Immersion Workshop, LASTconf Melbourne, Australia, 19th July ...
Agile Developer Immersion Workshop, LASTconf Melbourne, Australia, 19th July ...Agile Developer Immersion Workshop, LASTconf Melbourne, Australia, 19th July ...
Agile Developer Immersion Workshop, LASTconf Melbourne, Australia, 19th July ...
 
Performance Optimization of Rails Applications
Performance Optimization of Rails ApplicationsPerformance Optimization of Rails Applications
Performance Optimization of Rails Applications
 
Test Driven Development With Python
Test Driven Development With PythonTest Driven Development With Python
Test Driven Development With Python
 
New Features Of Test Unit 2.x
New Features Of Test Unit 2.xNew Features Of Test Unit 2.x
New Features Of Test Unit 2.x
 
關於測試,我說的其實是......
關於測試,我說的其實是......關於測試,我說的其實是......
關於測試,我說的其實是......
 
Unit Testing like a Pro - The Circle of Purity
Unit Testing like a Pro - The Circle of PurityUnit Testing like a Pro - The Circle of Purity
Unit Testing like a Pro - The Circle of Purity
 
TDD talk
TDD talkTDD talk
TDD talk
 
Test-Driven Development.pptx
Test-Driven Development.pptxTest-Driven Development.pptx
Test-Driven Development.pptx
 
Getting started with Test Driven Development - Ferdous Mahmud Shaon
Getting started with Test Driven Development - Ferdous Mahmud ShaonGetting started with Test Driven Development - Ferdous Mahmud Shaon
Getting started with Test Driven Development - Ferdous Mahmud Shaon
 

Recently uploaded

The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is inside
shinachiaurasa2
 

Recently uploaded (20)

Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
ManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide DeckManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide Deck
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdf
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is inside
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verifiedSector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
 
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdfAzure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
LEVEL 5 - SESSION 1 2023 (1).pptx - PDF 123456
LEVEL 5   - SESSION 1 2023 (1).pptx - PDF 123456LEVEL 5   - SESSION 1 2023 (1).pptx - PDF 123456
LEVEL 5 - SESSION 1 2023 (1).pptx - PDF 123456
 
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 
10 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 202410 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 2024
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdfThe Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
 

Test driven development - the right way

  • 1. Test driven development The right way Paweł Głasek @PawelGlasek
  • 2.
  • 3.
  • 5. Czym TDD nie jest Napisaniem testów wszystkich obiektów, przed implementacją funkcjonalności.
  • 6. Czym TDD nie jest Wszystkie testy przed implementacją ● Ciężko zaprojektować odpowiedni design oraz zmieniać go w trakcie kodowania ● Ciężko przewidzieć zmiany w obiektach klas już obecnych w systemie ● Ciężko przewidzieć współdziałanie komponentów ● Niektóre warunki brzegowe nigdy nie występują – zbyt duża ilość niepotrzebnych testów ● Często niepełne pokrycie
  • 7. Czym TDD nie jest Sztuką pisania unit testów
  • 8. Czym TDD nie jest Just Unit tests ● Błyskawicznie prowadzi do „przemockowania” ● Nie testuje współdziałania poszczególnych obiektów ● Pomimo zmian w powiązanych, ale zmockowanych klasach testy przechodzą ● Niektóre warunki brzegowe nigdy nie występują – zbyt duża ilość niepotrzebnych testów ● Brak motywacji do pisania testów
  • 9. Czym TDD nie jest Napisaniem testów po zakończeniu pisania kodu produkcyjnego.
  • 10. Czym TDD nie jest Testy po napisaniu kodu produkcyjnego ● Brak motywacji do pisania testów po fakcie ● Wiele przypadków pozostaje nieprzetestowanych ● Niektóre warunki brzegowe nigdy nie występują ● Brak poczucia sensu pisania testów w ten sposób ● Częste problemy z testowalnością napisanego kodu ● Nuda
  • 15.
  • 16. Red – green – refactor Zasady wujka Boba: 1. Nie wolno pisać kodu produkcyjnego, dopóki nie istnieje failujący test. 2. Nie wolno napisać więcej testów, niż jest to niezbędne do faila (niekompilujący się kod również uznajemy jako fail). 3. Nie wolno pisać więcej kodu produkcyjnego niż jest to niezbędne, by testy przechodziły.
  • 17. Powiedz mi, a zapomnę. Pokaż mi, a zapamiętam.
  • 18. Rozkład liczby na czynniki pierwsze
  • 20. Prime factorization – TDD style class TestPrimeFactors(unittest.TestCase): """ Prime factors test suite. """ def test_prime_factors(self): self.assertListEqual([], prime_factors(1))
  • 21. Prime factorization – TDD style >> nose2 test.prime_factors ================================================== ERROR: test_prime_factors (test.prime_factors.TestPrimeFactors) ---------------------------------------------------------------------- NameError: global name 'prime_factors' is not defined ---------------------------------------------------------------------- Ran 1 test in 0.000s FAILED (errors=1)
  • 22. Prime factorization – TDD style def prime_factors(number): """ Performs prime factorization. :param number: Number to be factorized. :type number: int :rtype: list """ return []
  • 23. Prime factorization – TDD style >>nose2 test.prime_factors . ---------------------------------------------------------------------- Ran 1 test in 0.001s OK
  • 24. Prime factorization – TDD style class TestPrimeFactors(unittest.TestCase): """ Prime factors test suite. """ def test_prime_factors(self): self.assertListEqual([], prime_factors(1)) self.assertListEqual([2], prime_factors(2))
  • 25. Prime factorization – TDD style >>nose2 test.prime_factors F ================================================ FAIL: test_prime_factors (test.prime_factors.TestPrimeFactors) ---------------------------------------------------------------------- AssertionError: Lists differ: [2] != [] ---------------------------------------------------------------------- Ran 1 test in 0.001s FAILED (failures=1)
  • 26. Prime factorization – TDD style def prime_factors(number): return [] def prime_factors(number): factors = [] if number > 1: factors.append(2) return factors
  • 27. Prime factorization – TDD style >>nose2 test.prime_factors . ---------------------------------------------------------------------- Ran 1 test in 0.001s OK
  • 28. Prime factorization – TDD style class TestPrimeFactors(unittest.TestCase): """ Prime factors test suite. """ def test_prime_factors(self): self.assertListEqual([], prime_factors(1)) self.assertListEqual([2], prime_factors(2)) self.assertListEqual([3], prime_factors(3))
  • 29. Prime factorization – TDD style >>nose2 test.prime_factors F ================================================ FAIL: test_prime_factors (test.prime_factors.TestPrimeFactors) ---------------------------------------------------------------------- AssertionError: Lists differ: [3] != [2] ---------------------------------------------------------------------- Ran 1 test in 0.001s FAILED (failures=1)
  • 30. Prime factorization – TDD style def prime_factors(number): factors = [] if number > 1: factors.append(2) return factors def prime_factors(number): factors = [] if number > 1: factors.append(number) return factors
  • 31. Prime factorization – TDD style >>nose2 test.prime_factors . ---------------------------------------------------------------------- Ran 1 test in 0.001s OK
  • 32. Prime factorization – TDD style class TestPrimeFactors(unittest.TestCase): """ Prime factors test suite. """ def test_prime_factors(self): self.assertListEqual([], prime_factors(1)) self.assertListEqual([2], prime_factors(2)) self.assertListEqual([3], prime_factors(3)) self.assertListEqual([2, 2], prime_factors(4))
  • 33. Prime factorization – TDD style >>nose2 test.prime_factors F ================================================ FAIL: test_prime_factors (test.prime_factors.TestPrimeFactors) ---------------------------------------------------------------------- AssertionError: Lists differ: [2, 2] != [4] ---------------------------------------------------------------------- Ran 1 test in 0.001s FAILED (failures=1)
  • 34. Prime factorization – TDD style def prime_factors(number): factors = [] if number > 1: factors.append(number) return factors def prime_factors(number): factors = [] if number > 1: if number % 2 == 0: factors.append(2) number /= 2 factors.append(number) return factors
  • 35. Prime factorization – TDD style >>nose2 test.prime_factors F ================================================ FAIL: test_prime_factors (test.prime_factors.TestPrimeFactors) ---------------------------------------------------------------------- AssertionError: Lists differ: [2] != [2, 1] ---------------------------------------------------------------------- Ran 1 test in 0.001s FAILED (failures=1)
  • 36. Prime factorization – TDD style def prime_factors(number): factors = [] if number > 1: if number % 2 == 0: factors.append(2) number /= 2 factors.append(number) return factors def prime_factors(number): factors = [] if number > 1: if number % 2 == 0: factors.append(2) number /= 2 if number > 1: factors.append(number) return factors
  • 37. Prime factorization – TDD style >>nose2 test.prime_factors . ---------------------------------------------------------------------- Ran 1 test in 0.001s OK
  • 38. Prime factorization – TDD style def prime_factors(number): factors = [] if number > 1: if number % 2 == 0: factors.append(2) number /= 2 if number > 1: factors.append(number) return factors def prime_factors(number): factors = [] if number > 1: if number % 2 == 0: factors.append(2) number /= 2 if number > 1: factors.append(number) return factors
  • 39. Prime factorization – TDD style >>nose2 test.prime_factors . ---------------------------------------------------------------------- Ran 1 test in 0.001s OK
  • 40. Prime factorization – TDD style class TestPrimeFactors(unittest.TestCase): """ Prime factors test suite. """ def test_prime_factors(self): self.assertListEqual([], prime_factors(1)) self.assertListEqual([2], prime_factors(2)) self.assertListEqual([3], prime_factors(3)) self.assertListEqual([2, 2], prime_factors(4)) self.assertListEqual([5], prime_factors(5))
  • 41. Prime factorization – TDD style >>nose2 test.prime_factors . ---------------------------------------------------------------------- Ran 1 test in 0.001s OK
  • 42. Prime factorization – TDD style class TestPrimeFactors(unittest.TestCase): """ Prime factors test suite. """ def test_prime_factors(self): self.assertListEqual([], prime_factors(1)) self.assertListEqual([2], prime_factors(2)) self.assertListEqual([3], prime_factors(3)) self.assertListEqual([2, 2], prime_factors(4)) self.assertListEqual([5], prime_factors(5)) self.assertListEqual([2, 3], prime_factors(6))
  • 43. Prime factorization – TDD style >>nose2 test.prime_factors . ---------------------------------------------------------------------- Ran 1 test in 0.001s OK
  • 44. Prime factorization – TDD style class TestPrimeFactors(unittest.TestCase): """ Prime factors test suite. """ def test_prime_factors(self): self.assertListEqual([], prime_factors(1)) self.assertListEqual([2], prime_factors(2)) self.assertListEqual([3], prime_factors(3)) self.assertListEqual([2, 2], prime_factors(4)) self.assertListEqual([5], prime_factors(5)) self.assertListEqual([2, 3], prime_factors(6)) self.assertListEqual([7], prime_factors(7))
  • 45. Prime factorization – TDD style >>nose2 test.prime_factors . ---------------------------------------------------------------------- Ran 1 test in 0.001s OK
  • 46. Prime factorization – TDD style class TestPrimeFactors(unittest.TestCase): """ Prime factors test suite. """ def test_prime_factors(self): self.assertListEqual([], prime_factors(1)) self.assertListEqual([2], prime_factors(2)) self.assertListEqual([3], prime_factors(3)) self.assertListEqual([2, 2], prime_factors(4)) self.assertListEqual([5], prime_factors(5)) self.assertListEqual([2, 3], prime_factors(6)) self.assertListEqual([7], prime_factors(7)) self.assertListEqual([2, 2, 2], prime_factors(8))
  • 47. Prime factorization – TDD style >>nose2 test.prime_factors F ================================================ FAIL: test_prime_factors (test.prime_factors.TestPrimeFactors) ---------------------------------------------------------------------- AssertionError: Lists differ: [2, 2, 2] != [2, 4] ---------------------------------------------------------------------- Ran 1 test in 0.001s FAILED (failures=1)
  • 48. Prime factorization – TDD style def prime_factors(number): factors = [] if number > 1: if number % 2 == 0: factors.append(2) number /= 2 if number > 1: factors.append(number) return factors def prime_factors(number): factors = [] if number > 1: while number % 2 == 0: factors.append(2) number /= 2 if number > 1: factors.append(number) return factors
  • 49. Prime factorization – TDD style >>nose2 test.prime_factors . ---------------------------------------------------------------------- Ran 1 test in 0.001s OK
  • 50. Prime factorization – TDD style class TestPrimeFactors(unittest.TestCase): def test_prime_factors(self): self.assertListEqual([], prime_factors(1)) self.assertListEqual([2], prime_factors(2)) self.assertListEqual([3], prime_factors(3)) self.assertListEqual([2, 2], prime_factors(4)) self.assertListEqual([5], prime_factors(5)) self.assertListEqual([2, 3], prime_factors(6)) self.assertListEqual([7], prime_factors(7)) self.assertListEqual([2, 2, 2], prime_factors(8)) self.assertListEqual([3, 3], prime_factors(9))
  • 51. Prime factorization – TDD style >>nose2 test.prime_factors F ================================================ FAIL: test_prime_factors (test.prime_factors.TestPrimeFactors) ---------------------------------------------------------------------- AssertionError: Lists differ: [3, 3] != [9] ---------------------------------------------------------------------- Ran 1 test in 0.001s FAILED (failures=1)
  • 52. Prime factorization – TDD style def prime_factors(number): factors = [] if number > 1: while number % 2 == 0: factors.append(2) number /= 2 if number > 1: factors.append(number) return factors def prime_factors(number): factors = [] if number > 1: while number % 2 == 0: factors.append(2) number /= 2 while number % 3 == 0: factors.append(3) number /= 3 if number > 1: factors.append(number) return factors
  • 53. Prime factorization – TDD style >>nose2 test.prime_factors . ---------------------------------------------------------------------- Ran 1 test in 0.001s OK
  • 54. Prime factorization – TDD style def prime_factors(number): factors = [] if number > 1: while number % 2 == 0: factors.append(2) number /= 2 while number % 3 == 0: factors.append(3) number /= 3 if number > 1: factors.append(number) return factors def prime_factors(number): factors = [] divisor = 2 while number > 1: while number % divisor == 0: factors.append(divisor) number /= divisor divisor += 1 if number > 1: factors.append(number) return factors
  • 55. Prime factorization – TDD style >>nose2 test.prime_factors . ---------------------------------------------------------------------- Ran 1 test in 0.001s OK
  • 56. Prime factorization – TDD style def prime_factors(number): factors = [] divisor = 2 while number > 1: while number % divisor == 0: factors.append(divisor) number /= divisor divisor += 1 if number > 1: factors.append(number) return factors def prime_factors(number): factors = [] divisor = 2 while number > 1: while number % divisor == 0: factors.append(divisor) number /= divisor divisor += 1 return factors
  • 57. Prime factorization – TDD style >>nose2 test.prime_factors . ---------------------------------------------------------------------- Ran 1 test in 0.001s OK
  • 58. Prime factorization – TDD style class TestPrimeFactors(unittest.TestCase): """ Prime factors test suite. """ def test_prime_factors(self): self.assertListEqual([], prime_factors(1)) self.assertListEqual([2], prime_factors(2)) self.assertListEqual([3], prime_factors(3)) self.assertListEqual([2, 2], prime_factors(4)) self.assertListEqual([5], prime_factors(5)) self.assertListEqual([2, 3], prime_factors(6)) self.assertListEqual([7], prime_factors(7)) self.assertListEqual([2, 2, 2], prime_factors(8)) self.assertListEqual([3, 3], prime_factors(9)) self.assertListEqual([2, 2, 3, 3, 5, 7 , 11, 13], prime_factors(2*2*3*3*5*7*11*13))
  • 59. Prime factorization – TDD style >>nose2 test.prime_factors . ---------------------------------------------------------------------- Ran 1 test in 0.001s OK
  • 61. Zalety TDD ● Prostota iteracji designu ● Pokrycie testami ● Możliwość refactoringu ● Zdecouplowany, testowalny kod ● Nietrywialny design ● Ograniczenie wykorzystania debugera ● Brak strachu przez zmianami w kodzie
  • 62. Problemy z TDD ● Konieczność zmiany stylu myślenia ● Początkowo mało intuicyjna technika ● Pokusa pisania kodu produkcyjnego bez testów