Overview
Code that is not tested does not work. It’s a mantra that we all should live by and yet, for various reasons, surprisingly few of us actually do.
But there is so much more to upfront testing than verifying the functional correctness of your code. By paying close attention to the quality of your production and test code, you will learn the non-functional benefits of more cohesive, maintainable, readable, modifiable and bug-free source code.
So while this course is largely about unit testing and refactoring, it is mostly about design and its purpose is to radically alter how you think about and approach design. We believe that by the end of this course you will not only be more productive, you will also be creating more maintainable and understandable designs.
Outline
Testing Fundamentals
- Programmer testing vs debugging
- Cost and quality
- White-box and Black-box testing
- Unit Testing
- Testing behaviour, not methods
- The xUnit/TestNG family
- Test cases, suites, runners, and fixtures
- Assertions/hamcrest
- IDE tooling
Factoring and Refactoring
- Intention revealing code
- Understanding test and production code quality
- Removing duplication and redundancy
- Decomposition and delegation
- Code smells
- Common refactorings
Testing Single Objects
- The red, green, refactor rhythm
- Sufficient design
- Faking it
- Obvious implementation
Testability and Isolation
- Loose coupling and high cohesion
- Open Closed Principle
- Strategies, Templates and Decorators
- Dependency Inversion
- Dependency Management
Testing Clusters of Objects
- Decoupling techniques; layering, facades, dependency injection
- Interaction vs state-based testing
- Pragmatic testing – when and when not to mock
- Static mocks vs dynamic mocks vs stubs
- Designing with interfaces
- Interface discovery through mocking
- Anti-patterns; statics, globals and singletons
Miscellaneous
- Understanding test quality – writing ‘Good Unit Tests’
- Using DSLs to simplify tests
- TDD vs design by contract
- The truth about code coverage
- Continuous integration