Book Image

Practical Test-Driven Development using C# 7

By : John Callaway, Clayton Hunt
Book Image

Practical Test-Driven Development using C# 7

By: John Callaway, Clayton Hunt

Overview of this book

Test-Driven Development (TDD) is a methodology that helps you to write as little as code as possible to satisfy software requirements, and ensures that what you've written does what it's supposed to do. If you're looking for a practical resource on Test-Driven Development this is the book for you. You've found a practical end-to-end guide that will help you implement Test-Driven Techniques for your software development projects. You will learn from industry standard patterns and practices, and shift from a conventional approach to a modern and efficient software testing approach in C# and JavaScript. This book starts with the basics of TDD and the components of a simple unit test. Then we look at setting up the testing framework so that you can easily run your tests in your development environment. You will then see the importance of defining and testing boundaries, abstracting away third-party code (including the .NET Framework), and working with different types of test double such as spies, mocks, and fakes. Moving on, you will learn how to think like a TDD developer when it comes to application development. Next, you'll focus on writing tests for new/changing requirements and covering newly discovered bugs, along with how to test JavaScript applications and perform integration testing. You’ll also learn how to identify code that is inherently un-testable, and identify some of the major problems with legacy applications that weren’t written with testability in mind. By the end of the book, you’ll have all the TDD skills you'll need and you’ll be able to re-enter the world as a TDD expert!
Table of Contents (21 chapters)
Title Page
Packt Upsell
Foreword
Contributors
Preface
4
What to Know Before Getting Started
Index

An approach to TDD 


TDD is also referred to as Test First Development. In both names, the key aspect is that the test must be written before the application code. Robert C. Martin, affectionately called "Uncle Bob" by the developer community, has created The Three Laws of TDD. They are as follows: 

  1. You are not allowed to write any production code unless it is to make a failing unit test pass
  2. You are not allowed to write any more of a unit test than is sufficient to fail, and compilation failures are failures
  3. You are not allowed to write any more production code than is sufficient to pass the one failing unit test

You can learn more about these laws at http://butunclebob.com/ArticleS.UncleBob.TheThreeRulesOfTdd 

By following these rules, you will ensure that you have a very tight feedback loop between your test code and your production code. One of the main components of Agile software development is working to reduce the feedback cycle. A small feedback cycle allows the project to make a course correction at the first sign of trouble. The same applies to the testing feedback cycle. The smaller you can make your tests, the better the end result will be. 

Note

For a video on Agile, check out Getting Started with Agile by Martin Esposito and Massimo Fascinari (https://www.packtpub.com/application-development/getting-started-agile-video).

An alternative approach 

The original approach to TDD has caused some confusion over the years. The problem is that the principles and approaches just weren't structured enough. In 2006, Dan North wrote an article in Better Software magazine (https://www.stickyminds.com/better-software-magazine/behavior-modification). The purpose of the article was to clear up some of this confusion and help to reduce the pitfalls that developers fell into while learning the TDD process. This new approach to TDD is called Behavior Driven Development (BDD). BDD provides a structure for testing, and a means of communicating between business requirements and unit tests, that is almost seamless. 

The process

It's difficult to start any journey without a goal in mind. There are a few tips and tricks that can be used to help get you started in TDD. The first is red, green, refactor.

Red, green, and refactor

We already discussed writing a failing test before writing production code. The goal is to build the system slowly through a series of tiny improvements. This is often referred to as red, green, refactor. We write a small test (red), then we make it pass by writing some production code (green), then we refactor our code (refactor) before we start the process again.

Many TDD practitioners advocate an It Exists test first. This will help determine that your environment is set up properly and you won't receive false positives. If you write an It Exists test and don't receive a failure right off the bat, you know something is wrong. Once you receive your first failure, you're safe to create the class, method, or function under test. This will also ensure that you don't dive in too deeply right off the bat with lines and lines of code before you're sure your system is working properly.

Once you have your first failure and the first working example, it's time to grow the application, slowly. Choose the next most interesting step and write a failing test to cover this step.

At each iteration, you should pause and evaluate whether there is any cleanup that can happen. Can you simplify a code block? Perhaps a more descriptive variable name is in order? Can any sins committed in the code be corrected, safely, at this time? It's important that you evaluate both the production code and the test suite. Both should be clean, accurate, and maintainable. After all, if it's such a mess that no one would be able to make head or tail of it, what good is the code?

Coder's block

TDD will also help you avoid what writers often call writer's block and what we're calling coder's block. Coder's block happens when you sit down at the keyboard in an attempt to solve a problem but don't know where to begin. We begin at the beginning. Write the easiest, simplest test you can imagine. Write It Exists.   

Why should we care?

We're professionals. We want to do a good job. We feel bad if someone finds fault with our code. If QA finds a bug, it makes us sad. If a user of our system encounters an error, we may cry. We should strive to deliver quality, error-free code and a fully functional, feature-rich application.

We're also lazy, but it's the good kind of lazy. We don't want to have to run the entire application just to validate that a simple function returns the proper value.