| Previous | Next |
| Speaker's notes: | It's more difficult to test a class, for example, that has many different responsibilities. Strong cohesion among the responsibilities of a module, class, or package is good design, and following this design principle will make it easier to find and refactor out common testing setup into a test fixture. |
|---|
| Speaker's notes: | Only test the interface exposed to the outside world. That way, when the implementation changes, your tests shouldn't break. In fact, providing validation that the unit works as expected after a change in implementation is one of the major focuses of unit testing. This "saftey net" permits aggressive refactoring that can help promote code quality. Thus, it is a good idea to use Python's name hiding conventions to hide non-public methods, functions, and modules. For example, we could rewrite our DateRange class so that when an endDate of None is given to the constructor, the DateRange instance actually uses DateTime.MaxDateTime internally. Making this change without affecting any behavior visible to users of DateRange is more complicated than you may think at first, but TestDateRange helps to ensure that you'll do it correctly. |
|---|
| Speaker's notes: | If you really want to test one unit without depending on other units, you'll need to work extra hard. It is best if you keep this goal in mind when designing your system. To test one class without using any other classes, for example, requires dummy implementations of the other classes for the test. Thus, each class may have two implementations, one for production and one for testing. During testing, you'll need to be able to switch which version of the dependent class your unit uses. A standard technique to accomplish this flexibility is to avoid constructors entirely. All object creation is performed through factories. The factories may return test objects or true objects, but all of the objects returned by one factory correspond to the same interface. In Python, you may instead manipulate sys.path, but modifications to sys.path can be difficult to code correctly. |
|---|
| Speaker's notes: | If you start testing heavily, spend the time to read the documentation on the test framework you're using. Then read it again. It'll save you time to understand the framework so that you don't struggle with the tests themselves. |
|---|
| Speaker's notes: | This point is relevant to unittest and its assertEquals test method. I hit this problem while writing TestDateRange. Internally, assertEquals and failIfEqual use the == and != operators to compare two objects. If the objects' are of a type that does not sensibly implement these methods, the tests will fail. |
|---|
| Speaker's notes: | unittest test failures will be easier to understand if each scenario has a meaningful description as a docstring. |
|---|