Veze, linkovi
Kompjuter biblioteka
Unit Testing Principles, Practices, and Patterns

Tehnologija Tehnologija

Unit Testing Principles, Practices, and Patterns

Autor: Vladimir Khorikov
Broj strana: 304
ISBN broj: 9781617296277
Godina izdanja: 2020.

Twitter   Facebook   Linkedin   Pinterest   Email
Predlog za prevod


Kupite na Amazonu


This book is an indispensable resource. Greg Wright, Kainos Software Ltd. Unit Testing Principles, Patterns and Practices shows you how to refine your existing unit tests by implementing modern best practices. You’ll learn to spot which tests are performing, which need refactoring, and which need to be deleted entirely! Upgrade your testing suite with new testing styles, good patterns, and reliable automated testing. Part 1: The bigger picture

1 The goal of unit testing

1.1 The current state of unit testing

1.2 The goal of unit testing

1.2.1 What makes a good or bad test?

1.3 Using coverage metrics to measure test suite quality

1.3.1 Understanding the code-coverage metric

1.3.2 Understanding the branch coverage metric

1.3.3 Problems with coverage metrics

1.3.4 Aiming at a particular coverage number

1.4 What makes a successful test suite?

1.4.1 It’s integrated into the development cycle

1.4.2 It targets only the most important parts of your code base

1.4.3 It provides maximum value with minimum maintenance costs

1.5 What you will learn in this book

1.6 Summary

2 What is a unit test?

2.1 The definition of "unit test"

2.1.1 The isolation issue: The London take

2.1.2 The isolation issue: The classical take

2.2 The classical and London schools of unit testing

2.2.1 How the classical and London schools handle dependencies

2.3 Contrasting the classical and London schools of unit testing

2.3.1 Unit testing one class at a time

2.3.2 Unit testing a large graph of interconnected classes

2.3.3 Revealing the precise bug location

2.3.4 Other differences between the classical and London schools

2.5 Integration tests in the two schools

2.5.1 End-to-end tests are a subset of integration tests

2.6 Summary

3 The anatomy of a unit test

3.1 How to structure a unit test

3.1.1 Using the AAA pattern

3.1.2 Avoid multiple arrange, act, and assert sections

3.1.3 Avoid if statements in tests

3.1.4 How large should each section be?

3.1.5 Differentiating the system under test

3.1.6 Dropping the arrange, act, and assert comments from tests

3.2 Exploring the xUnit testing framework

3.3 Reusing test fixtures between tests

3.3.1 High coupling between tests is an anti-pattern

3.3.2 The use of constructors in tests diminishes test readability

3.3.3 A better way to reuse test fixtures

3.4 Naming a unit test

3.4.1 Unit test naming guidelines

3.4.2 Example: Renaming a test toward the guidelines

3.5 Refactoring to parameterized tests

3.5.1 Generating data for parameterized tests

3.6 Using an assertion library to further improve test readability

3.7 Summary

Part 2: Making your tests work for you

4 The four pillars of a good unit test

4.1 Diving into the four pillars of a good unit test

4.1.1 The first pillar: Protection against regressions

4.1.2 The second pillar: Resistance to refactoring

4.1.3 What causes false positives?

4.1.4 Aim at the end result instead of implementation details

4.2 The intrinsic connection between the first two attributes

4.2.1 Maximizing test accuracy

4.2.2 The importance of false positives and false negatives: The dynamics

4.3 The third and fourth pillars: Fast feedback and maintainability

4.4 In search of an ideal test

4.4.1 Is it possible to create an ideal test?

4.4.2 Extreme case #1: End-to-end tests

4.4.3 Extreme case #2: Trivial tests

4.4.4 Extreme case #3: Brittle tests

4.4.5 In search of an ideal test: The results

4.5 Exploring well-known test automation concepts

4.5.1 Breaking down the Test Pyramid

4.5.2 Choosing between black-box and white-box testing

4.6 Summary

5 Mocks and test fragility

5.1 Differentiating mocks from stubs

5.1.1 The types of test doubles

5.1.2 Mock (the tool) vs. mock (the test double)

5.1.3 Don’t assert interactions with stubs

5.1.4 Using mocks and stubs together

5.1.5 How mocks and stubs relate to commands and queries

5.2 Observable behavior vs. implementation details

5.2.1 Observable behavior is not the same as a public API

5.2.2 Leaking implementation details: An example with an operation

5.2.3 Well-designed API and encapsulation

5.2.4 Leaking implementation details: An example with state

5.3 The relationship between mocks and test fragility

5.3.1 Defining hexagonal architecture

5.3.2 Intra-system vs. inter-system communications

5.3.3 Intra-system vs. inter-system communications: An example

5.4 The classical vs. London schools of unit testing, revisited

5.4.1 Not all out-of-process dependencies should be mocked out

5.4.2 Using mocks to verify behavior

5.5 Summary

6 Styles of unit testing

6.1 The three styles of unit testing

6.1.1 Defining the output-based style

6.1.2 Defining the state-based style

6.1.3 Defining the communication-based style

6.2 Comparing the three styles of unit testing

6.2.1 Comparing the styles using the metrics of protection against regressions and feedback speed

6.2.2 Comparing the styles using the metric of resistance to refactoring

6.2.3 Comparing the styles using the metric of maintainability

6.2.4 Comparing the styles: the results

6.3 Understanding functional architecture

6.3.1 What is functional programming?

6.3.2 What is functional architecture?

6.3.3 Comparing functional and hexagonal architectures

6.4 Transitioning to functional architecture and output-based testing

6.4.1 Introducing an audit system

6.4.2 Using mocks to decouple tests from the filesystem

6.4.3 Refactoring toward functional architecture

6.4.4 Looking forward to further developments

6.5 Understanding the drawbacks of functional architecture

6.5.1 Applicability of functional architecture

6.5.2 Performance drawbacks

6.5.3 Increase in the code base size

6.6 Summary

7 Refactoring toward valuable unit tests

7.1 Identifying the code to refactor

7.1.1 The four types of code

7.1.2 Using the Humble Object pattern to split overcomplicated code

7.2 Refactoring toward valuable unit tests

7.2.1 Introducing a customer management system

7.2.2 Take 1: Making implicit dependencies explicit

7.2.3 Take 2: Introducing an application services layer

7.2.4 Take 3: Removing complexity from the application service

7.2.5 Take 3: Introducing a new Company class

7.3 Analysis of optimal unit test coverage

7.3.1 Testing the domain layer and utility code

7.3.2 Testing the code from the other three quadrants

7.3.3 Should you test preconditions?

7.4 Handling conditional logic in controllers

7.4.1 Using the CanExecute/Execute pattern

7.4.2 Using domain events to track changes in the domain model

7.4.3 Conclusion

7.5 Summary

Part 3: Integration testing

8 Why integration testing?

8.1 What is an integration test?

8.1.1 The role of integration tests

8.1.2 The test pyramid revisited

8.1.3 Integration testing versus failing fast

8.2 Which out-of-process dependencies to test directly

8.2.1 The two types of out-of-process dependencies

8.2.2 Working with both managed and unmanaged dependencies

8.2.3 What if you can’t use a real database in integration tests?

8.3 Integration testing: An example

8.3.1 What scenarios to test?

8.3.2 Categorizing the database and the message bus

8.3.3 What about end-to-end testing?

8.3.4 Integration testing: The first try

8.4 Using interfaces to abstract dependencies

8.4.1 Interfaces and loose coupling

8.4.2 Why use interfaces for out-of-process dependencies?

8.4.3 Using interfaces for in-process dependencies

8.5 Integration testing best practices

8.5.1 Making domain model boundaries explicit

8.5.2 Reducing the number of layers

8.5.3 Eliminating circular dependencies

8.5.4 Using multiple act sections in a test

8.6 How to test logging functionality?

8.6.1 Should you test logging?

8.6.2 How to test logging?

8.6.3 How much logging is enough?

8.6.4 How to pass logger instances around?

8.6.5 Conclusion

8.7 Summary

9 Mocking best practices

9.1 Maximizing mocks' value

9.1.1 Verifying interactions at the system edges

9.1.2 Replacing mocks with spies

9.1.3 What about IDomainLogger?

9.2 Mocking best practices

9.2.1 Mocks are for integration tests only

9.2.2 Not just one mock per test

9.2.3 Verifying the number of calls

9.2.4 Only mock types that you own

9.3 Summary

10 Testing the database

10.1 Prerequisites for testing the database

10.1.1 Keeping the database in the source control system

10.1.2 Reference data is part of the database schema

10.1.3 Separate instance for every developer

10.1.4 State-based versus migration-based database delivery

