Hi, On 24 September 2016 at 06:55, boB Stepp <robertvst...@gmail.com> wrote: > > 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) >
To add to what Benn Finney's said: The key thing to understand is that to the test framework, this is *one* test due to there being one def test_....() method. The first iteration of the loop (which is a "pass" in your mind that should be displayed) is just a part of this one test that hasn't caused a failure. To accomplish what you want in a generalized way you have to therefore specify and make the framework aware of a) the existence of a generalized test method that takes some kind of test data to run, and b) what the test data is. The framework should then repeatedly run your test, varying the input as specified and showing the failure cases as independently run tests. And the way to do this when using the unittest framework is as Benn's described. I'd however suggest at this stage to not get stuck in the minutiae of how to write fully generalized tests, and to simply write separate test cases (seperate def's) with different data, to keep your focus on learning TDD rather than learning the ins and outs of unittest, if you find yourself falling down some kind of test framework learning rabbit hole. That said, I would suggest perhaps consider using Py.Test instead of unittest, which is arguably much "lower friction" with less overhead/boilerplate/ceremony required. With Pytest, tests can be defined via simple functions if you wish, and checks may be performed with simple asserts if you like. PyTest will also collect all test functions automatically wherever they may exist, based on its conventions. It is therefore possible to start really simply with any code you write, and have test functions defined alongside the code you're writing without any explicit reference/dependency on the test framework, which allows a very easy way of getting started. Obviously you can keep the tests in a separate module if you prefer, and/or make use of the infrastructure provided by the test framework (base classes, decorators etc) if you like or need them, but this is not obligatory and hence makes a very direct style of getting started possible (hence "low friction") The kind of parameterization you want can be more compactly and simply achieved with PyTest attributes, as follows below. I've rewritten your test module slightly and include a non-implemented right_justify() method, and thus you have 3 failing tests if you run the below module: ----------------------------begin code----------------------------- #!/usr/bin/env python3 '''This module defines the function right_justify(a_string) and defines its unit tests. When the module is run by itself it will self-test. The module should otherwise be imported as normal to use.''' def right_justify(s): #To be completed pass import pytest # Here we use an attribute to define the various inputs and outputs with which # to run our generalized test function test_returned_len_is_correct(). # As you can see, you define the paremeter names, followed by a list of # tuples defining the input and expected output. @pytest.mark.parametrize("test_string, expected_len", [ ("Monty Python", 12), ("She's a witch!", 14), ("Beware of the rabbit!!! She is a vicious beast who will rip"\ " your throat out!", 77), ] ) # Here's the generalized test function, that takes an input and expected length. def test_returned_len_is_correct(test_string, expected_len): '''Check that the string returned by "right_justify(a_string)" is the length of the input''' actual_len = len(right_justify(test_string)) assert actual_len == expected_len if __name__ == '__main__': # This is how to invoke pytest directly from this module as the main function. # Note this is an uncommon pytest usage pattern. More common is to run it # from command line in your source folder, and have pytest collect all the # tests from all modules automatically. See http://doc.pytest.org/en/latest/usage.html pytest.main([__file__]) ----------------------------end code----------------------------- Hope that gives you some ideas. An aside, you might also consider some of the coding challenge sites which are also a fun way to practice your TDD skills. For example: https://www.hackerrank.com/domains/python/py-introduction https://www.codeeval.com https://www.codewars.com Best wishes, Walter _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor