38
Unit-тестирование на энтузиазме Кожевников Дмитрий АКБ Росбанк [email protected] 8-я конференция .NET разработчиков 6 апреля 2014 dotnetconf.ru

Unit тестирование на энтузиазме

Embed Size (px)

DESCRIPTION

DotnetConf speach presentation. 2014 April 6. Chelyabinsk, Russia

Citation preview

Page 1: Unit тестирование на энтузиазме

Unit-тестирование на энтузиазме

Кожевников ДмитрийАКБ Росбанк

[email protected]

8-я конференция .NET разработчиков6 апреля 2014dotnetconf.ru

Page 2: Unit тестирование на энтузиазме

2Unit-тестирование на энтузиазме, Кожевников Дмитрий

Докладывает

• Кожевников Дмитрий Олегович • .Net разработчик• Инженер-программист, АКБ Росбанк• Интересы: паттерны и практики

разработки качественного кода, unit-тестирование и TDD, новые технологии в стеке .net, больше кода для бога кода

• Email [email protected]

Page 3: Unit тестирование на энтузиазме

3Unit-тестирование на энтузиазме, Кожевников Дмитрий

О чём я НЕ буду говорить

• Что такое unit-тесты и зачем?

• Как сделать код слабосвязным?

• Что за принципы SOLID?

• Как это - Inversion of Control?

• Программирование на основе интерфейсов?

Page 4: Unit тестирование на энтузиазме

4Unit-тестирование на энтузиазме, Кожевников Дмитрий

Перегруженные

unit-тесты

Большая инерция

кода

Тестируемость

вместо простоты

Page 5: Unit тестирование на энтузиазме

5Unit-тестирование на энтузиазме, Кожевников Дмитрий

Нарушение SRP

Много зависимостей в классах

Тяжелые алгорит

мы

Инициализация в конструк

торе

Page 6: Unit тестирование на энтузиазме

6Unit-тестирование на энтузиазме, Кожевников Дмитрий

… и, как следствие

Код

слабосвязный,

а тесты

монструозны

Page 7: Unit тестирование на энтузиазме

7Unit-тестирование на энтузиазме, Кожевников Дмитрий

Наши решения

ПРИНЦИПЫ

как Боб Мартин

ЗАПАХИ чем

пахнет наш код

Page 8: Unit тестирование на энтузиазме

8Unit-тестирование на энтузиазме, Кожевников Дмитрий

ПАТТЕРНЫ

прикладное

велосипедостроение

МЕТРИКИкак будто и так

не видно

Page 9: Unit тестирование на энтузиазме

9Unit-тестирование на энтузиазме, Кожевников Дмитрий

Принципы

Page 10: Unit тестирование на энтузиазме

10Unit-тестирование на энтузиазме, Кожевников Дмитрий

Page 11: Unit тестирование на энтузиазме

11Unit-тестирование на энтузиазме, Кожевников Дмитрий

Паттерны

Список команд

Шаг за шагом

Нормальная

декомпо-зиция

Отделение инициа-лизации

Контекст для

вызовов

Page 12: Unit тестирование на энтузиазме

12Unit-тестирование на энтузиазме, Кожевников Дмитрий

Page 13: Unit тестирование на энтузиазме

13Unit-тестирование на энтузиазме, Кожевников Дмитрий

Нормальная декомпозиция

NormalDecompositionPerformLogic();

IDependency1

MidResult1 SubAction();

IDependency2MidResult2 SubAction(MidResult1 r);

IDependency3MidResult3 SubAction(MidResult2 r);

Page 14: Unit тестирование на энтузиазме

14Unit-тестирование на энтузиазме, Кожевников Дмитрий

Page 15: Unit тестирование на энтузиазме

15Unit-тестирование на энтузиазме, Кожевников Дмитрий

Нормальная декомпозиция

+ -

Page 16: Unit тестирование на энтузиазме

16Unit-тестирование на энтузиазме, Кожевников Дмитрий

Шаг за шагом

StepsDirector

PerformLogic();

StepByStep

MidResult1 Step1();MidResult2 Step2(MidResult1 r);MidResult3 Step3(MidResult2 r);

StepByStep_Tests

Step1_Test();Step2_Test();Step3_Test();

Page 17: Unit тестирование на энтузиазме

17Unit-тестирование на энтузиазме, Кожевников Дмитрий

Page 18: Unit тестирование на энтузиазме

18Unit-тестирование на энтузиазме, Кожевников Дмитрий

Page 19: Unit тестирование на энтузиазме

19Unit-тестирование на энтузиазме, Кожевников Дмитрий

Шаг за шагом

+ -Сложно выделить шаги

Страдает инкапсуляция

Промежуточные данные

Сохранение логики внутри класса

Мало новых зависимостей

Можно выделить много шагов

Page 20: Unit тестирование на энтузиазме

20Unit-тестирование на энтузиазме, Кожевников Дмитрий

Список команд

PerformLogic();

CommandsDirector ICommand

Execute(MidData data);int SortOrder { get; }

Command1

Execute(MidData data);int SortOrder { get; }

Command2

Execute(MidData data);int SortOrder { get; }