10.2 Database transaction management

10.2.1 Managing database transactions in production code

10.2.2 Managing database transactions in integration tests

10.3 Test data life cycle

10.3.1 Parallel versus sequential test execution

10.3.2 Clearing data between test runs

10.3.3 Avoid in-memory databases

10.4 Reusing code in test sections

10.4.1 Reusing code in arrange sections

10.4.2 Reusing code in act sections

10.4.3 Reusing code in assert sections

10.4.4 Does the test create too many database transactions?

10.5 Common database testing questions

10.5.1 Should you test reads?

10.5.2 Should you test repositories?

10.5.3 Conclusion

10.6 Summary

Part 4: Unit testing best practices

11 Unit testing anti-patterns

11.1 Unit testing private methods

11.1.1 Private methods and test fragility

11.1.2 Private methods and insufficient coverage

11.1.3 When testing private methods is acceptable

11.2 Exposing private state

11.3 Leaking domain knowledge to tests

11.4 Code pollution

11.5 Mocking concrete classes

11.6 Working with time

11.6.1 Time as an ambient context

11.6.2 Time as an explicit dependency

11.6.3 Conclusion

11.7 Summary

About the Technology

Great testing practices will help maximize your project quality and delivery speed. Wrong tests will break your code, multiply bugs, and increase time and costs. You owe it to yourself—and your projects—to learn how to do excellent unit testing to increase your productivity and the end-to-end quality of your software.

About the book

Unit Testing Principles, Patterns and Practices teaches you to design and write tests that target the domain model and other key areas of your code base. In this clearly written guide, you learn to develop professional-quality test suites, safely automate your testing process, and integrate testing throughout the application life cycle. As you adopt a testing mindset, you’ll be amazed at how better tests cause you to write better code.

What's inside

Universal guidelines to assess any unit test Testing to identify and avoid anti-patterns Refactoring tests along with the production code Using integration tests to verify the whole system

About the reader

For readers who know the basics of unit testing. The C# examples apply to any language.

About the author

Vladimir Khorikov is an author, blogger, and Microsoft MVP. He has mentored numerous teams on the ins and outs of unit testing.



• Nikola Ajdukovic
Ovo je knjiga koja bi svakako trebala da se prevede na srpski jezik. Za razliku od drugih izvora za ucenje koji se fokusiraju ili na same osnove ili na sintaksu nekog frameworka za testove ova knjiga objasnjava ne samo za sta treba pisati (koje delove koda) nego i u kakvoj su sprezi unit i integracioni testovi. Isto tako knjiga daje i jasne razloge kako treba razdvajati produkcijski kod na tri dela podatke, kalkulacije i akcije, tako sto uvodi osnove funkcionalnog programiranja. Testovi kako integracioni tako i unit su neophodna mreza koja je potrebna svakom programeru sto zbog lakseg usudjivanja refaktorisanja postojeceg koda usled nadolazenja novih feature-a sto i zbog toga sto oni prvi ukazuju na skretanje u pogresnu stranu prilikom dizajna (ili redizajna) produkcijskog koda. Inace autor ove knjige Vladimir Khorikov je autor nekoliko odlicnih kurseva vezano za Domain Driven Design i Applaying Functional progamming tako da ova knjiga je samo zatvaranje kompletne slike koju bi svaki programer trebao da ima prilikom razvoja neke aplikacije

• Saša
Ovo obavezno prevedite! Knjiga je top!

• Lazar
Preporuka za prevod. Knjiga ima veoma dobre ocene na amazonu.

• Siniša Nikolić
Ovo bi trebala da bude biblija svakog programera. Svako ko želi da piše kvalitetan kod mora biti majstor testiranja. Ja sam jedan od onih koji će sigurno kupiti ovu knjigu.

• Dragan
Ovo morate prevesti. Dosta programera u Srbiji zeli da nauci pisanje Unit testova, ali obicno ide na sajtove i uci. Ovo je odlicna knjiga, procitao sam je na engleskom. Ali zelim da je i procitam i na srpskom i da mi stoji na polici. Ovo je must have za sve koji zele biti dobri programeri.

Ostavite komentar Ostavite komentar



Nema slike

Popust cena:

Veze, linkovi
Linkedin Twitter Facebook
© Sva prava pridržana, Kompjuter biblioteka, Beograd, Obalskih radnika 4a, Telefon: +381 11 252 0 272