Модульное тестирование с помощью visual studio 2012 ms test, nunit,...

32
Практическое занятие Модульное Тестирование, Покрытие Кода и Анализ Клонов Кода с использованием Visual Studio 2012 Версия практического занятия: 11.0.60315.01 Обновление 2 Последнее обновление: 09.04.2013 г.

Upload: -

Post on 22-May-2015

4.715 views

Category:

Technology


4 download

TRANSCRIPT

Page 1: Модульное тестирование с помощью visual studio 2012 MS Test, Nunit, X-unit.net и Code Clone

Практическое занятие

Модульное Тестирование, Покрытие Кода и Анализ Клонов Кода с использованием Visual Studio 2012

Версия практического занятия: 11.0.60315.01 Обновление 2

Последнее обновление: 09.04.2013 г.

Page 2: Модульное тестирование с помощью visual studio 2012 MS Test, Nunit, X-unit.net и Code Clone

СОДЕРЖАНИЕ

ОБЩИЕ СВЕДЕНИЯ .................................................................................................................................. 3

УПРАЖНЕНИЕ 1: МОДУЛЬНОЕ ТЕСТИРОВАНИЕ ............................................................................. 4

УПРАЖНЕНИЕ 2: ПОКРЫТИЕ ИСХОДНОГО КОДА ............................................................................. 19

УПРАЖНЕНИЕ 3: АНАЛИЗ КЛОНОВ ИСХОДНОГО КОДА .............................................................. 25

Page 3: Модульное тестирование с помощью visual studio 2012 MS Test, Nunit, X-unit.net и Code Clone

Общие сведения

Выполнив задания этого упражнения, вы узнаете о принципиально новом подходе к модульному

тестированию в Visual Studio 2012. Ядро модульного тестирования в Visual Studio 2012 стало

расширяемым, оно поддерживает адаптеры тестирования от сторонних поставщиков, такие как

NUnit и xUnit.net. Вы также узнаете о том, как новые инструменты обнаружения клонов исходного

кода способствуют разработке высококачественного программного обеспечения, помогая найти

семантически сходные блоки кода для внесения общих исправлений или рефакторинга.

Необходимые условия

Для этого практического занятия вам понадобится виртуальная машина Visual Studio 2012,

предоставляемая компанией Microsoft. Для получения дополнительных сведений о получении и

использовании этой виртуальной машины выберите ссылку.

Информация о сценарии Fabrikam Fiber

В этой группе практических занятий для более удобного изучения сценариев упоминается

вымышленная компания Fabrikam Fiber, которая предоставляет доступ к кабельному телевидению

и оказывает сопутствующие услуги в США. С целью масштабирования своего веб-сайта для

клиентов она использует приложение Windows Azure, чтобы предоставить конечным

пользователям возможность самообслуживания и отслеживания доступности технических

специалистов. В компании используется также локальное приложение ASP.NET MVC для

повышения эффективности работы представителей отдела обслуживания клиентов. Приложение

позволяет управлять процессом выполнения заказов клиентов.

В рамках этой группы практических занятий вы примете участие в ряде сценариев, в которые

вовлечены разработчики и тестировщики компании Fabrikam Fiber. Рабочая группа из 8–10

специалистов решила использовать инструменты управления жизненным циклом приложений

Visual Studio для управления исходным кодом, запуска сборок, проверки веб-сайтов, а также

планирования и мониторинга процесса реализации проекта.

Обновления

Для Обновления 1 были внесены следующие обновления:

Добавлены шаги для упражнения Модульное Тестирование, которые показывают

использование характеристик

Добавлено упражнение Анализ покрытия исходного кода

Для Обновления 2 были внесены следующие обновления:

Добавлены шаги для упражнения Модульное Тестирование, которые показывают новую

опцию группировки и тестовых списков

Page 4: Модульное тестирование с помощью visual studio 2012 MS Test, Nunit, X-unit.net и Code Clone

Упражнения

Это практическое занятие включает следующие упражнения:

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

2. Анализ покрытия исходного кода.

3. Анализ клонирования кода.

Примерная продолжительность практического занятия: 30 минут.

Упражнение 1: Модульное

тестирование

В этом упражнении вы познакомитесь с некоторыми усовершенствованиями, внесенными в

процесс модульного тестирования в Visual Studio 2012 и направленными на повышение

эффективности и расширяемости.

1. Войдите в систему с логином Julia. Для всех учетных записей используется пароль

P2ssw0rd.

2. Запустите Visual Studio 11 с помощью ярлыка на панели задач или через меню Start |

All Programs | Microsoft Visual Studio 2012.

Рисунок 1

Запуск Visual Studio 2012

3. Запустите решение FabrikamFiber.CallCenter из ветви Dev в окне Source Control

Explorer.

Page 5: Модульное тестирование с помощью visual studio 2012 MS Test, Nunit, X-unit.net и Code Clone

Рисунок 2

Окно Source Control Explorer

4. Откройте окно Test Explorer через меню Test | Windows | Test Explorer. Заметьте, что

поиск тестов изначально установлен в состояние Not Run.

Рисунок 3

Окно Test Explorer

5. Выберите ссылку Run All для запуска всех обнаруженных модульных тестов. Среди них

также существует закодированный тест интерфейса пользователя, поэтому не используйте

клавиатуру и мышку пока тесты не закончатся.

Page 6: Модульное тестирование с помощью visual studio 2012 MS Test, Nunit, X-unit.net и Code Clone

Рисунок 4

Выполнение всех модульных тестов

Примечание. Visual Studio 2012 также предоставляет инструмент Continuous Test Runner,

который можно активировать через меню Test | Test Settings | Run Tests After Build. Если

эта опция включена, тесты будут выполняться после сборки приложений в случае

необходимости.

6. Откройте группу Passed Tests и дважды щелкните тест с названием

CreateInsertsCustomerAndSaves, чтобы открыть исходный код.

Рисунок 5

Переход к методу тестирования, который использует MSTest

7. В открывшемся файле CustomersControllerTest.cs обратите внимание на то, что метод

тестирования использует ожидаемый атрибут TestMethod. Этот атрибут используется

инструментом MSTest для маркировки модульных тестов.

Page 7: Модульное тестирование с помощью visual studio 2012 MS Test, Nunit, X-unit.net и Code Clone

Рисунок 6

Исходный код модульного теста MSTest

8. В поле Search в верхней части окна Test Explorer введите слово index и обратите

внимание на доступные фильтры поиска.

Рисунок 7

Выполнение поиска в окне Test Explorer

9. Нажмите клавишу Enter (Ввод), чтобы выполнить поиск.

10. В списке результатов поиска двойным щелчком откройте единственный тест под

названием IndexReturnsNonNullView, чтобы просмотреть исходный код.

Рисунок 8

Переход к методу тестирования, который использует XUnit

11. В открывшемся файле HomeControllerTest.cs вы увидите, что тест

IndexReturnsNonNullView действительно использует платформу тестирования XUnit.

Page 8: Модульное тестирование с помощью visual studio 2012 MS Test, Nunit, X-unit.net и Code Clone

Адаптер XUnit для Visual Studio 2012 может быть доступен на сайте галереи Visual Studio

at http://aka.ms/UnitTestAdapters.

Рисунок 9

Пример теста XUnit в Visual Studio 2012

12. Нажмите Х для очистки поиска в окне Test Explorer.

Рисунок 10

Расположение кнопки Х

13. Обратите внимание, что результаты распределены на группы по успешности

выполнения с отображением времени, затраченного на выполнение теста.

Page 9: Модульное тестирование с помощью visual studio 2012 MS Test, Nunit, X-unit.net и Code Clone

Рисунок 11

Результаты выполнения теста

14. В Visual Studio 2012 улучшилась производительность средств выполнения тестов.

Обратите внимание на затраченное время, затем щелкните ссылку Run… и затем

Repeat Last Run, чтобы оценить разницу.

Рисунок 12

Повтор последнего тестового запуска

Page 10: Модульное тестирование с помощью visual studio 2012 MS Test, Nunit, X-unit.net и Code Clone

Примечание. Затраченное время, которое вы видите, может отличаться от показанного

на снимках экрана. При первом запуске модульные тесты будут выполняться медленнее,

чем в дальнейшем, поскольку тесты и ядро тестирования загружаются в первый раз.

Рисунок 13

Второй тестовый запуск выполняется быстрее при отсутствии изменений в коде

