SlideShare a Scribd company logo
TDD в кровавом
энтерпрайзе
История одного моста
2
Сначала вопрос
Как можно тестировать? Результат – только видимые извне итоги
работы системы, не обладая знаниями о
реализации.
Поведение – система имеет зависимости,
взаимодействие с которыми можно
отследить и протестировать.
Контракты, интерфейсы, поверхность –
аналогично результату.
3
Немного теории
тестирования
4
Когда тестировать
В ОБЩЕМ СЛУЧАЕ
Высокая стоимость ошибки
Поведение не очевидно
Требуется подтверждение результата
работы
АВТОМАТИЗИРУЯ
Высокая частота релизов
Контракты стабилизированы
CI
5
Виды тестирования
6
7
https://github.com/polarnik/TypesOfTesting
8
9
https://github.com/polarnik/TypesOfTesting
Основные артефакты
Тест план
◦ Назначение данного плана
◦ Что тестируется (система, модуль, билд, …)
◦ Описание рисков
◦ Тестируемые фичи
◦ Не тестируемые фичи
◦ Стратегия тестирования
◦ Критерии успешного и не успешного завершения тестирования
◦ Описание окружения
◦ …
10
IEEE 829
Зачем нужен план?
◦ Определяет цель тестирования
◦ Описывает стратегию и необходимый объём работ по тестированию
◦ Определяет объект тестирования
◦ Позволяет определить покрытие функциональных требований
◦ Ограничивает скоуп тестирования
◦ Описывает исходы тестирования и условия успешного прохождения тестирования
11
Тест кейс
• Название
• Тестируемые фичи
• Определение входных данных
• Определение результата выполнения
• Серьёзность и приоритет бага
• ...
12
Баги
СЕРЬЁЗНОСТЬ
Блокирующий
Критический
Значительный
Незначительный
Тривиальный
ПРИОРИТЕТ
Высокий
Средний
Низкий
13
Практика
11 СЛАЙДОВ БЕЗ СТРОЧКИ КОДА – ГДЕ ЖЕ ТУТ TEST DRIVEN?
14
Проблема
Когда закончить писать код?
Test-driven development требует определить критерий полноты выполнения требования до того, как
приступать к реализации.
15
Определим Объект тестирования
Web API, принимающий на вход дату и возвращающий интервал времени,
прошедший (или предшествующий) этой дате с Unix Epoch
Тестируем:
◦ Обработку входного параметра времени с указанием часового пояса
◦ Возможный интервал дат
Не тестируем:
◦ Обработку входного параметра без указания часового пояса
◦ Даты вне интервала допустимых значений
16
• DotNetMsk.10.DemoTestProject.Contracts – DTO
контракты нашего сервиса
• DotNetMsk.10.DemoTestProject.Client – реализация
клиента
• DotNetMsk.10.DemoTestProject – веб-сервис. Его
мы и будем тестировать
• DotNetMsk.10.DemoTestProject.IntegrationTests,
DotNetMsk.10.DemoTestProject.UnitTests – проекты
с тестами
• DotNetMsk.10.DemoTestProject.Tests.Shared –
общий код для тестов. В нём находятся
SeverityAttribute и PriorityAttribute классы
17
Первый тест
18
19
[TestFixture]
public class TimeServiceShould
{
private readonly string _baseUrl;
public TimeServiceShould()
{
_baseUrl = ConfigurationManager.AppSettings["api.baseUrl"];
_baseUrl.Should().NotBeNullOrWhiteSpace();
}
private ITimerServiceClient Client => new TimerServiceClient(_baseUrl);
[Test]
[Severity(Severity.Blocker)]
public async Task RespondWithOk()
{
var response = await new RestClient(_baseUrl).ExecuteTaskAsync(new
RestRequest(TimerServiceClient.GetTimePassedRoute, Method.HEAD));
response.Should().NotBeNull();
response.Headers.Should().NotBeNullOrEmpty();
response.Headers.Should().Contain(p => p.Name.Equals("Allow",
StringComparison.InvariantCultureIgnoreCase));
}
}
Тестируем основной
функционал
20
21
[Severity(Severity.Critical)]
[TestCaseSource(nameof(CalculateTimestampFromStartOfUnixEpoch_DataSource))]
public async Task<string> CalculateTimestampFromStartOfUnixEpoch(string
tillDate)
{
return (await Client.GetTimePassedTillDateAsync(DateTime.Parse(tillDate)))
.ToString();
}
Запускаем – всё красное
22
Добавим немного кода 
23
Http stubs
24
Карманный
веб-сервер
25
26
[TestFixture]
public class TimerClientShould : IDisposable
{
private readonly IHttpServer _httpMock;
private readonly string _baseUrl;
public TimerClientShould()
{
_httpMock = HttpMockServer.LaunchTimeStub(ConfigurationManager.AppSettings["stub.baseUrl"]);
_baseUrl = ConfigurationManager.AppSettings["stub.baseUrl"];
_baseUrl.Should().NotBeNullOrWhiteSpace();
}
[Severity(Severity.Critical)]
[TestCase("2017-01-01T00:00:00.0000000Z", Description = "Basic positive test without time zone",
ExpectedResult = "17166.21:00:00")]
public async Task<string> CalculateTimestampFromStartOfUnixEpoch(string tillDate)
{
var sut = new TimerServiceClient(_baseUrl);
return (await sut.GetTimePassedTillDateAsync(DateTime.Parse(tillDate))).ToString();
}
public void Dispose() => _httpMock?.Dispose();
}
27
public static class HttpMockServer
{
public static IHttpServer LaunchTimeStub(string baseAddress)
{
var result = new HttpServer(new Uri(baseAddress));
//Setup error routes for test purposes
result.SetupErrorStubMethod(HttpStatusCode.BadRequest)
.SetupErrorStubMethod(HttpStatusCode.Unauthorized)
.SetupErrorStubMethod(HttpStatusCode.NotFound)
.SetupErrorStubMethod(HttpStatusCode.UnsupportedMediaType)
.SetupErrorStubMethod(HttpStatusCode.InternalServerError)
.SetupErrorStubMethod(HttpStatusCode.NotImplemented);
//Setup actual methods
result.Stub(rf => rf.Post($"/{TimerServiceClient.GetTimePassedTillDateRoute}"))
.Return(JsonConvert.SerializeObject(new TimePassedResponse
{
TimePassed = TimeSpan.Parse("17166.21:00:00"),
StartingPoint = new DateTime(1970, 1, 1)
}))
.AsContentType("application/json")
.WithStatus(HttpStatusCode.OK);
result.Start();
return result;
}
}
Обо мне
.NET C# разработчик, тим лид
Skype: lleyte
Email: leyte@live.ru
Facebook: https://facebook.com/an.zaytsev
GitHub repo: https://github.com/zaytsevand/DotNetMsk
28

