After another long layoff from studying Python due to "that's life", I am back at it again. I am trying to combine learning unit testing and TDD with working through the text, "Think Python 2" by Allen Downey. I am currently in chapter 3 which is an introduction to functions. In trying to apply TDD to exercise 3.1, which is:
"Write a function named right_justify that takes a string named s as a parameter and prints the string with enough leading spaces so that the last letter of the string is in column 70 of the display. Hint: Use concatenation and repetition..." The problem is pretty easy, but the point is for me is to practice the steps of TDD and learn how to use unit testing, and I figure using easy problems as I go through the book will make learning TDD and testing easier. After a couple of iterations I have this program, right_justify.py: #!/usr/bin/env python3 '''Exerise 3.1 from "Think Python 2" by Allen Downey. This module will take a string and right justify it so that the last character of the line will fall in column 70 of the display. This is accomplished by padding the line with spaces.''' def right_justify(a_string): '''This fucntion will take the string, "a_string", and left justify it by padding it with spaces until its last character falls in column 70 of the display. The padded string will be returned.''' return ' ' * 58 + a_string Of course, this code passed its test when the string was "Monty Python", so I next wanted to run the same test with different strings each time, so that my code would fail in these more general cases. However, I struggled to find a way to repeat the same test with varying data, eventually crying "Uncle!" and consulted the documentation. This led me to this version of test_right_justify.py: #!/usr/bin/env python3 '''This module contains unit tests for the function, "right_justify(a_string)", located in the module, "right_justify".''' import unittest import right_justify class TestRightJustify(unittest.TestCase): '''Tests for the function, "right_justify(a_string)", in the "right_justify module".''' def setUp(self): '''Define variables needed to run this class' tests.''' self.test_strings = [ "Monty Python", "She's a witch!", "Beware of the rabbit!!! She is a vicious beast who will rip" " your throat out!"] def test_returned_len_is_70(self): '''Check that the string returned by "right_justify(a_string)" is the length of the entire line, i.e., 70 columns.''' for test_string in self.test_strings: with self.subTest(test_string = test_string): length_of_returned_string = ( len(right_justify.right_justify(test_string))) print('The current test string is: ', test_string) self.assertEqual(length_of_returned_string, 70) if __name__ == '__main__': unittest.main() I know that I need more tests (or a better single one) to fully test this function. But I am taking baby steps here, checking the most obvious stuff first. Refinement will come as I learn and move along. Anyway, running the tests gave me this result: c:\thinkpython2\ch3\ex_3-1>py -m unittest The current test string is: Monty Python The current test string is: She's a witch! The current test string is: Beware of the rabbit!!! She is a vicious beast who will rip your throat out! ====================================================================== FAIL: test_returned_len_is_70 (test_right_justify.TestRightJustify) (test_string="She's a witch!") Check that the string returned by "right_justify(a_string)" is the ---------------------------------------------------------------------- Traceback (most recent call last): File "c:\thinkpython2\ch3\ex_3-1\test_right_justify.py", line 32, in test_returned_len_is_70 self.assertEqual(length_of_returned_string, 70) AssertionError: 72 != 70 ====================================================================== FAIL: test_returned_len_is_70 (test_right_justify.TestRightJustify) (test_string='Beware of the rabbit!!! She is a vicious beast who will rip your throat out!') Check that the string returned by "right_justify(a_string)" is the ---------------------------------------------------------------------- Traceback (most recent call last): File "c:\thinkpython2\ch3\ex_3-1\test_right_justify.py", line 32, in test_returned_len_is_70 self.assertEqual(length_of_returned_string, 70) AssertionError: 135 != 70 ---------------------------------------------------------------------- Ran 1 test in 0.009s FAILED (failures=2) Question #1: Why is the test output NOT showing the first, passed test? The one where the string is "Monty Python"? Question #2: Before I hit the docs to learn about subTest, I tried a bunch of different ways to make that for loop to work inside the class, but I guess my current poor knowledge of OOP did me in. But I KNOW there has to be a way to accomplish this WITHOUT using subTest. After all, subTest was not introduced until Python 3.4. So how should I go about this without using subTest? Question #3: In "with self.subTest(test_string = test_string):" why is "test_string = test_string" necessary? Is it that using "with" sets up a new local namespace within this context manager? I think with these long Python layoffs I am losing knowledge faster than I am gaining it! Cheers! -- boB _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor