Тестируем код с Visual Studio 2012 - XP Days Ukraine 2012

Preview:

DESCRIPTION

 

Citation preview

Тестируем код с Visual Studio 2012

@dmytromindra

@dmytromindra

Содержит откровенный код и сцены модульного тестирования.

@dmytromindra

Test Driven Development

Эффективное модульное тестирование – одна из

важнейших составляющих высококачественного кода.

Тестировать легаси код сложно, а в некоторых случаях невозможно.

Архитектура

Visual Studio Unit Test Explorer

Command Line Runner

TeamBuild Unit Test Activity

Visual Studio Unit Test Platform

MS-Test Managed

MS-Test Native NUnit xUnit.net QUnit MORE!

Approval Tests

http://approvaltests.sourceforge.net/

@dmytromindra

Легаси код

@dmytromindra

void FileExistsTest() { File.Write("foo.txt", ""); var result = IsFileEmpty("foo.txt") Assert.IsTrue(result); }

bool IsFileEmpty(string file) { var content = File.ReadAllText(file); return content.Length == 0; }

А это хороший тест ?

Это хороший код?

Что такое плохо

@dmytromindra

Код, не поддающийся тестированию.

Где он водится?

«Лишь бы работало» – Бизнес логика в code-behind – Слишком много зависимостей – Работа с БД перемешана с бизнес логикой. – Свой вариант ... ;)

Там, где тестируемость не предусмотрена Там, где тестируемость намеренно исключена Монолитная архитектура

@dmytromindra

Код, не поддающийся тестированию.

Как его узнать?

– Сложные процедуры “setup” и “teardown”

– Зависимость от состояния среды – Публичные статические методы – Скрытое создание объектов. – Использование замысловатых фреймворков. – Полное отсутствие тестов!

@dmytromindra

Любая система, где тестирование требует сложной предварительной

подготовки или где тесты работают

медленно, считается не тестируемой.

@dmytromindra

Зависимость от среды • Пусть имеется следующий код:

public void ThrowIfEndOfTheWorld() { if (DateTime.Now == new DateTime(2012,12,21)) throw new EndOfTheWorldException(); }

Как протестировать его надежность ?

@dmytromindra

[DllImport("kernel32.dll")] extern static bool SetSystemTime(ref SystemTime time); [TestMethod] public void Y2KTest() { SetSystemTime(2012,12,21,0,0,0); Assert.Throws( () => ThrowIfEndOfTheWorld() ); }

• Может как-нибудть так?

Зависимость от среды

@dmytromindra

Разделяй и властвуй

Есть два пути: • Тестируемая архитектура

– Уровни абстракции, интерфейсы, инъекция зависимости

• Не тестируемая архитектура – Отсутствие уровней абстракции, обилие

публичных статических методов, запечатанные типы, и т.д.

Изолируй

@dmytromindra

Модульное тестирование

• Стабы(Stubs) и Моки(Mocks) – Простые в использовании, конкретные

реализации для тестирования – Очень похожи, но представляют собой

разные подходы http://martinfowler.com/articles/mocksArentStubs.html

VISUAL STUDIO 2012 STUBS

@dmytromindra

Visual Studio 2012 Stubs

Генерируются на этапе компиляции (быстрые)

Используют возможности языка C# (без дополнительных API)

Совместимы по типу (is-a) с интерфейсом

VISUAL STUDIO 2012 SHIMS

@dmytromindra

Visual Studio 2012 Shims

Во время выполнения перехватывают вызовы любых .NET методов

Используют профайлер для перенаправления вызовов

“Monkey patching” для .NET

@dmytromindra

Используйте Shims, если …

Вы работаете с внешними компонентами, которые нельзя изменить

Вы работаете с легаси кодом, обладающим нетестируемой архитектурой

@dmytromindra

ShimsContext

Не используйте общий контекст. Создавайте контекст в каждом тесте отдельно.

@dmytromindra

Почему стоит побысрее избавиться от Shims?

Они медленные!

Они полагаются на знание внутреннего устройства вашей системы!

Эффективное модульное тестирование – одна из

важнейших составляющих высококачественного кода.

Тестировать легаси код сложно, но возможно.

Помните! Использование тестов может улучшить архитектуру

@dmytromindra

Спасибо !

Recommended