15. Выберите неудачно пройденный тест в окне Test Explorer, чтобы просмотреть

результаты тестирования.

Рисунок 14

Выбор неудачно пройденного теста

Page 11: Модульное тестирование с помощью visual studio 2012 MS Test, Nunit, X-unit.net и Code Clone

Примечание. Вы также можете щелкнуть правой кнопкой результаты тестирования и

выбрать команду Copy, чтобы скопировать подробную информацию в буфер обмена. Эта

функция будет полезна, например, при отправке электронной почты.

16. В окне со сводной информацией о неудачном тесте отображается сообщение о

возникновении исключения ArgumentNullException. Система предоставит вам

трассировку стека на момент появления исключения. Обратите внимание, что мы

можем перейти по ссылкам непосредственно к исходному коду для тестирования или к

точкам трассировки стека. Щелкните ссылку source link, чтобы просмотреть исходный

код метода теста.

Рисунок 15

Переход к исходному коду метода теста

Рисунок 16

Начальное представление после перехода к исходному коду метода теста

Page 12: Модульное тестирование с помощью visual studio 2012 MS Test, Nunit, X-unit.net и Code Clone

17. Найдите закомментированную строку кода и раскомментируйте ее. Предположим, что

это и есть причина неудачного теста.

Рисунок 17

Устранение причины неудачного теста

18. Нажмите клавиши CTRL + S, чтобы сохранить изменения.

19. Щелкните правой кнопкой неудачный тест в окне Test Explorer и выберите Run

Selected Tests, чтобы убедиться в том, что проблема устранена.

Рисунок 18

Выполнение неудачно пройденного теста

20. До сих пор мы видели, как управлять всеми обнаруженными тестами, искать

определенные тесты и группировать по результатам тестирования. Теперь давайте

используем несколько другие методы, с которыми Вы можете организовать и

просматривать модульные тесты, что делает модульное тестирование проще. Для

некоторого мотивационного контекста, вспомните сколько времени Вы должны были

ждать окончание закодированного теста интерфейса пользователя и затем предположите,

что есть еще много таких. Было бы хорошо, если бы тесты были организованы так, чтобы

Вы могли легко избежать запуска тестов без необходимость быть осторожными в выборе

тестов.

Page 13: Модульное тестирование с помощью visual studio 2012 MS Test, Nunit, X-unit.net и Code Clone

21. Начиная с Visual Studio 2012 Обновление 2, появилось много полезных вариантов

группировки. Щелкните правой кнопкой мыши где-нибудь в окне Обозревателя тестов и

выберите Group By | Class.

Рисунок 19

Группировка тестов по классам

22. Предположив, что тесты хорошо организованы в пределах описательных названий

классов, это может сделать намного легче выбор и управление тестами. Здесь Вы можете

выбрать все классы за исключением класса CodedUITest1, и затем управлять ими (или

наоборот, Вы можете выбрать все закодированные тесты интерфейса пользователя).

Рисунок 20

Группировка тестов по классам

23. Нажмите правой кнопкой мыши в окне Обозревателя Тестов и выберите Group By |

Project.

Page 14: Модульное тестирование с помощью visual studio 2012 MS Test, Nunit, X-unit.net и Code Clone

Рисунок 21

Группировка тестов по проекту

24. Группировка тестов по проекту, очевидно, будет полезна для проведения и управления

тестами на проектном уровне. Здесь Вы можете выбрать все проекты за исключением

FabrikamFiber.Web.UITests и затем запустить их (или наоброт, выбрать все закодировали

тесты интерфейса пользователя, которые находятся в проекте FabrikamFiber.Web.UITests).

Рисунок 22

Группировка тестов по проекту

25. В Visual Studio 2012 Обновление 1, можно использовать характеристики в коде теста для

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

закодированные тесты пользовательского интерфейса. Откройте CodedUITest1.cs из

проекта FabrikamFiber.Web.UITests.

Page 15: Модульное тестирование с помощью visual studio 2012 MS Test, Nunit, X-unit.net и Code Clone

Рисунок 23

Загрузка кода теста

26. Добавьте атрибут TestCategory к методу CodedUITestMethod1 с категорией “UI”.

Рисунок 24

Добавление пользовательской характеристики в тестовый метод

