41
Unit testing best practices Oleksandr Masalov

Unit testing best practices

Embed Size (px)

DESCRIPTION

.NET IT Share - Unit testing best practices

Citation preview

Page 1: Unit testing best practices

Unit testing best practices

Oleksandr Masalov

Page 2: Unit testing best practices

• зачем нужны юниттесты?• unit of coverage/work• требования к юниттестам и как

не нужно писать тесты• повторное использование

кода(initialization, asserts)

Agenda

Page 3: Unit testing best practices

Зачем нужны юниттесты?

поиск багов? (интеграционные тесты)регрессионное тестирование?

(интеграционные тесты)улучшение качества кода(дизайна

компонентов)поиск багов в случае рефакторинга!

(изменение поведения компонента)источник спецификации системы

masalov.alexander mas
- Make each test orthogonal (i.e., independent) to all the others - Don’t make unnecessary assertions - Mock out all external services and state - Avoid unnecessary preconditions - Don’t unit-test configuration settings - Name your unit tests clearly and consistently Trust worthy- Make it easy to run- Avoid test logic- Don't repeat production logic- Dont't use things that keeps changingMaintanable- Test only publics! Avoid testing private/protected memebers(makes your tests more brittle)- Re-use test code: - Create objects using common methods- Enforce test isolation - No dependency between tests - Don't run a test from another test - - Test one thing - Avoid multiple asserts on diffrerent objects - Create multiple tests - Hard to name - - one mock per test Readable tests: - project structure - No magic values - Naming a unit tests - Naming variables - separate assert from action - test structure- Use test cases
Page 4: Unit testing best practices

Unit of coverage/work

Page 5: Unit testing best practices

Return value/exception

Page 6: Unit testing best practices

Example: Return value/exception

Page 7: Unit testing best practices

State change

Page 8: Unit testing best practices

Example: State change

Page 9: Unit testing best practices

3rd party call

Page 10: Unit testing best practices

Example: 3rd party call

Page 11: Unit testing best practices

Требования к юниттестам

Page 12: Unit testing best practices

Надежные (Trustworthy)

• должны легко запускаться

• failed test == поведение модуля изменилось

• тесты независимы друг от друга

Page 13: Unit testing best practices

Readable

• Структура

• Именование тестов (self-desciptive)

• Именование переменных (self-desciptive)

• No IFs, SWITCHs (split test)

• 1-15 lines

• Don't Repeat Yourself & Descriptive And Meaningful Phrases

Page 14: Unit testing best practices

Структура

Page 15: Unit testing best practices

Именование тест методов

Pattern:

UnitOfWork_Input_ExpectedOutputUnitOfWork_LogicalAction_ExpectedChangeInBehaviorUnitOfWork_ActionOrInput_ExpectedCallToThirdParty

Examples:

Addition_PositiveNumbers_ReturnsSum()Addition_WhenCalled_ResetsTheNextSum()Addition_NegativeNumbers_CallsLogger()

Page 16: Unit testing best practices

Именование тест методов - 2

Page 17: Unit testing best practices

Поддерживаемые (Maintainable)

• Тестируйте только public интерфейс

• Не используйте объекты, которые непостоянны(DateTime.Now, Thread, Random etc)

• Не дублируйте продакшин логику

• Не тестируйте всё в одном тесте

• Многократно используйте код для тестов(initialize, assert etc)

Page 18: Unit testing best practices

Не используйте объекты, которые непостоянны

DateTime.Now, Thread, Random etc

Page 19: Unit testing best practices

Не дублируйте продакшин логику

Page 20: Unit testing best practices

Не тестируйте всё в одном тесте

• сложно именовать

• тест не отображает полной картины

Page 21: Unit testing best practices

Структурируйте тесты!

• Arrange, Act, Assert

• Four-Phase Test

• Given/When/Then

1) DRY - Don't repeat yourself- используйте сетап и тердаун методы для инициализации и удаления данных- проперти в рамках тест класса не используются всеми тест методами(делает тесты тяжелее читаемыми)- дублируемые участки плохи, тем что надо изменять все кусочки, при изменении функционала2) DAMP - made more maintanableDescriptive and meaningful pharses- тесты должны быть легко читаемыми- думай о юниттесте как о дсл-masalov.alexander mas
Page 22: Unit testing best practices

Arrange, Act, Assert - format

if(test.lines <= 3)

{

без форматирования

}else if (test.lines > 3 && !test.hasSubSections)

{

blank line разделитель

}

else{

code comment(Arrange, Act, Assert)

}

Page 23: Unit testing best practices

Four-Phase Test

Page 24: Unit testing best practices

Given/When/Then

Page 25: Unit testing best practices

Code reuse - Initialization problem

Page 26: Unit testing best practices

Test data initialization:

•Object Mother pattern

•Test Data builder pattern

SUT initialization:

•SUT Mother pattern

•SUT Builder pattern

•Auto-Mocking container

"system under test" = "whatever thing we are testing"(class, object, method)

Page 27: Unit testing best practices

Object Mother Pattern

var basket = CreateWithDiscount();

var basket = CreateWithSmallDiscount();

var basket = CreateWithLargeDiscount();

var basket = CreateWithLargeDiscountButWithSpecialOffer();

Page 28: Unit testing best practices

Fluent Builder Pattern

var basket = new BasketBuilder().Build();

var basket = new BasketBuilder().WithSmallDiscount().Build();

var basket = new BasketBuilder()

.WithLargeDiscount()

.WithSpecialOffer()

.Build(); …

Page 29: Unit testing best practices

Example: Test Data Builder

Page 30: Unit testing best practices

SUT Mother

Page 31: Unit testing best practices

SUT Builder

Page 32: Unit testing best practices

Auto-Mocking container pattern

Page 33: Unit testing best practices

Code reuse - Asserts problem

Page 34: Unit testing best practices

Object types

• Entities - Identity(long lived Id) Customers Products

• Value Objects - Identity(Value) Money(currency + amount)

• Services - Identity(by default - reference)

Page 35: Unit testing best practices

Value Objects (Override Equals + GetHashCode)

Page 36: Unit testing best practices

Test-specific equality

• Comparer concrete IEqualityComparer

• Resemblance(for non-sealed classes)

• Likeness(SemanticComparison)

Page 37: Unit testing best practices

Comparer

Page 38: Unit testing best practices

Resemblance (partially comparison)

Order присваевает id продукту

Page 39: Unit testing best practices

Example: Resemblance

Page 40: Unit testing best practices

Likeness (convension based comparison)

Page 41: Unit testing best practices

Q&A