From the course: Learning SOLID Programming Principles
Test-driven design - Python Tutorial
From the course: Learning SOLID Programming Principles
Test-driven design
- [Instructor] What's a good approach to getting a solid design? As we've noted before, there are five general design principles and these can lead to a lot of other considerations. Here are two suggestions for tools that can help move from a story to a design. In the last section, we looked at CRC cards. In this section, I want to look at automated test code. Tests are just as important as the application code since it's essential to test every class in isolation. Building unit tests turns out to be an important part of designing a class. I think that considerations related to testability can help assure that the solid principles are being followed. This is one of the ideas behind test-driven development. The guiding concept under test-driven development is a blunt statement. If there's no automated test, the feature does not really exist. The guiding idea here is to provide a definition of done for any particular feature by saying the software is done when it passes the automated acceptance tests. And that means the definition of done can be formalized as a suite of test cases. A search on phrases like acceptance test-driven development and test-first development will yield a number of resources to help do this. The idea is to write test cases first, and then, from that, create code that passes the tests. We'll look at describing features using a formal testing language named Gherkin. I find it helpful to describe software tests using a given-when-then kind of statement. Given some class in an initial state, when some interaction or method is evaluated, then there's an expected result. This is the Gherkin language, which is handy for describing tests. The unit test framework in Python has a set-up method that handles the given part. There's a run test method that handles the when and then parts. A pie test fixture is often the given part of a test and a test function implements the when and then parts of the test. Here's an example test case spelled out in detail. It starts with a definition of the scenario, provides the given conditions that must be true. It provides the when statement for the action we want to carry out and it provides then clauses that show what we need to evaluate to determine if the test passed or failed. Here's a test case using the pie test framework with some annotations to show how we turned the Gherkin given-when-and-then concepts into actual test code. The given clause became some mock objects to provide the initial state. The when statement became a method in vocation and the then statement became a series of assertions to determine if indeed the test was passed. Tools like behave use Python modules to implement the Gherkin steps. I prefer to write the steps manually because it serves as a way to affirm the solid design principles have been followed by the code being tested. When the tests are hard to write, it indicates potential design problems that need to be reviewed. In addition to unit tests, Python also supports doctests. These are test scenarios that are included in the documentation strings for classes and method definitions. They're relatively easy to prepare and I think they're an important part of being sure the solid principles are part of the design. These tests tend to fit the Gherkin model of having a given starting condition, a when action of some kind and then a then consequence that shows the results of the action. I like writing these to confirm the design really fills out the solid principles. Test to design bumps into the solid principles in important ways. Generally, all tests should reflect the single responsibility principle. Some tests must be written to evaluate the open-closed principle. We'll need to write a general test for an extension to an abstract class. The tests will often reflect interface segregation. If an interface has too many features, the tests tend to grow also and test coverage tools can show if interface features aren't being tested properly.
Practice while you learn with exercise files
Download the files the instructor uses to teach the course. Follow along and learn by watching, listening and practicing.