27. Перестройте решение, нажав Ctrl+Shift+B.

28. Нажмите правой кнопкой мыши в Test Explorer и выберите Group By | Traits.

Рисунок 25

Группировки по Характеристикам

29. С использованием характеристик для закодированных тестов ПИ теперь можно легко

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

Page 16: Модульное тестирование с помощью visual studio 2012 MS Test, Nunit, X-unit.net и Code Clone

Рисунок 26

Окно Test Explorer показывает тесты, сгруппированные по характеристикам

30. Начиная с Visual Studio 2012 Обновление 2, Вы можете создавать наборы тестов, которые

называются playlists. Это обеспечивает пользовательскую группировку без необходимости

модификации кода модульных тестов. Нажмите правой кнопкой мыши на тесте

CodedUITestMethod1 и выберите Add to Playlist | New Playlist.

Рисунок 27

Создание нового тестового списка

31. Введите «UI Tests» для имени тестового списка и затем нажмите Save.

Page 17: Модульное тестирование с помощью visual studio 2012 MS Test, Nunit, X-unit.net и Code Clone

Рисунок 28

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

32. Выберите выпадающий список Playlist и выберите список «UI Tests».

Рисунок 29

Группировки по Характеристикам

33. Только выбрав «UI Tests» вы будете видеть только определенные тесты в Обозревателе

Тестов, что позволяет намного легче сосредоточиться на особом наборе тестов.

Page 18: Модульное тестирование с помощью visual studio 2012 MS Test, Nunit, X-unit.net и Code Clone

Рисунок 30

Выбран список тестов

34. Тестовый список простой XML файл, который определяет какие индивидуальные тесты

включать. Например, так выглядит XML для «UI Tests» (загруженный в редактор Visual

Studio).

Рисунок 31

Содержимое списка тестирования

35. Список тестов может быть передан другим участникам команды через командный портал,

почту или даже версионный контроль по необходимости. Для загрузка файла списка

необходимо выбрать выпадающий список Playlist и затем нажать пункт Open Playlist File.

Нет необходимости делать этой в этом задании.

Рисунок 32

Открытие списка тестов

Page 19: Модульное тестирование с помощью visual studio 2012 MS Test, Nunit, X-unit.net и Code Clone

Упражнение 2: Покрытие Исходного

Кода В этом упражнении вы узнаете о изменения в функционале покрытия кода и другие

усовершенствования Visual Studio 2012, которые делают его проще в использовании и интеграции

в цикл разработки. Возможности покрытия кода доступны в Visual Studio Premium и Ultimate.

1. Вы должны уже иметь открытое окно Test Explorer из предыдущего упражнения, если нет,

то откройте его (из Test | Windows | Test Explorer).

2. Верните тестовый список по умолчанию, чтобы включить все тесты, выбрав выпадающий

список Playlist и затем выбрав пункт All Tests.

Рисунок 33

Выбор всех тестов

3. Для анализа покрытия кода для всех тестов, выберите раскрывающийся список Run и

выберите Analyze Code Coverage for All Tests. Это начнет процесс построения,

тестирования и сбора результатов покрытия кода.

Рисунок 34

Анализ покрытия кода

Page 20: Модульное тестирование с помощью visual studio 2012 MS Test, Nunit, X-unit.net и Code Clone

4. Теперь можно просмотреть результаты в окне Code Coverage Results и получить видение

статистику Покрыто/Не покрыто для всего решения. Обратите внимание, на скриншоте

ниже покрытие измеряется в блоках кода по умолчанию, где блок является код с одной

точкой входа и выхода.

Рисунок 35

Результаты покрытия кода

Примечание: Если вы хотите увидеть результаты с точки зрения линии кода, вы можете

сделать это, щелкнув правой кнопкой мыши в окне Code Coverage Results и выбрав

опцию the Add/Remove Columns.

5. Разверните корневой узел результата покрытия кода для просмотра покрытия в разбивке

по сборкам. По умолчанию мы видим все сборки, которые загружаются во время

выполнения теста и для которых доступен файл PDB.

Рисунок 36

Результаты покрытия кода по сборкам

Примечание: Вы можете настроить контроль, по которому сборки выбираются для

анализа покрытия кода, записав в файл .runsettings. Для получения дополнительной

информации смотрите статью MSDN Customizing Code Coverage Analysis.

6. Разверните узел Fabrikamfiber.web.dll для просмотра покрытия в разбивке по пространству

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

Page 21: Модульное тестирование с помощью visual studio 2012 MS Test, Nunit, X-unit.net и Code Clone

классов контроллера, для команды тестирования еще предстоит много работы для того,

чтобы обеспечить покрытие других пространства имен.

Рисунок 37

Результаты покрытия кода для пространств имен сборки

7. Разверните узел пространства имен FabrikamFiber.Web.Controllers для просмотра покрытия

с разбивкой по классам. Это покажет, что класс HomeController хорошо покрыт и что

EmployeesController в настоящее время нет покрыт.

Рисунок 38

Результаты покрытия кода для классов в пространстве имен

8. В конце пройдем вниз в узлы класса для просмотра покрытия до уровня методов,

развернув узел класса CustomersController.

Page 22: Модульное тестирование с помощью visual studio 2012 MS Test, Nunit, X-unit.net и Code Clone

Рисунок 39

Результаты покрытия кода для методов

9. Двойным щелчком выберите конструктор Create(FabrikamFiber.DAL.Models.Customer)

для перехода к исходному коду для визуализации покрытия блоков.

Рисунок 40

Переход к исходному коду

10. В окне редактора для SourceController.cs вы можете увидеть, что код подчеркнутый

голубым цветом представляет собой блок, который покрыт тестами, тогда как красным

цветом представлен блок, который не был покрыт.

Рисунок 41

Page 23: Модульное тестирование с помощью visual studio 2012 MS Test, Nunit, X-unit.net и Code Clone

Представление исходного кода, который показывает цветовое покрытие кода

11. Также можно получить покрытие кода для конкретного набора тестов. В окне Test Explorer

выберите тестовый метод CreatInsersCustomerAndSaves, щелкните правой кнопкой мыши

и затем выберите Analyze Code Coverage for Selected Tests.

Рисунок 42

Анализ покрытия кода для выбранных тестов

12. По завершении выполнения теста для выбранного теста разверните узел покрытия кода и

обратите внимание, что только сборки, загруженные во время выполнения теста,

отображаются со статистическими данными.

Рисунок 43

Результаты покрытия кода

13. Также легко переходить между результатами покрытия кода, используя раскрывающийся

список в окне Code Coverage Results. Пойдите вперед и выберите первый файл результатов

покрытия кода.

Page 24: Модульное тестирование с помощью visual studio 2012 MS Test, Nunit, X-unit.net и Code Clone

Рисунок 44

Выбор результатов покрытия кода

14. Скажем, что мы хотим использовать эти результаты покрытия кода в отчете или просто

поделиться ими с кем-то. Чтобы сделать это, нажмите на кнопку Export Results.

Рисунок 45

Экспорт результатов покрытия кода

15. В диалоговом окне Save можно сохранить данные о покрытии кода в XML-файл и затем

использовать его по своему усмотрению. Для этого практического занятия откройте и

просто отмените операцию из диалогового окна и перейдите к следующему упражнению.

Page 25: Модульное тестирование с помощью visual studio 2012 MS Test, Nunit, X-unit.net и Code Clone

Рисунок 46

Сохранение результатов покрытия кода

Упражнение 3: Анализ клонов

исходного кода

В этом упражнении вы познакомитесь с новой функцией Code Clone в Visual Studio 2012. Этот

инструмент ищет семантически сходные блоки кода, используя эвристический анализ, а не просто

поиск точных совпадений.

1. Выберите пункт Analyze | Analyze Solution for Code Clones в главном меню Visual

Studio.

Page 26: Модульное тестирование с помощью visual studio 2012 MS Test, Nunit, X-unit.net и Code Clone

Рисунок 47

Анализ клонов в исходном коде решения

2. По завершении анализа в окне Code Clone Analysis Results отображаются кандидаты на

клоны, сгруппированные по степени совпадения. Откройте группу Strong Match, чтобы

открыть два файла, в которых присутствуют практически аналогичные блоки.

Рисунок 48

Просмотр близких совпадений в файлах

3. В каждой строке показан класс и метод, определенный файл и строки, которые были

определены как близкие совпадения. Если вы наведете указатель мыши на любое

совпадение, фрагмент кода даст вам представление о сходных блоках кода.

Рисунок 49

Page 27: Модульное тестирование с помощью visual studio 2012 MS Test, Nunit, X-unit.net и Code Clone

Наведение указателя мыши на результаты, чтобы получить более подробную

информацию

4. Дважды щелкните каждое совпадение, чтобы открыть их в редакторе кода, затем

щелкните правой кнопкой заголовок одной из вкладок и выберите пункт New

Horizontal Tab Group в контекстном меню.

Рисунок 50

Открытие обоих файлов для сравнения

5. Пролистайте код и найдите метод AssignSchedule в обоих файлах. Обратите внимание,

что блоки кода практически полностью совпадают, за исключением последней строки,

в которой вызывается метод RedirectToAction. Это означает, что данный метод

является подходящим для рефакторинга. Такой всеобъемлющий поиск особенно

полезен в процессе обнаружения кода, который подходит для рефакторинга с целью

упрощения обслуживания в будущем.

Page 28: Модульное тестирование с помощью visual studio 2012 MS Test, Nunit, X-unit.net и Code Clone

Рисунок 51

Сравнение близких совпадений в результатах анализа кода клонов

6. Выберите пункт Window | Close All Documents в главном меню, чтобы освободить

пространство на экране.

7. Вы также можете сузить область поиска клонов исходного кода, если это необходимо.

В окне Solution Explorer перейдите в папку Controllers проекта FabrikamFiber.Web и

откройте файл CustomersController.cs в редакторе кода.

Page 29: Модульное тестирование с помощью visual studio 2012 MS Test, Nunit, X-unit.net и Code Clone

Рисунок 52

Открытие файла CustomersController.cs

8. Прокрутите страницу вниз и найдите метод Create, который использует параметр

Customer. Выделите три строки, начиная с оператора if.

Рисунок 53

Выбор кода для обнаружения клонов

9. Щелкните правой кнопкой выбранный блок кода и выберите пункт Find Matching

Clones in Solution в контекстном меню.

Page 30: Модульное тестирование с помощью visual studio 2012 MS Test, Nunit, X-unit.net и Code Clone

Рисунок 54

Поиск близких совпадений для выбранного блока кода

10. После выполнения поиска в окне Code Clone Search Results отображаются фрагменты

кода с различной степенью совпадения.

Рисунок 55

Обнаруженные клоны кода

11. Разверните все группы клонов и просмотрите обнаруженные совпадения, в том числе в

исходной группе клонов. Если увеличить размер окна Code Clone Search Results, вы

сможете увидеть сразу все совпадения.

Page 31: Модульное тестирование с помощью visual studio 2012 MS Test, Nunit, X-unit.net и Code Clone

Рисунок 56

Развернутые группы обнаруженных клонов кода

12. Наведите курсор мыши на оригинальный фрагмент кода, чтобы напомнить, для какого

блока мы ищем клоны.

Рисунок 57

Оригинальный фрагмент кода

13. Наведите курсор на результат Exact Match и обратите внимание, что метод Edit

использует тот же код, что и метод Create.

14. Наведите курсор на результат Strong Match и обратите внимание, что разница

заключается только в строке с вызовом метода Delete

Рисунок 58

Фрагмент кода, представляющий собой близкое совпадение с оригиналом

Page 32: Модульное тестирование с помощью visual studio 2012 MS Test, Nunit, X-unit.net и Code Clone

15. Наведите курсор на результат Medium Match и обратите внимание, что фрагмент

похож на оригинал, но мы работаем с совершенно другим объектом

(employeeRepository).

Рисунок 59

Фрагмент кода, представляющий собой близкое совпадение с оригиналом

16. Таким образом, существует три основных сценария, когда обнаружение клонов кода

может быть полезно для разработчиков:

a. Выявление подходящих блоков для рефакторинга.

b. Обновление сходных блоков кода в процессе исправления ошибок или

оптимизации.

c. Обучение новых разработчиков, которые присоединяются к проекту рабочей

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

о клиенте и хочет увидеть методы, используемые в остальной части программы

(например, блок Try... Catch).

Свои отзывы и предложения вы можете отправить по электронной

почте: [email protected]

© 2013 г. Корпорация Microsoft. Все права защищены.