More Related Content

What's hot

Java Core. Lecture# 3. Part# 3. Multithreading.
Java Core. Lecture# 3. Part# 3. Multithreading.Java Core. Lecture# 3. Part# 3. Multithreading.
Java Core. Lecture# 3. Part# 3. Multithreading.
Anton Moiseenko
 
C++ STL & Qt. Занятие 11.
C++ STL & Qt. Занятие 11.C++ STL & Qt. Занятие 11.
C++ STL & Qt. Занятие 11.
Igor Shkulipa
 
Java Core. Lecture# 3. Part# 2. Exceptions.
Java Core. Lecture# 3. Part# 2. Exceptions.Java Core. Lecture# 3. Part# 2. Exceptions.
Java Core. Lecture# 3. Part# 2. Exceptions.
Anton Moiseenko
 
QA Лекция2
QA Лекция2QA Лекция2
QA Лекция2
Svetlana Stoyan
 
лекция4 qa
лекция4 qaлекция4 qa
лекция4 qa
Svetlana Stoyan
 
лекция3 QA
лекция3 QAлекция3 QA
лекция3 QA
Svetlana Stoyan
 
модуль 14 введение в generics
модуль 14 введение в genericsмодуль 14 введение в generics
модуль 14 введение в generics
Yevgeniy Gertsen
 
ковалев нестандатное нт
ковалев    нестандатное нтковалев    нестандатное нт
ковалев нестандатное нтAlexei Lupan
 
C++ STL & Qt. Занятие 10.
C++ STL & Qt. Занятие 10.C++ STL & Qt. Занятие 10.
C++ STL & Qt. Занятие 10.
Igor Shkulipa
 
Тестируем код с Visual Studio 2012 - XP Days Ukraine 2012
Тестируем код с Visual Studio 2012 - XP Days Ukraine 2012Тестируем код с Visual Studio 2012 - XP Days Ukraine 2012
Тестируем код с Visual Studio 2012 - XP Days Ukraine 2012Dmytro Mindra
 
C++ STL & Qt. Занятие 05.
C++ STL & Qt. Занятие 05.C++ STL & Qt. Занятие 05.
C++ STL & Qt. Занятие 05.
Igor Shkulipa
 
Java Core. Lecture# 5. Concurrency.
Java Core. Lecture# 5. Concurrency.Java Core. Lecture# 5. Concurrency.
Java Core. Lecture# 5. Concurrency.
Anton Moiseenko
 
Тестирование осень 2013 лекция 4
Тестирование осень 2013 лекция 4Тестирование осень 2013 лекция 4
Тестирование осень 2013 лекция 4Technopark
 
Артем Розуменко - "Как и зачем разрабатывать собственный фреймворк?"
Артем Розуменко - "Как и зачем разрабатывать собственный фреймворк?"Артем Розуменко - "Как и зачем разрабатывать собственный фреймворк?"
Артем Розуменко - "Как и зачем разрабатывать собственный фреймворк?"
QA Dnepropetrovsk Community (Ukraine)
 
Java осень 2014 занятие 3
Java осень 2014 занятие 3Java осень 2014 занятие 3
Java осень 2014 занятие 3
Technopark
 
Архитектура. Доступноять программных систем.
Архитектура. Доступноять программных систем.Архитектура. Доступноять программных систем.
Архитектура. Доступноять программных систем.
Dima Dzuba
 
Dmitrii Dolzhenko «С++ Problems and How Test Frameworks Actually Work»
Dmitrii Dolzhenko «С++ Problems and How Test Frameworks Actually Work» Dmitrii Dolzhenko «С++ Problems and How Test Frameworks Actually Work»
Dmitrii Dolzhenko «С++ Problems and How Test Frameworks Actually Work»
LogeekNightUkraine
 
Автоматическая генерация тестов по комментариям к программному коду
Автоматическая генерация тестов по комментариям к программному кодуАвтоматическая генерация тестов по комментариям к программному коду
Автоматическая генерация тестов по комментариям к программному коду
Alexey Noskov
 

What's hot (20)

JRebel
JRebelJRebel
JRebel
 
Bytecode
BytecodeBytecode
Bytecode
 
Java Core. Lecture# 3. Part# 3. Multithreading.
Java Core. Lecture# 3. Part# 3. Multithreading.Java Core. Lecture# 3. Part# 3. Multithreading.
Java Core. Lecture# 3. Part# 3. Multithreading.
 
C++ STL & Qt. Занятие 11.
C++ STL & Qt. Занятие 11.C++ STL & Qt. Занятие 11.
C++ STL & Qt. Занятие 11.
 
Java Core. Lecture# 3. Part# 2. Exceptions.
Java Core. Lecture# 3. Part# 2. Exceptions.Java Core. Lecture# 3. Part# 2. Exceptions.
Java Core. Lecture# 3. Part# 2. Exceptions.
 
QA Лекция2
QA Лекция2QA Лекция2
QA Лекция2
 
лекция4 qa
лекция4 qaлекция4 qa
лекция4 qa
 
лекция3 QA
лекция3 QAлекция3 QA
лекция3 QA
 
модуль 14 введение в generics
модуль 14 введение в genericsмодуль 14 введение в generics
модуль 14 введение в generics
 
ковалев нестандатное нт
ковалев    нестандатное нтковалев    нестандатное нт
ковалев нестандатное нт
 
C++ STL & Qt. Занятие 10.
C++ STL & Qt. Занятие 10.C++ STL & Qt. Занятие 10.
C++ STL & Qt. Занятие 10.
 
Тестируем код с Visual Studio 2012 - XP Days Ukraine 2012
Тестируем код с Visual Studio 2012 - XP Days Ukraine 2012Тестируем код с Visual Studio 2012 - XP Days Ukraine 2012
Тестируем код с Visual Studio 2012 - XP Days Ukraine 2012
 
C++ STL & Qt. Занятие 05.
C++ STL & Qt. Занятие 05.C++ STL & Qt. Занятие 05.
C++ STL & Qt. Занятие 05.
 
Java Core. Lecture# 5. Concurrency.
Java Core. Lecture# 5. Concurrency.Java Core. Lecture# 5. Concurrency.
Java Core. Lecture# 5. Concurrency.
 
Тестирование осень 2013 лекция 4
Тестирование осень 2013 лекция 4Тестирование осень 2013 лекция 4
Тестирование осень 2013 лекция 4
 
Артем Розуменко - "Как и зачем разрабатывать собственный фреймворк?"
Артем Розуменко - "Как и зачем разрабатывать собственный фреймворк?"Артем Розуменко - "Как и зачем разрабатывать собственный фреймворк?"
Артем Розуменко - "Как и зачем разрабатывать собственный фреймворк?"
 
Java осень 2014 занятие 3
Java осень 2014 занятие 3Java осень 2014 занятие 3
Java осень 2014 занятие 3
 
Архитектура. Доступноять программных систем.
Архитектура. Доступноять программных систем.Архитектура. Доступноять программных систем.
Архитектура. Доступноять программных систем.
 
Dmitrii Dolzhenko «С++ Problems and How Test Frameworks Actually Work»
Dmitrii Dolzhenko «С++ Problems and How Test Frameworks Actually Work» Dmitrii Dolzhenko «С++ Problems and How Test Frameworks Actually Work»
Dmitrii Dolzhenko «С++ Problems and How Test Frameworks Actually Work»
 
Автоматическая генерация тестов по комментариям к программному коду
Автоматическая генерация тестов по комментариям к программному кодуАвтоматическая генерация тестов по комментариям к программному коду
Автоматическая генерация тестов по комментариям к программному коду
 

Similar to Андрей Зайцев - TDD в кровавом энтерпрайзе

Модульное тестирование и TDD в .NET
Модульное тестирование и TDD в .NETМодульное тестирование и TDD в .NET
Модульное тестирование и TDD в .NET
Alexander Byndyu
 
Повышение качества тестов и автоматическая валидация REST API документации
Повышение качества тестов и автоматическая валидация REST API документацииПовышение качества тестов и автоматическая валидация REST API документации
Повышение качества тестов и автоматическая валидация REST API документации
CEE-SEC(R)
 
КГТУ Лекция 6: Обеспечение Качества Программного Обеспечения
КГТУ Лекция 6: Обеспечение Качества Программного Обеспечения КГТУ Лекция 6: Обеспечение Качества Программного Обеспечения
КГТУ Лекция 6: Обеспечение Качества Программного Обеспечения
Iosif Itkin
 
Оценка проектов тестирования
Оценка проектов тестированияОценка проектов тестирования
Оценка проектов тестирования
Rina Uzhevko
 
Test Driven Development in .NET Applications
Test Driven Development in .NET ApplicationsTest Driven Development in .NET Applications
Test Driven Development in .NET ApplicationsAnton Vidishchev
 
GUI-автоматизация в Telerik Test Studio
GUI-автоматизация в Telerik Test StudioGUI-автоматизация в Telerik Test Studio
GUI-автоматизация в Telerik Test Studio
SQALab
 
Современный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтерыСовременный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтеры
corehard_by
 
Test driven development in net
Test driven development in netTest driven development in net
Test driven development in net
Alex Tumanoff
 
Test plan Толстова Ольга
Test plan Толстова ОльгаTest plan Толстова Ольга
Test plan Толстова Ольга
Smart-on-line
 
