
Outline the fundamentals of test-driven development, clarifying what TDD is and why we need it, plus key concepts like red-green-refactor, unit tests, code coverage, and testing frameworks.
Explore why test-driven development matters by illustrating common coding traps, production bugs, and the role of unit testing in preventing regressions, leading to TDD as a solution.
Test-driven development, or test-first development, drives production code by writing tests before code to shape a modular design, delivering about 70% test coverage and reducing bugs by 40–80%.
Master red/green/refactor, the core tdd technique, by writing a unit test, running to see a red failure, implementing production code to green, and refactoring as needed.
Follow the three laws of TDD: write a failing test before production code, keep tests minimal, and avoid excess production code to maintain a balanced test suite.
Keep tests clean to maintain a safety net as requirements change. Identify design smells—rigidity, fragility, immobility, viscosity, and needless complexity—and use solid principles and automated tests to stay maintainable.
Define and enforce fast, independent, repeatable, and self-validatable unit tests before production code, while avoiding ordered tests to prevent temporal coupling.
Understand code coverage as a metric showing how much code is exercised by tests, with examples like 82% overall and 70% for the Character class in Visual Studio.
Learn about unit, integration, and acceptance tests, how TDD applies to each, and how acceptance tests in plain English fit into a balanced test pyramid.
Discover testing frameworks and tools for tdd in c#, from unit testing with NUnit, MSTest, and xUnit to acceptance testing with SpecFlow and FitNesse, and mocking and ui testing options.
Explore cases where TDD cannot be applied directly, including security, multithreading, and GUI testing. Follow a pragmatic approach: use TDD when beneficial, otherwise design first and avoid dogmatic testing.
Apply TDD by writing tests before production code, adopting the red-green-refactoring cycle. Ensure tests are fast, isolated, repeatable, and aim for at least 70% test coverage as a safety net.
Master test-driven development in C# from a to z by learning tdd techniques (faking, triangulation, obvious implementation), practical tests (fibonacci, fizzbuzz, roman numerals, tic-tac-toe, sticks), and continuous testing within agile.
In an agile, iterative workflow, customers and developers define user stories and acceptance tests, sketch architectural diagrams, then implement features with TDD, iterating until unit and acceptance tests pass.
Discover how shortcut-rich editors and refactoring tools speed up TDD in C#. Compare Visual Studio with ReSharper (R#), CodeRush, and VSCommands, and consider Rider for faster editing and testing.
Explore implementing the Fibonacci numbers with test-driven development, starting from simple tests and triangulation. See how NUnit tests drive the GetFibonacci logic, from base cases to recursion.
Master three main TDD techniques—faking, triangulation, and obvious implementation—using constant values, test-driven refinement, and edge-case testing (nulls, zeroes, max values) to guide C# development.
Learn how to apply test-driven development in c# by starting with exceptional, degenerate, and ancillary tests, covering nulls, empty strings, and edge cases before implementing the core canonicalization.
Practice test-driven development in C# by implementing FizzBuzz through unit tests, covering Fizz, Buzz, and FizzBuzz cases, and validating with NUnit in Visual Studio.
Apply test-driven development to implement a roman numeral parser in c#, using a dictionary map, iterating characters, handling subtractive notation, and refactoring with well-named methods.
Learn how to implement an updateable spin synchronization primitive to manage multithreading, timeouts, and event-driven responses within a TDD workflow, with live coding and tests.
Explore continuous testing in c#, using tdd to build a tic-tac-toe game, and leverage NCrunch, Live Unit Testing in Visual Studio, and dotCover for automated test feedback.
From a 3x3 tic-tac-toe, implement game rules with TDD, counting moves, tracking square state, and determining the winner, while using NCrunch for automated testing.
Embrace an assert-first approach in tdd, starting tests by writing assertions to define and verify correct outputs, revealing the simplest, targeted api for faster test creation.
Demonstrates test-driven development in a sticks game with an immutable game state, covering constructor checks, invalid moves, and machine versus human turns with machine moved and game over events.
Conclude by applying TDD in C# with faking, triangulation, and obvious implementation, building fibonacci, fizzbuzz, roman numeral parser, and tic-tac-toe, while avoiding multithreading tests and embracing continuous testing and katas.
Learn TDD in C# from a to z by practicing code katas, including the stack kata, immutable stack kata, and list kata to sharpen algorithms and practice programming.
Practice a test-driven approach to building a generic C# stack with push, pop, and peek operations. Verify IsEmpty, count, and empty-stack exceptions using a list-backed implementation.
Demonstrates building an immutable stack in C# using Lippert’s approach: define IStack<T> with Push, Pop, Peek, and IsEmpty; implement a nested EmptyStack state; and drive design with tests.
Define a generic singly linked list API with head and tail, and implement add and remove operations. Drive tests, cover edge cases, and examine remove last and remove first.
Explore code katas to practice TDD, compare a regular stack with an immutable version, and run through the list kata, then discuss TDD and preview topics for the next section.
Explore test doubles, dependency injection, and the types: fakes, dummies, stubs, spies, mocks, while learning manual doubles and using NSubstitute for mocks.
Explore unit testing with NUnit for a wage calculation that depends on a DbGateway and a Logger, highlighting challenges of external dependencies and flaky tests.
Refactor the customer design to make code testable using abstractions and dependency injection, emphasize constructor injection over property injection. Explore the concept of test doubles to inform testing strategies.
Explore test doubles for unit testing, including dummy, stub, spy, mock, and fake, and learn how each controls or verifies external dependencies during tests.
Learn to implement a dummy logger and a stub db gateway, set up test doubles in unit tests, and use spies, mocks, and fakes to verify interactions.
Explore the drawbacks of hand-rolled mocks in TDD, including boilerplate code, maintenance challenges for interfaces with many members, and the use of mocking frameworks to overcome these problems.
Discover how mocking frameworks create test doubles to isolate dependencies and streamline unit testing. Compare constrained and unconstrained approaches and review popular tools like NSubstitute, Moq, and Typemock Isolator.
Learn how to replace dependencies with the NSubstitute mocking framework, create test doubles for IDbGateway and logger, configure returns for any id, and assert GetWorkingStatistics called with the proper id.
Master NSubstitute essentials: mock methods and properties, return values with Any and Arg.Is, test exceptions with Throws, verify calls with Received, and raise events for async tests.
Compare the Detroit and London schools of testing, showing Detroit uses assertions to verify state while London verifies object interactions. Embrace a pragmatic, best-practices approach to unit testing.
Learn to use test doubles such as fakes, dummies, stubs, spies, and mocks to replace controllable dependencies, refactor for testability, and compare classic Detroit school with mockists London school.
Learn how acceptance testing complements test-driven development by translating business requirements into unit tests using SpecFlow and Gherkin. Write a simple feature with a scenario and implement a passing test.
Explore acceptance tests in TDD for C#, showing how business readable automated tests bridge the problem domain, provide executable documentation, and leverage SpecFlow in agile workflows.
Discover how SpecFlow uses Gherkin feature files and a Visual Studio extension to generate executable C# code bound to scenarios, enabling parameterized, reusable steps and clean, maintainable tests.
Explore Gherkin, a business readable domain specific language for behavior descriptions, and learn how features, scenarios, and steps map to C# functions to support documentation and acceptance tests in TDD.
Install the SpecFlow extensions for Visual Studio and the SpecFlow and testing NuGet packages to enable acceptance testing with given, when, then steps.
Explore the test pyramid from unit to integration and acceptance tests, and see how UI tests fit as end-to-end integration tests. Compare UI-based and high-level interface acceptance tests.
Compare web-UI and desktop-UI testing frameworks: Selenium, Visual Studio Coded UI Test, and TestStack.White, and learn how each records actions or uses manual code for maintainable tests.
Discover how the White framework uses the UI Automation API to locate controls, launch applications, and work with windows and standard or custom UI items using automation IDs.
Learn to write business readable automated acceptance tests with SpecFlow and Gherkin, using given-when-then steps, and compare high-level interfaces or ui manipulations for a WPF app through test-driven development.
Demonstrate tdd techniques, dependency injection, mocking, and acceptance tests through a true-false game with a statement editor saved to xml, in a wpf project using caliburn.micro and castle windsor.
Introduce an MVVM app using a serializable statement model with INotifyPropertyChanged, XML serialization, a basic persistence layer, and a Caliburn.Micro bootstrapper hosting game and main views.
Express features with SpecFlow and Gherkin, install Visual Studio tooling, and implement editing and playing the game scenarios using a shared statement list and a UI automation API.
Apply the page object design pattern to abstract UI interactions, wrap windows with a UI API, and expose high-level actions for main and game windows using TestStack.White.
Implement acceptance tests in a c# tdd workflow by using before/after scenario hooks to isolate each test with a fresh application instance, launching and interacting through spec flow steps.
Master view model implementation with TDD in C#, drive development with tests, bind via Caliburn Micro, use in-memory persistence, and employ a builder to assemble the main view model.
implements the game view model with tdd in c#, binding statement text, statement number, and score, plus a dialogue service. drives testing of next statements, correct/incorrect answers, and end-of-game logic.
See how acceptance tests and high-level requirements drive TDD in C#, from writing scenarios and user interface wrappers to test-first viewmodels, with the builder pattern for cleaner construction.
Explore test-driven development in depth, from defining TDD to its philosophy, relationships with agile, upfront design, unit tests, architecture versus design, and balancing simplicity with code suppleness.
Recognize that TDD may not suit all programmers. Weigh that writing tests is a professional requirement, yet some embrace production code first and others live without TDD.
Learn how agile and TDD relate: TDD is a technique that can stand alone, while agile is a broader methodology guiding requirements, collaboration, and short development cycles.
Tdd supports good design without replacing upfront architecture. Start with a big picture, sketch use cases and actors, and design clear API names before coding.
Unit tests alone do not guarantee project success and can become a liability without proper design; learn to craft reliable tests and balance coverage with maintainability.
Prioritize well-constructed unit tests in a TDD approach, treating tests as production code to keep maintainable, robust software while applying SOLID principles like SRP, OCP, LSP, and DIP.
Explore architecture and design, learn the difference, and how architecture is a social, high-level view built from significant components; defer early decisions and distinguish architecture patterns from design patterns.
Recognize that TDD is a matter of taste, but writing tests is essential. Acknowledge that Agile goes hand in hand with TDD, and architecture and design require balanced best practices.
Explore TDD practices in C# from a to z, covering pair-programming and ping-pong programming, test data techniques, positive-if statements, Shouldly assertions, while examining singletons, static classes, immutability and testability.
End tdd day per Kent Beck: in a team keep tests green in source control; solo, end with failing test to ease next-day work and never check in broken tests.
Explore pair-programming and ping-pong programming as TDD practices in C#, highlighting knowledge sharing, code quality, faster development, and collaborative problem solving.
Prioritize test quality by keeping cyclomatic complexity near 1 and avoiding if statements. Limit tests to about 10 lines, refactor duplication, and use the builder pattern to simplify initialization.
Avoid strange test data and excessive test cases in tdd. Use evident data, like 1, and near-value pairs such as 2 and 3 to clarify money operations.
Explore how the shouldly framework improves assertion readability and error messages, showing results such as game.points should be 100 but was 90, and covering shouldbe, shouldnotbe, shouldbetrue/false, and approval tests.
Prefer positive if-statements by naming booleans affirmatively and avoiding double negatives, improving readability in tests and production code.
Examine the debate in test-driven design over testing trivial code, including Uncle Bob and Mark Seemann, and weigh getters, setters, one-line methods, indirect testing, and future changes.
Clarify the rule of a single assertion and demonstrate testing one aspect or behavior per test, using a Money class with amount in kopeks and rubles.
Examine how singletons and static classes introduce global state and hidden dependencies that complicate unit testing. Show how constructor injection and exposing dependencies through the interfaces improves testability and design.
Explore the builder pattern for immutable objects, using fluent methods like WithName, WithAge, and WithPhones to create testable, maintainable tests with mocks.
Master tdd in c# from a to z, emphasizing test quality and maintainability; avoid long init, duplication, slow tests, and magic numbers with constants, using shouldly, pair-programming, and builder patterns.
Promote engagement with this bonus lecture by joining the mailing list, leaving reviews, and supporting the creator via discounted courses, the blog at engineerspock.com, and Patreon.
Today unit testing is the absolutely required skill which is required from any professional developer. Companies expect from developers to know how to write unit tests including all the most important topics such as mocking and test driven development (TDD in short).
This course is all about practicing TDD using C# programming language and NUnit as a unit testing framework. Along the way, we will learn the concepts related to unit testing. This course does not cover all the features of NUnit. This course is way more interesting.
Learning unit testing and TDD puts a powerful and very useful tool at your fingertips. Being familiar with unit testing and TDD you can write reliable and maintainable applications. It is very hard to lead a project which is not covered by unit tests.
Content and Overview
This course is primarily aimed at developers who’re already familiar with the basics of unit testing and dependency injection. Some experience in C# programming is required. The course provides solid theoretical base reinforced by tons of practical material.
We start with basics of test-driven development. Why we need TDD? What is TDD? When TDD fails, three laws of TDD, different types of tests, tooling and other fundamental topics. This section is mostly theoretical.
Theory is dead without practice, so starting from the second section, you’ll see tons of programming sessions where I’ll demonstrate how to implement generating of Fibonacci numbers, FizzBuzz, parsing of roman numerals, updateable spin synchronization primitives, tic-tac-toe or crosses and noughts game and game in sticks. You’ll also learn:
How a regular agile development process looks like
That you need to learn shortcuts to practice TDD more smoothly
Three Main TDD techniques: faking, triangulation and obvious implementation
Which tests to write first
How to start writing a test in a TDD manner
Stack kata
Immutable stack kata
And list kata
What is acceptance testing
About the SpecFlow acceptance testing framework
How to write acceptance tests with SpecFlow in Gherkin language
What are UI tests
What tools for writing UI Tests exist
How to access UI through the TestStack.White framework
Have you heard about katas? No, I’m talking about programming. In the third section, you’ll learn what is a code kata and I’ll demonstrate three code katas:
Growing an application by writing tests first, we’re not only writing unit tests first. So, in the next section, you’ll learn what is acceptance testing and integration testing. You’ll learn:
You’ll need to see how to apply all the material learned by this moment. Practice helps very much with understanding especially when we uncover highly practical topics such as TDD. That’s why I decided to show you how all the things work in practice altogether. So, in the next section, you’ll see a real enterprise approach for working on a software project in action.
I’ll build a bridge to UI through TestStack.White applying the Page Object design pattern
I’ll write acceptance tests using the bridge built for accessing UI
I’ll implement ViewModels and all the corresponding business-logic
What is TDD in the end? Is it possible to live without it?
The relationships between TDD and Agile development process
Should we design architecture upfront or not?
Do unit tests guarantee the success?
Quality of tests, some criterions
How to express data for writing unit tests
Shouldly for writing more readable assertions
Singletons, Static classes and testability, Builder design pattern
And some other important topics
The last two sections are rather philosophical. We will discuss:
What is TDD in the end? Is it possible to live without it?
The relationships between TDD and Agile development process
Should we design architecture upfront or not?
Do unit tests guarantee the success?
Quality of tests, some criterions
How to express data for writing unit tests
Shouldly for writing more readable assertions
Singletons, Static classes and testability, Builder design pattern
and some other important topics
Here is my Teaching Approach -
No fluff, no ranting, no beating the air. I respect your time. The course material is succinct, yet comprehensive. All important concepts are covered. Particularly important topics are covered in-depth.
Take this course, and you will be satisfied.