Page 21: Unit тестирование на энтузиазме

21Unit-тестирование на энтузиазме, Кожевников Дмитрий

Page 22: Unit тестирование на энтузиазме

22Unit-тестирование на энтузиазме, Кожевников Дмитрий

Список команд

+ -

Page 23: Unit тестирование на энтузиазме

23Unit-тестирование на энтузиазме, Кожевников Дмитрий

Много шагов

Нужна гибкость

Шаги независимы

Логика в одном классе Нормальная

декомпозицияШаг за шагомСписок команд

Выделить более крупные

шаги-+

-+

+-

+-

Page 24: Unit тестирование на энтузиазме

24Unit-тестирование на энтузиазме, Кожевников Дмитрий

Отделение инициализации

InitializedObject

MidResult3 { get; set; }Ctor(MidResult3 r, IDependency3 service);Initialize();Action();

InitializedObject_TestsCtor_Test();Initialize_Test();Action_Test();

Page 25: Unit тестирование на энтузиазме

25Unit-тестирование на энтузиазме, Кожевников Дмитрий

Page 26: Unit тестирование на энтузиазме

26Unit-тестирование на энтузиазме, Кожевников Дмитрий

Page 27: Unit тестирование на энтузиазме

27Unit-тестирование на энтузиазме, Кожевников Дмитрий

Отделение инициализации

+ -Ограничение инкапсуляции

состояния класса

Дополнительный вызов метода

инициализации

Разгрузка тестов от поддержки логики

конструктора

Разгрузка конструктора от части

зависимостей

Page 28: Unit тестирование на энтузиазме

28Unit-тестирование на энтузиазме, Кожевников Дмитрий

Контекст вызовов

Actor

Action1(IDependency1 d);Action2(IDependency2 d);Action3(IDependency3 d);

IDependency2

IDependency1

IDependency3

Facade

Action1();Action2();Action3();

WorkContext

Act<T>(Action<T> act);TR Get<T,TR>(Func<T,TR>

f);

ILocator

T Resolve<T>();

Page 29: Unit тестирование на энтузиазме

29Unit-тестирование на энтузиазме, Кожевников Дмитрий

Page 30: Unit тестирование на энтузиазме

30Unit-тестирование на энтузиазме, Кожевников Дмитрий

Page 31: Unit тестирование на энтузиазме

31Unit-тестирование на энтузиазме, Кожевников Дмитрий

+ -Таки вариант ServiceLocator

Чудной интерфейс

Разгрузка конструктора от

контекстных зависимостей

Контекст для логики (DCI?)

Контекст вызовов

Page 32: Unit тестирование на энтузиазме

32Unit-тестирование на энтузиазме, Кожевников Дмитрий

Много заглушек и глубокая

настройка в Arrange

Дублирование кода в

Arrange

Вспомогательные

методы в фикстурах

Защищённые

конструкторы только для тестов

Тестовые реализации вместо

моков

Зависимости только

для конструкто

ра

Page 33: Unit тестирование на энтузиазме

33Unit-тестирование на энтузиазме, Кожевников Дмитрий

Метрики по переменным:

Тестируемые объекты

Моки - классами в тестовой сборке

Моки\Стабы созданные

фреймворком изоляции

Переменные библиотечных типов

слож

ность

Page 34: Unit тестирование на энтузиазме

34Unit-тестирование на энтузиазме, Кожевников Дмитрий

Настройки выброса

исключенийНастройки сallback’ов

Настройки методов

Настройки свойств

Метрики по настройкам стабов/моков:

слож

ность

Page 35: Unit тестирование на энтузиазме

35Unit-тестирование на энтузиазме, Кожевников Дмитрий

ИтогиРазделение

ответственности - необходимость, а

не искусств

о

Код определ

яет качество

тестовСлабосвязный

дизайн !=

тестируемый

дизайн

Тестируемый

дизайн !=

простой дизайн

Page 36: Unit тестирование на энтузиазме

36Unit-тестирование на энтузиазме, Кожевников Дмитрий

ВопросыКаков порог

входа в практики

unit-тестиров

ания?

Как достигнуть баланса

между тестируемостью и простото

й?Оправдывают ли

unit-тесты

усложнение

дизайна?

Нужны ли

паттерны тестируе

мого кода?

Page 37: Unit тестирование на энтузиазме

37Unit-тестирование на энтузиазме, Кожевников Дмитрий

Ссылки

• Антипаттерны TDD http://habrahabr.ru/post/43761/• Те же посылки, но совсем другие решения, цикл

статей, Юрий Солдатенков http://solyutor.blogspot.ru/2012/03/ock.html

• Тестируемый дизайн vs хороший дизайн, Сергей Тепляков http://sergeyteplyakov.blogspot.ru/2013/04/vs.html

• Проект MockMetrics, R# плагин подсчёта метрик unit тестов https://github.com/KozhevnikovDmitry/MockMetrics/tree/trunk

Page 38: Unit тестирование на энтузиазме

38Unit-тестирование на энтузиазме, Кожевников Дмитрий

Спасибо за внимание

Кожевников ДмитрийАКБ Росбанк

[email protected]