20
TDD joyful coding
Because you find it boring to test your code since you think it is already working fine. Also, you are most likely to write tests that will make your code pass, because your code wasn't designed to be testable.
I thought so, but since I watched a demo about how it works, I started to understand how it can help you have more fun while coding
- Write test to make it fail
- write code to make it pass
- Refactor the code
- Repeat the steps 1,2,3 until you can't make it fail
- Step 1
#tests.py
class TestQueue(unittest.TestCase):
def test_queue(self):
q = MyQueue()
- Step 2
#queue.py
class MyQueue:
pass
- Step 3
#tests.py
class TestQueue(unittest.TestCase):
def test_queue(self):
q = Queue()
#queue.py
class Queue:
pass
- Step 1
#tests.py
class TestQueue(unittest.TestCase):
def test_new_queue_is_empty(self):
q = Queue()
self.assertTrue(q.is_empty())
- Step 2
#queue.py
class Queue:
def is_empty(self) -> bool:
return True
- Step 1
#tests.py
class TestQueue(unittest.TestCase):
...
def test_queue_after_one_enqueue_not_empty(self):
q = Queue()
q.enqueue(3)
self.assertFalse(q.is_empty())
- Step 2
#queue.py
class Queue:
__empty = True
def is_empty(self) -> bool:
return self.__empty
def enqueue(self, element: int):
self.__empty = False
- Step 3
#tests.py
class TestQueue(unittest.TestCase):
def setUp(self) -> None:
self.q = Queue()
def test_new_queue_is_empty(self):
self.assertTrue(self.q.is_empty())
def test_queue_after_one_enqueue_not_empty(self):
self.q.enqueue(3)
self.assertFalse(self.q.is_empty())
- Step 1
#tests.py
class TestQueue(unittest.TestCase):
...
def test_dequeue_from_empty_queue(self):
self.assertRaises(UnderFlowException, self.q.dequeue)
- Step 2
#queue.py
class UnderFlowException(Exception):
def __str__(self):
return "Can't dequeue from empty queue"
class Queue:
...
def dequeue(self):
if self.is_empty():
raise UnderFlowException()
return -1
- Step 1
#tests.py
class TestQueue(unittest.TestCase):
...
def test_is_empty_after_one_enqueue_one_dequeue(self):
self.q.enqueue(10)
self.q.dequeue()
self.assertTrue(self.q.is_empty())
- Step 2
#queue.py
...
def dequeue(self):
if self.is_empty():
raise UnderFlowException()
self.__empty = True
return -1
- Step 1
#tests.py
class TestQueue(unittest.TestCase):
...
def test_is_not_empty_two_enqueue_one_dequeue(self):
self.q.enqueue(10)
self.q.enqueue(20)
self.q.dequeue()
self.assertFalse(self.q.is_empty())
- Step 2
#queue.py
class Queue:
__size = 0
def is_empty(self) -> bool:
return self.__size == 0
def enqueue(self, element: int):
self.__size += 1
def dequeue(self):
if self.is_empty():
raise UnderFlowException()
self.__size -= 1
return -1
- Step 1
#tests.py
class TestQueue(unittest.TestCase):
...
def test_dequeue_value(self):
self.q.enqueue(10)
self.assertEqual(self.q.dequeue(), 10)
self.q.enqueue(20)
self.assertEqual(self.q.dequeue(), 20)
- Step 2
#queue.py
class Queue:
__size = 0
__element = -1
def is_empty(self) -> bool:
return self.__size == 0
def enqueue(self, element: int):
self.__size += 1
self.__element = element
def dequeue(self) -> int:
if self.is_empty():
raise UnderFlowException()
self.__size -= 1
return self.__element
- Step 1
#tests.py
class TestQueue(unittest.TestCase):
...
def test_dequeue_value_after_two_enqueues(self):
self.q.enqueue(10)
self.q.enqueue(20)
self.assertEqual(self.q.dequeue(), 10)
- Step 2
#queue.py
class Queue:
__size = 0
__elements = []
def is_empty(self) -> bool:
return self.__size == 0
def enqueue(self, element: int):
self.__size += 1
self.__elements.append(element)
def dequeue(self) -> int:
if self.is_empty():
raise UnderFlowException()
self.__size -= 1
return self.__elements.pop(0)
- Step 3
#queue.py
class Queue:
__elements = []
def is_empty(self) -> bool:
return len(self.__elements) == 0
def enqueue(self, element: int):
self.__elements.append(element)
def dequeue(self) -> int:
if self.is_empty():
raise UnderFlowException()
return self.__elements.pop(0)
20