So let's add a test for the other feature we want, which is to count the number of characters in the file. Since analyze_text() is now supposed to return two values, we'll have it return a tuple with line count in the first position and character count in the second. Our new test looks like this:
# text_analyzer.py
class TextAnalysisTests(unittest.TestCase):
. . .
def test_character_count(self):
"Check that the character count is correct."
self.assertEqual(analyze_text(self.filename)[1], 131)
And it fails as expected:
% python text_analyzer.py
E..
======================================================================
ERROR: test_character_count (__main__.TextAnalysisTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "text_analyzer.py", line 32, in test_character_count
self.assertEqual(analyze_text(self.filename)[1], 131)
TypeError: 'int' object has no attribute '__getitem__'
----------------------------------------------------------------------
Ran 3 tests in 0.004s
FAILED (errors=1)
This result is telling us that it can't index into the integer returned by analyze_text(). So let's fix analyze_text() to return the proper tuple:
# text_analyzer.py
def analyze_text(filename):
"""Calculate the number of lines and characters in a file.
Args:
filename: The name of the file to analyze.
Raises:
IOError: If ``filename`` does not exist or can't be read.
Returns: A tuple where the first element is the number of lines in
the files and the second element is the number of characters.
"""
lines = 0
chars = 0
with open(filename, 'r') as f:
for line in f:
lines += 1
chars += len(line)
return (lines, chars)
This fixes our new test, but we find we've broken an old one:
% python text_analyzer.py
..F
======================================================================
FAIL: test_line_count (__main__.TextAnalysisTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "text_analyzer.py", line 34, in test_line_count
self.assertEqual(analyze_text(self.filename), 4)
AssertionError: (4, 131) != 4
----------------------------------------------------------------------
Ran 3 tests in 0.004s
FAILED (failures=1)
Fortunately that's easy enough to fix because all we need to do is account for the new return type in our earlier test:
# text_analyzer.py
class TextAnalysisTests(unittest.TestCase):
. . .
def test_line_count(self):
"Check that the line count is correct."
self.assertEqual(analyze_text(self.filename)[0], 4)
Now everything is passing again:
% python text_analyzer.py
...
----------------------------------------------------------------------
Ran 3 tests in 0.004s
OK