logo资料库

practical-test-driven-development-c#7.pdf

第1页 / 共653页
第2页 / 共653页
第3页 / 共653页
第4页 / 共653页
第5页 / 共653页
第6页 / 共653页
第7页 / 共653页
第8页 / 共653页
资料共653页,剩余部分请下载后查看
Preface
Who this book is for
What this book covers
To get the most out of this book
Download the example code files
Download the color images
Conventions used
Get in touch
Reviews
Why TDD is Important
First, a little background
John's story on TDD
Clayton's story on TDD
So, what is TDD?
An approach to TDD
An alternative approach
The process
Red, green, and refactor
Coder's block
Why should we care?
Arguments against TDD
Testing takes time
Testing is expensive
Testing is difficult
We don't know how
Arguments in favor of TDD
Reduces the effort of manual testing
Reduces bug count
Ensures some level of correctness
Removes the fear of refactoring
A better architecture
Faster development
Different types of test
Unit tests
Acceptance tests
Integration tests
End to end tests
Quantity of each test type
Parts of a unit test
Arrange
Act
Assert
Requirements
Why are they important?
User stories
Role
Request
Reason
Gherkin
Givens
When
Then
Our first tests in C#
Growing the application with tests
Our first tests in JavaScript
Why does it matter?
Summary
Setting Up the .NET Test Environment
Installing the .NET Core SDK
Getting set up with VS Code
Downloading the IDE
Installing the VS Code
Adding extensions
Creating a project in VS Code
Setting up Visual Studio Community
Downloading Visual Studio Community
Installing Visual Studio Community
Switching to xUnit
Code katas
FizzBuzz
Creating the test project
The Given3ThenFizz test
The Given5ThenBuzz test
The Given15ThenFizzBuzz test
The Given1Then1 test
Theories
Solution to the FizzBuzz Problem
What is Speaker Meet?
Web API project
Listing Speakers (API)
Requirements
A new test file
Summary
Setting Up a JavaScript Environment
Node.js
What is Node?
Why do we need Node?
Installing Node
Linux
Mac OSX
Windows
NPM
What is NPM?
Why do we need NPM?
Installing NPM?
A quick introduction to JavaScript IDEs
Visual Studio Code
Why Visual Studio Code?
Installing Visual Studio Code
Linux
Mac
Windows
Installing the plugins you will need
Configuring the testing environment
WebStorm
Why WebStorm?
Installing WebStorm
Linux
Mac
Windows
Installing the plugins you will need
Configuring the testing environment
Create React App
What is Create React App?
Installing the global module
Creating a React application
Running the Create React App script
Mocha and Chai
Jest
Mocha
Chai
Sinon
Enzyme
Ejecting the React app
Configuring to use Mocha and Chai
A quick kata to check our test setup
The requirements
The execution
Starting the kata
Summary
What to Know Before Getting Started
Untestable code
Dependency Injection
Static
Singleton
Global state
Abstracting third-party software
Test doubles
Mocking frameworks
The SOLID principles
The Single Responsibility Principle
The Open/Closed principle
The Liskov Substitution principle
The Interface Segregation principle
The Dependency Inversion principle
Timely greeting
Fragile tests
False positives and false failures
Abstract DateTime
Test double types
Dummies
Dummy logger
Example in C#
Example in JavaScript
Stubs
Example in C#
Example in JavaScript
Spies
Example in C#
Example in JavaScript
Mocks
Example in C#
Example in JavaScript
Fakes
Example in C#
Example in JavaScript
N-Tiered example
Presentation layer
Moq
Business layer
Summary
Tabula Rasa – Approaching an Application with TDD in Mind
Where to begin
Yak shaving
Big design up front
A clean slate
One bite at a time
Minimum Viable Product
Different mindset
YAGNI – you aren't gonna need it
Test small
Devil's advocate
Test negative cases first
When testing is painful
A spike
Assert first
Stay organized
Breaking down Speaker Meet
Speakers
Communities
Conferences
Technical requirements
Summary
Approaching the Problem
Defining the problem
Digesting the problem
Epics, features, and stories; oh my!
Epics
Features
Stories
Maintain your backlog
The Speaker Meet problem
Meaningful separation
Speakers
Communities
Conferences
Separate by team function
Technical separations
Technical requirements
React web user interface
.NET Core
.NET Web API
Entity Framework
Azure
Database
An N-Tiered hexagonal architecture
Hexagonal architecture
Basic yet effective N-Tiered divisions
Service layer
Microservices
Data access layer
Repository Pattern
Generic repository
User interface adapter layer
User interface layer
Front-end business layer
Front-end user interface layer
Front-end data source layer
Testing direction
Back-to-front
Defining a data source
Creating a business layer
Building a user interface
Front-to-back
Defining a user interface
Creating a business layer
Building a data source
Inside out
Defining a business layer
Summary
Test-Driving C# Applications
Reviewing the requirements
Speaker listing
API
API tests
Moq
Testing exception cases
Service
Service tests
Clean tests
Repository
The IRepository interface
FakeRepository
Using factories with the FakeRepository
Soft delete
Speaker details
API
API tests
Service
Service tests
Clean the tests
More from the repository
Additional factory work
Testing exception cases
Summary
Abstract Away Problems
Abstracting away problems
Gravatar
Starting with an interface
Implementing a test version of the interface
Implementing the production version of the interface
Future planning
Abstracting the data layer
Extending the repository pattern
The Get method
The GetAll method
The Create method
The Delete method
The Update method
Ensuring functionality
Creating a speaker
Getting a single speaker
Getting multiple speakers
Updating a speaker
Deleting a speaker
Genericizing the repository
Step one – abstract interface
Step two – abstract the concrete class
Converting Create to a generic method
Converting Get to a generic method
Converting GetAll to a generic method
Converting Update to a generic method
Converting Delete to a generic method
Step three – reorient the tests to use the generic repository
InMemoryRepository Create tests
InMemoryRepository Get tests
InMemoryRepository GetAll tests
InMemoryRepository Update tests
Entity Framework
DbContext
Models
Generic repository
Dependency Injection
Wire it all up
Postman
Summary
Testing JavaScript Applications
Creating a React app
Ejecting the app
Configuring Mocha, Chai, Enzyme, and Sinon
The plan
Considering the React component
Looking at Redux testability
The store
Actions
Reducers
Unit-testing an API service
Speaker listing
A mock API service
The Get All Speakers action
Testing a standard action
Testing a thunk
The Get All Speakers reducer
The Speaker listing component
Speaker detail
Adding to the mock API Service
The Get Speaker action
The Get Speaker reducer
The Speaker Detail component
Summary
Exploring Integrations
Implementing a real API service
Replacing the mock API with the real API service
Using Sinon to mock Ajax responses
Fixing existing tests
Mocking the server
Application configuration
End-to-end integration tests
Benefits
Detriments
How much end-to-end testing should you do?
Configuring the API project
Integration test project
Where to begin?
Verifying the repository calls into the DB context
InMemory database
Adding speakers to the InMemory database
Verify that the service calls the DB through the repository
ContextFixture
Verify the API calls into the service
TestServer
ServerFixture
Summary
Changes in Requirements
Hello World
A change in requirements
Good evening
FizzBuzz
A new feature
Number not found
TODO app
Mark complete
Adding tests
Production code
But don't remove from the list!
Adding tests
Production code
Changes to Speaker Meet
Changes to the back-end
Changes to the front-end
Sorted by rating on client side
What now?
Premature optimization
Summary
The Legacy Problem
What is legacy code?
Why does code go bad?
When does a project become legacy?
What can be done to prevent legacy decay?
Typical issues resulting from legacy code
Unintended side effects
Open Closed Principle and legacy code
Liskov Substitution Principle and legacy code
Over-optimization
Overly clever code
Tight coupling to third-party software
Issues that prevent adding tests
Direct dependence on framework and third-party code
Law of Demeter
Work in the constructor
Global state
Static methods
Large classes and functions
Dealing with legacy problems
Safe refactoring
Converting values to variables
Extracting a method
Extracting a class
Abstracting third-party libraries and framework code
Early tests
Gold standard tests
Testing all potential outcomes
Moving forward
Fixing bugs
Free to do unsafe refactoring
Summary
Unraveling a Mess
Inheriting code
The game
A change is requested
Life sometimes hands you lemons
Getting started
Abstracting a third-party class
Unexpected Input
Making sense of the madness
Final beautification
Ready for enhancements
Summary
A Better Foot Forward
What we've covered
Moving forward
TDD is a personal practice
You don't need permission
Grow applications through tests
Introducing TDD to your team
Don’t force TDD on anyone
Gamification of TDD
Showing your team the benefits
Review the results
Rejoining the world as a TDD expert
Seek a mentor
Becoming a mentor
Practice, practice, practice
Summary
Other Books You May Enjoy
Leave a review - let other readers know what you think
Practical Test-Driven Development using C# 7 Unleash the power of TDD by implementing real world examples under .NET environment and JavaScript John Callaway Clayton Hunt
BIRMINGHAM - MUMBAI
Practical Test-Driven Development using C# 7 Copyright © 2018 Packt Publishing All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews. Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the authors, nor Packt Publishing or its dealers and distributors, will be held liable for any damages caused or alleged to have been caused directly or indirectly by this book. Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information. Commissioning Editor: Amarabha Banerjee Acquisition Editor: Shweta Pant Content Development Editor: Aditi Gour Technical Editor: Shweta Jadhav Copy Editor: Safis Editing Project Coordinator: Hardik Bhinde Proofreader: Safis Editing Indexer: Pratik Shirodkar Graphics: Jason Monteiro Production Coordinator: Aparna Bhagat First published: February 2018 Production reference: 1090218 Published by Packt Publishing Ltd. Livery Place 35 Livery Street Birmingham B3 2PB, UK. ISBN 978-1-78839-878-7 www.packtpub.com
mapt.io Mapt is an online digital library that gives you full access to over 5,000 books and videos, as well as industry leading tools to help you plan your personal development and advance your career. For more information, please visit our website.
Why subscribe? Spend less time learning and more time coding with practical eBooks and Videos from over 4,000 industry professionals Improve your learning with Skill Plans built especially for you Get a free eBook or video every month Mapt is fully searchable Copy and paste, print, and bookmark content
PacktPub.com Did you know that Packt offers eBook versions of every book published, with PDF and ePub files available? You can upgrade to the eBook version at www.Packt Pub.com and as a print book customer, you are entitled to a discount on the eBook copy. Get in touch with us at service@packtpub.com for more details. At www.PacktPub.com, you can also read a collection of free technical articles, sign up for a range of free newsletters, and receive exclusive discounts and offers on Packt books and eBooks.
Foreword I'll be honest, when I first looked at the title of this book, Practical Test-Driven Development Using C# 7, I thought "do we really need another book outlining the basics of unit testing and TDD?" I mean at this point, TDD isn't really that new, and plenty of authors have written about what TDD is and have given us countless examples of how to score a bowling or a tic-tac-toe game using TDD to drive the creation of the application. The problems most developers run into when learning or trying to implement TDD is not understanding what TDD itself is and what "red, green, refactor" means, but how to practically implement it in real-world situations. Most real- world applications are messy and don't conform easily to the usual TDD shoehorn that many well-meaning TDD books and examples try to demonstrate. The real difficulty in successfully implementing TDD arises when you try to use it to develop a non-trivial application—an application with databases and multiple layers and external services you need to call. As a consultant, I spent a large amount of time teaching teams who were supposedly doing TDD how to actually do TDD. I saw countless examples of teams who would hardcode tests with fake data or call out directly to a database, because they didn't really understand what a mock was and how to isolate their tests. Moreover, I found many development teams that understood the basics of TDD, but didn't understand how to take business requirements and user stories and convert them into working unit tests that they can actually use to develop the system they were trying to create. I've never had a difficult time teaching software developers the basics of TDD. It's fairly easy to explain how TDD works and how to get started doing it—and there have always been plenty of resources available to teach all that. No, what companies paid me the big bucks for was to sit down with their teams and explain all the nuances of TDD. What do you do when you have to mock a class that directly uses the database? How do you handle 15 test cases that have different input values but are essentially testing the same thing? Where do we start with TDD—which tests do we write first?
分享到:
收藏