TDD: когда нужно и, самое главное, когда не нужно / Павел Калашников (SimbirS...
TDD: когда нужно и, самое главное, когда не нужно / Павел Калашников (SimbirS...TDD: когда нужно и, самое главное, когда не нужно / Павел Калашников (SimbirS...
TDD: когда нужно и, самое главное, когда не нужно / Павел Калашников (SimbirS...
Ontico
 
QA Fes 2016. Анастасия Асеева. Роль тестирования в Devops
QA Fes 2016. Анастасия Асеева. Роль тестирования в DevopsQA Fes 2016. Анастасия Асеева. Роль тестирования в Devops
QA Fes 2016. Анастасия Асеева. Роль тестирования в Devops
QAFest
 
QAFest. Роль тестирования в Devops
QAFest. Роль тестирования в DevopsQAFest. Роль тестирования в Devops
QAFest. Роль тестирования в Devops
Анастасия Асеева
 
Solit 2014, Централизованное управление тестами с помощью TestLink, Зубович В...
Solit 2014, Централизованное управление тестами с помощью TestLink, Зубович В...Solit 2014, Централизованное управление тестами с помощью TestLink, Зубович В...
Solit 2014, Централизованное управление тестами с помощью TestLink, Зубович В...
solit
 
Jbreak 2016: Твой личный Spring Boot Starter
Jbreak 2016: Твой личный Spring Boot StarterJbreak 2016: Твой личный Spring Boot Starter
Jbreak 2016: Твой личный Spring Boot Starter
Aleksandr Tarasov
 
доклад на SQADays 2011 в Казани
доклад на SQADays  2011 в Казанидоклад на SQADays  2011 в Казани
доклад на SQADays 2011 в Казаниmargo-qa
 
Вадим Зубович - Test Link
Вадим Зубович - Test LinkВадим Зубович - Test Link
Вадим Зубович - Test Link
QA Club Minsk
 
TestLink
TestLinkTestLink
TestLinkISsoft
 
Как построить свой фреймворк для автотестов?
Как построить свой фреймворк для автотестов?Как построить свой фреймворк для автотестов?
Как построить свой фреймворк для автотестов?
Dmitry Buzdin
 
Сергей Ревко
Сергей РевкоСергей Ревко
Сергей Ревко
SQALab
 
Мобильная Автоматизация в Контексте Continuous Delivery
Мобильная Автоматизация в Контексте  Continuous DeliveryМобильная Автоматизация в Контексте  Continuous Delivery
Мобильная Автоматизация в Контексте Continuous Delivery
Igor Dorovskikh
 

Similar to Андрей Зайцев - TDD в кровавом энтерпрайзе (20)

Модульное тестирование и TDD в .NET
Модульное тестирование и TDD в .NETМодульное тестирование и TDD в .NET
Модульное тестирование и TDD в .NET
 
Повышение качества тестов и автоматическая валидация REST API документации
Повышение качества тестов и автоматическая валидация REST API документацииПовышение качества тестов и автоматическая валидация REST API документации
Повышение качества тестов и автоматическая валидация REST API документации
 
КГТУ Лекция 6: Обеспечение Качества Программного Обеспечения
КГТУ Лекция 6: Обеспечение Качества Программного Обеспечения КГТУ Лекция 6: Обеспечение Качества Программного Обеспечения
КГТУ Лекция 6: Обеспечение Качества Программного Обеспечения
 
Оценка проектов тестирования
Оценка проектов тестированияОценка проектов тестирования
Оценка проектов тестирования
 
Test Driven Development in .NET Applications
Test Driven Development in .NET ApplicationsTest Driven Development in .NET Applications
Test Driven Development in .NET Applications
 
GUI-автоматизация в Telerik Test Studio
GUI-автоматизация в Telerik Test StudioGUI-автоматизация в Telerik Test Studio
GUI-автоматизация в Telerik Test Studio
 
Современный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтерыСовременный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтеры
 
Test driven development in net
Test driven development in netTest driven development in net
Test driven development in net
 
Test plan Толстова Ольга
Test plan Толстова ОльгаTest plan Толстова Ольга
Test plan Толстова Ольга
 
TDD: когда нужно и, самое главное, когда не нужно / Павел Калашников (SimbirS...
TDD: когда нужно и, самое главное, когда не нужно / Павел Калашников (SimbirS...TDD: когда нужно и, самое главное, когда не нужно / Павел Калашников (SimbirS...
TDD: когда нужно и, самое главное, когда не нужно / Павел Калашников (SimbirS...
 
QA Fes 2016. Анастасия Асеева. Роль тестирования в Devops
QA Fes 2016. Анастасия Асеева. Роль тестирования в DevopsQA Fes 2016. Анастасия Асеева. Роль тестирования в Devops
QA Fes 2016. Анастасия Асеева. Роль тестирования в Devops
 
QAFest. Роль тестирования в Devops
QAFest. Роль тестирования в DevopsQAFest. Роль тестирования в Devops
QAFest. Роль тестирования в Devops
 
Solit 2014, Централизованное управление тестами с помощью TestLink, Зубович В...
Solit 2014, Централизованное управление тестами с помощью TestLink, Зубович В...Solit 2014, Централизованное управление тестами с помощью TestLink, Зубович В...
Solit 2014, Централизованное управление тестами с помощью TestLink, Зубович В...
 
Jbreak 2016: Твой личный Spring Boot Starter
Jbreak 2016: Твой личный Spring Boot StarterJbreak 2016: Твой личный Spring Boot Starter
Jbreak 2016: Твой личный Spring Boot Starter
 
доклад на SQADays 2011 в Казани
доклад на SQADays  2011 в Казанидоклад на SQADays  2011 в Казани
доклад на SQADays 2011 в Казани
 
Вадим Зубович - Test Link
Вадим Зубович - Test LinkВадим Зубович - Test Link
Вадим Зубович - Test Link
 
TestLink
TestLinkTestLink
TestLink
 
Как построить свой фреймворк для автотестов?
Как построить свой фреймворк для автотестов?Как построить свой фреймворк для автотестов?
Как построить свой фреймворк для автотестов?
 
Сергей Ревко
Сергей РевкоСергей Ревко
Сергей Ревко
 
Мобильная Автоматизация в Контексте Continuous Delivery
Мобильная Автоматизация в Контексте  Continuous DeliveryМобильная Автоматизация в Контексте  Continuous Delivery
Мобильная Автоматизация в Контексте Continuous Delivery
 

Андрей Зайцев - TDD в кровавом энтерпрайзе

  • 3. Сначала вопрос Как можно тестировать? Результат – только видимые извне итоги работы системы, не обладая знаниями о реализации. Поведение – система имеет зависимости, взаимодействие с которыми можно отследить и протестировать. Контракты, интерфейсы, поверхность – аналогично результату. 3
  • 5. Когда тестировать В ОБЩЕМ СЛУЧАЕ Высокая стоимость ошибки Поведение не очевидно Требуется подтверждение результата работы АВТОМАТИЗИРУЯ Высокая частота релизов Контракты стабилизированы CI 5
  • 8. 8
  • 10. Основные артефакты Тест план ◦ Назначение данного плана ◦ Что тестируется (система, модуль, билд, …) ◦ Описание рисков ◦ Тестируемые фичи ◦ Не тестируемые фичи ◦ Стратегия тестирования ◦ Критерии успешного и не успешного завершения тестирования ◦ Описание окружения ◦ … 10 IEEE 829
  • 11. Зачем нужен план? ◦ Определяет цель тестирования ◦ Описывает стратегию и необходимый объём работ по тестированию ◦ Определяет объект тестирования ◦ Позволяет определить покрытие функциональных требований ◦ Ограничивает скоуп тестирования ◦ Описывает исходы тестирования и условия успешного прохождения тестирования 11
  • 12. Тест кейс • Название • Тестируемые фичи • Определение входных данных • Определение результата выполнения • Серьёзность и приоритет бага • ... 12
  • 14. Практика 11 СЛАЙДОВ БЕЗ СТРОЧКИ КОДА – ГДЕ ЖЕ ТУТ TEST DRIVEN? 14
  • 15. Проблема Когда закончить писать код? Test-driven development требует определить критерий полноты выполнения требования до того, как приступать к реализации. 15
  • 16. Определим Объект тестирования Web API, принимающий на вход дату и возвращающий интервал времени, прошедший (или предшествующий) этой дате с Unix Epoch Тестируем: ◦ Обработку входного параметра времени с указанием часового пояса ◦ Возможный интервал дат Не тестируем: ◦ Обработку входного параметра без указания часового пояса ◦ Даты вне интервала допустимых значений 16
  • 17. • DotNetMsk.10.DemoTestProject.Contracts – DTO контракты нашего сервиса • DotNetMsk.10.DemoTestProject.Client – реализация клиента • DotNetMsk.10.DemoTestProject – веб-сервис. Его мы и будем тестировать • DotNetMsk.10.DemoTestProject.IntegrationTests, DotNetMsk.10.DemoTestProject.UnitTests – проекты с тестами • DotNetMsk.10.DemoTestProject.Tests.Shared – общий код для тестов. В нём находятся SeverityAttribute и PriorityAttribute классы 17
  • 19. 19 [TestFixture] public class TimeServiceShould { private readonly string _baseUrl; public TimeServiceShould() { _baseUrl = ConfigurationManager.AppSettings["api.baseUrl"]; _baseUrl.Should().NotBeNullOrWhiteSpace(); } private ITimerServiceClient Client => new TimerServiceClient(_baseUrl); [Test] [Severity(Severity.Blocker)] public async Task RespondWithOk() { var response = await new RestClient(_baseUrl).ExecuteTaskAsync(new RestRequest(TimerServiceClient.GetTimePassedRoute, Method.HEAD)); response.Should().NotBeNull(); response.Headers.Should().NotBeNullOrEmpty(); response.Headers.Should().Contain(p => p.Name.Equals("Allow", StringComparison.InvariantCultureIgnoreCase)); } }
  • 21. 21 [Severity(Severity.Critical)] [TestCaseSource(nameof(CalculateTimestampFromStartOfUnixEpoch_DataSource))] public async Task<string> CalculateTimestampFromStartOfUnixEpoch(string tillDate) { return (await Client.GetTimePassedTillDateAsync(DateTime.Parse(tillDate))) .ToString(); }
  • 22. Запускаем – всё красное 22
  • 26. 26 [TestFixture] public class TimerClientShould : IDisposable { private readonly IHttpServer _httpMock; private readonly string _baseUrl; public TimerClientShould() { _httpMock = HttpMockServer.LaunchTimeStub(ConfigurationManager.AppSettings["stub.baseUrl"]); _baseUrl = ConfigurationManager.AppSettings["stub.baseUrl"]; _baseUrl.Should().NotBeNullOrWhiteSpace(); } [Severity(Severity.Critical)] [TestCase("2017-01-01T00:00:00.0000000Z", Description = "Basic positive test without time zone", ExpectedResult = "17166.21:00:00")] public async Task<string> CalculateTimestampFromStartOfUnixEpoch(string tillDate) { var sut = new TimerServiceClient(_baseUrl); return (await sut.GetTimePassedTillDateAsync(DateTime.Parse(tillDate))).ToString(); } public void Dispose() => _httpMock?.Dispose(); }
  • 27. 27 public static class HttpMockServer { public static IHttpServer LaunchTimeStub(string baseAddress) { var result = new HttpServer(new Uri(baseAddress)); //Setup error routes for test purposes result.SetupErrorStubMethod(HttpStatusCode.BadRequest) .SetupErrorStubMethod(HttpStatusCode.Unauthorized) .SetupErrorStubMethod(HttpStatusCode.NotFound) .SetupErrorStubMethod(HttpStatusCode.UnsupportedMediaType) .SetupErrorStubMethod(HttpStatusCode.InternalServerError) .SetupErrorStubMethod(HttpStatusCode.NotImplemented); //Setup actual methods result.Stub(rf => rf.Post($"/{TimerServiceClient.GetTimePassedTillDateRoute}")) .Return(JsonConvert.SerializeObject(new TimePassedResponse { TimePassed = TimeSpan.Parse("17166.21:00:00"), StartingPoint = new DateTime(1970, 1, 1) })) .AsContentType("application/json") .WithStatus(HttpStatusCode.OK); result.Start(); return result; } }
  • 28. Обо мне .NET C# разработчик, тим лид Skype: lleyte Email: leyte@live.ru Facebook: https://facebook.com/an.zaytsev GitHub repo: https://github.com/zaytsevand/DotNetMsk 28

Editor's Notes

  1. Это не совсем обычный мост – это летающий паром. Для того, чтобы такой мост появился, нужно было сочетание нескольких факторов: достаточной зрелости технологий, потребности в транспортировке ограниченного количества людей и грузов с одного берега на другой, потребности в сохранении судоходной этой части реки. Почему я решил начать рассказ с него? Потому, что интеграция различных систем напоминает наведение мостов, потому что Addison Wesley обожают помещать фото мостов на обложки своих книг и потому, что этот мост до сих пор работает, что для меня является прекрасным примером успешности инженерного решения.
  2. Результат – только видимые извне итоги работы системы, не обладая знаниями о реализации. Поведение – система имеет зависимости, взаимодействие с которыми можно отследить и протестировать. Контракты, интерфейсы, поверхность – аналогично результату.
  3. Тестировать можно практически все части системы, систему в сборе, отдельные инсталляции, конфигурации.
  4. Если не удалось разглядеть картинку с предыдущих слайдов, то её можно найти на гитхабе
  5. S1 Блокирующая (Blocker) Блокирующая ошибка, приводящая приложение в нерабочее состояние, в результате которого дальнейшая работа с тестируемой системой или ее ключевыми функциями становится невозможна. Решение проблемы необходимо для дальнейшего функционирования системы. S2 Критическая (Critical) Критическая ошибка, неправильно работающая ключевая бизнес логика, дыра в системе безопасности, проблема, приведшая к временному падению сервера или приводящая в нерабочее состояние некоторую часть системы, без возможности решения проблемы, используя другие входные точки. Решение проблемы необходимо для дальнейшей работы с ключевыми функциями тестируемой системой. S3 Значительная (Major)  Значительная ошибка, часть основной бизнес логики работает некорректно. Ошибка не критична или есть возможность для работы с тестируемой функцией, используя другие входные точки. S4 Незначительная (Minor)  Незначительная ошибка, не нарушающая бизнес логику тестируемой части приложения, очевидная проблема пользовательского интерфейса. S5 Тривиальная (Trivial)  Тривиальная ошибка, не касающаяся бизнес логики приложения, плохо воспроизводимая проблема, малозаметная посредствам пользовательского интерфейса, проблема сторонних библиотек или сервисов, проблема, не оказывающая никакого влияния на общее качество продукта. P1 Высокий (High)  Ошибка должна быть исправлена как можно быстрее, т.к. ее наличие является критической для проекта. P2 Средний (Medium)  Ошибка должна быть исправлена, ее наличие не является критичной, но требует обязательного решения. P3 Низкий (Low)  Ошибка должна быть исправлена, ее наличие не является критичной, и не требует срочного решения.
  6. Определим объект тестирования в коде. Контракты; Интерфейс; Тест.
  7. Вопрос: каким должен быть первый тест для Web API?
  8. До того, как начинать функциональное тестирование, стоит убедиться, что наш сервис работает. Этот тест по сути smoke – мы проверяем, что API отвечает. Прохождение данного теста является критическим для определения работоспособности приложения. Обратите внимания на проверки - они последовательно проверяют разные части ответа. Чем подробнее проверки, тем легче определить источник проблемы. Для их написания я использовал пакет FluentAssertions, так как он приблежает написание ассерта к естественному языку.
  9. Ключевые моменты: Разделение тестовых данных и логики выполнения теста; Использование того же клиента к API, что и в коде приложения. Клиент покрывается тестами отдельно, и в его работоспособности мы уверены, плюс при разработке мы не тратим лишнее время на поддержку тестов; Скоуп тест-кейса жёстко ограничен. Гранулярность скоупа позволяет тратить меньше времени на идентификацию части приложения, в которой произошла ошибка, а так же степени важности и приоритета самой ошибки.
  10. После реализации клиента и API останется запустить тесты ещё раз, чтобы убедиться, что они стали зелёными; отрефакторить код и запустить тесты снова.
  11. HttpMock очень полезен, когда нужно протестировать клиент к REST сервису.