Improving Testability Through Design
This course tackles the issues of designing a complex application so that it can be covered with high quality tests.
What you'll learn
A well designed application is not necessarily the one which has a perfect separation of layers, or the one which perfectly implements some predefined design patterns. It is certainly a plus to have these two goals met, but that is not sufficient to make the application really good. We can learn the most about one application by reading the source code of particular methods embedded deep inside of it. A common for loop often reveals more about the design than the whole diagram depicting responsibilities of an application layer in which it is located. The devil is in the details. The best of all intentions in design fails miserably when the low-profile design of small, seemingly unimportant classes is misconceived. In this course, the order of decisions is sorted bottom-up. It is the small class to which we pay attention the most. Only when all things are in place at the microscopic level can we discuss responsibilities of layers, isolation of modules and other high profile topics. The result is a well-built, easily testable and easily maintainable application.
Table of contents
- Preparing Tests for Properties 2m
- Testing Boundary Conditions 3m
- Improving the Boundary Conditions Tests 3m
- Defining the Circle 3m
- Adding an Operation to the Frame 2m
- Completing Tests for the Operation 3m
- Completing the Feature 2m
- Adding More Tests 2m
- Notes About how to Improve Unit Tests 2m
- Adding Another Feature and Its Tests 4m
- Adding a Concrete Implementation of the Circle 2m
- Trying the Demo Application 1m
- Exposing the Defects 2m
- A Case When It's Better Not to Mock 2m
- Exposing a Serious Defect 3m
- Summary 3m
- How Defects Are Introduced 4m
- How to Avoid Introducing Defects 3m
- How to Improve Tests 3m
- Factoring Out Common Logic From Tests 3m
- Using Common Testing Methods 1m
- Decoupling Library Test Code From Concrete Types 3m
- Completing the Testing Library for Decimal Properties 3m
- Avoiding Null Reference Exceptions 3m
- Introducing the Non-Default Constructor 3m
- Making Plans for Constructor Tests 2m
- Single vs. Multiple Tests per Test Method 3m
- Designing the Library for Constructor Tests 3m
- Beginning the Library Implementation 2m
- Adding Features to the Library 3m
- Completing the Constructor Testing Library 2m
- Making the Constructor Test Pass 2m
- Discussion on Declarative Tests 2m
- Discussion on Remaining Transition Tests 2m
- Summary 2m
- About Values 2m
- Immutable Objects as Values 2m
- Example of Immutable Objects in C# 3m
- More Measurements on C# Performance 2m
- Performance of Immutable Collections 3m
- When to Be Careful With Immutable Collections 2m
- One Common Mistake With Immutable Collections 2m
- Different Ways to Validate Data 3m
- Problems When Validating in More Than One Way 3m
- Benefits From Validating Only in the Constructor 2m
- Transactional Qualities of Operations on Immutable Objects 2m
- Avoiding Processing Overhead in Immutable Operations 1m
- Immutability and Equality 1m
- Equality in Objects With Identity 3m
- Example of Immutable Structure 1m
- Immutable Structure Implementation 2m
- Designing the Immutable Circle Interface 3m
- Implementing the Immutable Circle Class 3m
- Implementing the Immutable Frame Class 2m
- Summary 2m
- About Different Kinds of Tests 2m
- About Integration Tests 4m
- Overview of Types That Will Be Tested 3m
- Preparing the Immutable Structure Tests 2m
- Designing the Immutable Structure Tests API 2m
- Beginning the Library Implementation 2m
- Implementing the Assert Method 2m
- Completing the Library 1m
- Testing the Rectangle 2m
- Completing the Immutable Structures Tests 2m
- Testing the Circle Constructor 2m
- Testing the Geometry 2m
- Testing the Immutable Methods 2m
- Preparing the Equality Testing Library 2m
- Design of Declarative Testing Methods 2m
- Assert Method 2m
- Test Cases for Testing the Equals Methods 1m
- Test Cases for Operator Overloads 2m
- Demonstrating the Equality Testing Library 2m
- Discussion 3m
- Summary 1m
- Defining Responsibilities of a Class 2m
- Defining Responsibility Boundaries 2m
- Different Kinds of Test Doubles 2m
- Identifying Responsibilities of the Circle Class 1m
- Moving Somebody Else's Responsibilities Out 3m
- Identifying the Problems 3m
- Motivation Behind the Visitor Pattern 2m
- The Visitor Pattern 2m
- Identifying Weaknesses in the Visitor Pattern 2m
- Modified Visitor Pattern Implementation 2m
- Applying the Visitor Pattern 3m
- Testing the Interaction With Visitors 2m
- Completing the Interaction Tests 2m
- Identifying Responsibilities of the Frame Class 2m
- Pros and Cons of Mocking in Unit Tests 3m
- Integration Tests in Place of Unit Tests With Mocks 2m
- Using Manually Coded Mocks 2m
- Using Concrete Visitor as a Spy 2m
- Using the Fluent Interface to Simplify Integration Tests 1m
- Mocking Framework vs. Manual Mocks 2m
- Running the Tests 1m
- Summary 2m
- The Problem of Connecting to External Systems 4m
- Designing the Actual User Interface 5m
- Layering the Application 4m
- Referencing Issues Between Layers 3m
- Demonstrating the Data Mapping Layer 3m
- Final Organization of Layers 2m
- Adding a Data Access Layer to the Application 3m
- Adding the Data Gateway to the Application 3m
- About Testing the Layered Application 2m
- Handling Database Errors - the Incorrect Way 3m
- Handling Database Errors - the Correct Way 4m
- Summary 4m
- Course Summary 5m