unit testing best practices
DESCRIPTION
.NET IT Share - Unit testing best practicesTRANSCRIPT
![Page 1: Unit testing best practices](https://reader035.vdocuments.site/reader035/viewer/2022070319/557f6734d8b42af1298b49d6/html5/thumbnails/1.jpg)
Unit testing best practices
Oleksandr Masalov
![Page 2: Unit testing best practices](https://reader035.vdocuments.site/reader035/viewer/2022070319/557f6734d8b42af1298b49d6/html5/thumbnails/2.jpg)
• зачем нужны юниттесты?• unit of coverage/work• требования к юниттестам и как
не нужно писать тесты• повторное использование
кода(initialization, asserts)
Agenda
![Page 3: Unit testing best practices](https://reader035.vdocuments.site/reader035/viewer/2022070319/557f6734d8b42af1298b49d6/html5/thumbnails/3.jpg)
Зачем нужны юниттесты?
поиск багов? (интеграционные тесты)регрессионное тестирование?
(интеграционные тесты)улучшение качества кода(дизайна
компонентов)поиск багов в случае рефакторинга!
(изменение поведения компонента)источник спецификации системы
![Page 4: Unit testing best practices](https://reader035.vdocuments.site/reader035/viewer/2022070319/557f6734d8b42af1298b49d6/html5/thumbnails/4.jpg)
Unit of coverage/work
![Page 5: Unit testing best practices](https://reader035.vdocuments.site/reader035/viewer/2022070319/557f6734d8b42af1298b49d6/html5/thumbnails/5.jpg)
Return value/exception
![Page 6: Unit testing best practices](https://reader035.vdocuments.site/reader035/viewer/2022070319/557f6734d8b42af1298b49d6/html5/thumbnails/6.jpg)
Example: Return value/exception
![Page 7: Unit testing best practices](https://reader035.vdocuments.site/reader035/viewer/2022070319/557f6734d8b42af1298b49d6/html5/thumbnails/7.jpg)
State change
![Page 8: Unit testing best practices](https://reader035.vdocuments.site/reader035/viewer/2022070319/557f6734d8b42af1298b49d6/html5/thumbnails/8.jpg)
Example: State change
![Page 9: Unit testing best practices](https://reader035.vdocuments.site/reader035/viewer/2022070319/557f6734d8b42af1298b49d6/html5/thumbnails/9.jpg)
3rd party call
![Page 10: Unit testing best practices](https://reader035.vdocuments.site/reader035/viewer/2022070319/557f6734d8b42af1298b49d6/html5/thumbnails/10.jpg)
Example: 3rd party call
![Page 11: Unit testing best practices](https://reader035.vdocuments.site/reader035/viewer/2022070319/557f6734d8b42af1298b49d6/html5/thumbnails/11.jpg)
Требования к юниттестам
![Page 12: Unit testing best practices](https://reader035.vdocuments.site/reader035/viewer/2022070319/557f6734d8b42af1298b49d6/html5/thumbnails/12.jpg)
Надежные (Trustworthy)
• должны легко запускаться
• failed test == поведение модуля изменилось
• тесты независимы друг от друга
![Page 13: Unit testing best practices](https://reader035.vdocuments.site/reader035/viewer/2022070319/557f6734d8b42af1298b49d6/html5/thumbnails/13.jpg)
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](https://reader035.vdocuments.site/reader035/viewer/2022070319/557f6734d8b42af1298b49d6/html5/thumbnails/14.jpg)
Структура
![Page 15: Unit testing best practices](https://reader035.vdocuments.site/reader035/viewer/2022070319/557f6734d8b42af1298b49d6/html5/thumbnails/15.jpg)
Именование тест методов
Pattern:
UnitOfWork_Input_ExpectedOutputUnitOfWork_LogicalAction_ExpectedChangeInBehaviorUnitOfWork_ActionOrInput_ExpectedCallToThirdParty
Examples:
Addition_PositiveNumbers_ReturnsSum()Addition_WhenCalled_ResetsTheNextSum()Addition_NegativeNumbers_CallsLogger()
![Page 16: Unit testing best practices](https://reader035.vdocuments.site/reader035/viewer/2022070319/557f6734d8b42af1298b49d6/html5/thumbnails/16.jpg)
Именование тест методов - 2
![Page 17: Unit testing best practices](https://reader035.vdocuments.site/reader035/viewer/2022070319/557f6734d8b42af1298b49d6/html5/thumbnails/17.jpg)
Поддерживаемые (Maintainable)
• Тестируйте только public интерфейс
• Не используйте объекты, которые непостоянны(DateTime.Now, Thread, Random etc)
• Не дублируйте продакшин логику
• Не тестируйте всё в одном тесте
• Многократно используйте код для тестов(initialize, assert etc)
![Page 18: Unit testing best practices](https://reader035.vdocuments.site/reader035/viewer/2022070319/557f6734d8b42af1298b49d6/html5/thumbnails/18.jpg)
Не используйте объекты, которые непостоянны
DateTime.Now, Thread, Random etc
![Page 19: Unit testing best practices](https://reader035.vdocuments.site/reader035/viewer/2022070319/557f6734d8b42af1298b49d6/html5/thumbnails/19.jpg)
Не дублируйте продакшин логику
![Page 20: Unit testing best practices](https://reader035.vdocuments.site/reader035/viewer/2022070319/557f6734d8b42af1298b49d6/html5/thumbnails/20.jpg)
Не тестируйте всё в одном тесте
• сложно именовать
• тест не отображает полной картины
![Page 21: Unit testing best practices](https://reader035.vdocuments.site/reader035/viewer/2022070319/557f6734d8b42af1298b49d6/html5/thumbnails/21.jpg)
Структурируйте тесты!
• Arrange, Act, Assert
• Four-Phase Test
• Given/When/Then
![Page 22: Unit testing best practices](https://reader035.vdocuments.site/reader035/viewer/2022070319/557f6734d8b42af1298b49d6/html5/thumbnails/22.jpg)
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](https://reader035.vdocuments.site/reader035/viewer/2022070319/557f6734d8b42af1298b49d6/html5/thumbnails/23.jpg)
Four-Phase Test
![Page 24: Unit testing best practices](https://reader035.vdocuments.site/reader035/viewer/2022070319/557f6734d8b42af1298b49d6/html5/thumbnails/24.jpg)
Given/When/Then
![Page 25: Unit testing best practices](https://reader035.vdocuments.site/reader035/viewer/2022070319/557f6734d8b42af1298b49d6/html5/thumbnails/25.jpg)
Code reuse - Initialization problem
![Page 26: Unit testing best practices](https://reader035.vdocuments.site/reader035/viewer/2022070319/557f6734d8b42af1298b49d6/html5/thumbnails/26.jpg)
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](https://reader035.vdocuments.site/reader035/viewer/2022070319/557f6734d8b42af1298b49d6/html5/thumbnails/27.jpg)
Object Mother Pattern
var basket = CreateWithDiscount();
var basket = CreateWithSmallDiscount();
var basket = CreateWithLargeDiscount();
var basket = CreateWithLargeDiscountButWithSpecialOffer();
…
![Page 28: Unit testing best practices](https://reader035.vdocuments.site/reader035/viewer/2022070319/557f6734d8b42af1298b49d6/html5/thumbnails/28.jpg)
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](https://reader035.vdocuments.site/reader035/viewer/2022070319/557f6734d8b42af1298b49d6/html5/thumbnails/29.jpg)
Example: Test Data Builder
![Page 30: Unit testing best practices](https://reader035.vdocuments.site/reader035/viewer/2022070319/557f6734d8b42af1298b49d6/html5/thumbnails/30.jpg)
SUT Mother
![Page 31: Unit testing best practices](https://reader035.vdocuments.site/reader035/viewer/2022070319/557f6734d8b42af1298b49d6/html5/thumbnails/31.jpg)
SUT Builder
![Page 32: Unit testing best practices](https://reader035.vdocuments.site/reader035/viewer/2022070319/557f6734d8b42af1298b49d6/html5/thumbnails/32.jpg)
Auto-Mocking container pattern
![Page 33: Unit testing best practices](https://reader035.vdocuments.site/reader035/viewer/2022070319/557f6734d8b42af1298b49d6/html5/thumbnails/33.jpg)
Code reuse - Asserts problem
![Page 34: Unit testing best practices](https://reader035.vdocuments.site/reader035/viewer/2022070319/557f6734d8b42af1298b49d6/html5/thumbnails/34.jpg)
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](https://reader035.vdocuments.site/reader035/viewer/2022070319/557f6734d8b42af1298b49d6/html5/thumbnails/35.jpg)
Value Objects (Override Equals + GetHashCode)
![Page 36: Unit testing best practices](https://reader035.vdocuments.site/reader035/viewer/2022070319/557f6734d8b42af1298b49d6/html5/thumbnails/36.jpg)
Test-specific equality
• Comparer concrete IEqualityComparer
• Resemblance(for non-sealed classes)
• Likeness(SemanticComparison)
![Page 37: Unit testing best practices](https://reader035.vdocuments.site/reader035/viewer/2022070319/557f6734d8b42af1298b49d6/html5/thumbnails/37.jpg)
Comparer
![Page 38: Unit testing best practices](https://reader035.vdocuments.site/reader035/viewer/2022070319/557f6734d8b42af1298b49d6/html5/thumbnails/38.jpg)
Resemblance (partially comparison)
Order присваевает id продукту
![Page 39: Unit testing best practices](https://reader035.vdocuments.site/reader035/viewer/2022070319/557f6734d8b42af1298b49d6/html5/thumbnails/39.jpg)
Example: Resemblance
![Page 40: Unit testing best practices](https://reader035.vdocuments.site/reader035/viewer/2022070319/557f6734d8b42af1298b49d6/html5/thumbnails/40.jpg)
Likeness (convension based comparison)
![Page 41: Unit testing best practices](https://reader035.vdocuments.site/reader035/viewer/2022070319/557f6734d8b42af1298b49d6/html5/thumbnails/41.jpg)
Q&A