Ответы на вопросы, правила написания юнит-тестов. Поддержи развитие канала! money.yandex.ru/to/4100139057... Qiwi Wallet +79534684569 Группа ВКонтакте: easycomp
Добрый день и спасибо за очередной потрясающий урок. У меня возникли вопросы: 1. Я так и не понял зачем нам нужен именно Unit test. Почему я не могу подключить отдельный проект скажем консольный, подключить необходимые пространства имен для работы и написать обыкновенные методы в которых буду и реализовать ARRANGE ACT ASSERT. а после выводить результаты теста в консоль. 2. Что таит под собой атрибут [Test] и почему им надо помечать метод если в нем и так записана вся логика от объявления до вызова тестируемого метода и проверки. 3. Почему надо имя класса заканчивать на слово Test это как-то влияет на компилятор ? Как скажем у контроллеров в MVC ?
+Sargis Lefty Sanoyan 1. Можно и отдельный консольный проект, но через NUnit удобнее. Сам по себе NUnit ничего не делает, а только предоставляет удобную среду для запуска тестовых методов 2. Атрибут [Test] как раз и показывает среде NUnit, что данный метод - тестовый. Если атрибут не указать, то NUnit метод не увидит и запустить его через NUnit не получится. 3. Заканчивать тестовые классы на Test - это общепринятое соглашение, никак на компилятор не влияет. Влияют только атрибуты, как я уже говорил.
Увлекательно и познавательно как всегда!!! Особо радует, что Вы добрались до реальных примеров. Пока один вопрос: обязательно ли отделять слой данных от бизнес логики или это желательно, или это выбор только для данного примера и ничего страшного нет в том, что слой данных знает про/умеет создавать экземпляры типов бизнес логики? Еще, если это возможно, хотелось бы, чтобы Вы сделали акцент на применении статических классов. В первую очередь где это во благо, а также где это зло вопиющее и ошибка новичка. Спасибо.
+Сергей Ф Ну как сказать, конечно, Вселенная не взорвется, если слой данных будет обращаться к бизнес-логике ) И программа будет работать. Но с точки зрения классического подхода это категорически неверно. А дальше уже Вы сами решаете, как Вам строить архитектуру своего приложения )
Кстати, тем, кто захочет воспроизвести код, у меня была проблема такого рода с NUnit: не поддерживалась 3-я версия NUnit Resharper-ом Ultimate 2015.2 . Пока не поставил версию 10.2 ничего не прыгало. Пробовал 3 других варианта (с устаревшей графической оболочкой, с NUnit Test Adapter [тут какой-то результат вроде намечался, но я не дожал, т.к. то что я мог все таки получить меня не вдохновило] и дагунгрейдом NUnity до 2.6). Так что проверяйте версию ReSharper!
Поставил NUnit Test Adapter, но не знаю как его использовать в студии. Таким образом не могу запустить юнит-тесты. Кто-нибудь может подсказать как это сделать ?
Спасибо вам за уроки! Наверноe мой вопрос будет немного не по теме, скорее это относится к рефакторингу. Тестовый метод: public void GenerateUser_NameRequired() { UserEntity entity = _generator.GenerateUser(); string name = entity.Name; Assert.That(name, Is.Not.Empty); } Почему вы пишете именно так, а не например: string name = _generator.GenerateUser().Name; или сразу Assert.That(_generator.GenerateUser().Name, Is.Not.Empty); так лаконично и, в принципе, тоже понятно. Есть какие то рекомендации или "правила хорошего тона" при написании кодa?
+Анжей Ковальски На мой взгляд, вариант в уроке куда читаемее, чем Assert.That(_generator.GenerateUser().Name, Is.Not.Empty); И еще одна причина: во время отладки можно сразу увидеть все переменные: entity со всеми полями, name в окне отладки Locals. Ведь юнит-тесты, помимо непосредственно тестирования, удобно использовать и для отладки.
Мне одному кажется, интерфейс IScriptGenerator замешал в себя две задачи? Задача первая- генерировать данные, т.е. poco, которые заполнены данными. Задача вторая- из данных, которые подаются ему на вход генерировать скрипт. Т.е. если у меня меняется скрипт, его формат, то это никак не должно влиять на генерацию данных. И наоборот. Я интерфейс разбил на две части.
Спасибо за урок! Вопрос. Вы говорили, что один класс должен делать одну задачу. Класс, в котором хранятся данные, должен иметь только поля для данных без логики. Но, что если поля данных жорстко зависят друг от друга? То есть, изменение одного поля, влечет немедленное изменение остальных полей. Может произойти ситуация, когда кто-то из разработчиков, начнет обращаться к классу хранения данных напрямую, игнорируя класс управления этими данными, и, естественно, рискует нарушить логику приложения. Имеет ли смысл в этом случае писать setter-ы с нужной логикой прямо внутри класса хранения данных? Надеюсь не сильно вас запутал. Еще раз, спасибо!
+ReasonX7 Любое изменение внутреннего состояния класса при обращении к его методам должно быть как-то задекларировано. Либо именем метода, либо XML-комментарием к методу, либо (что хуже) некоей сторонней справкой. Тогда логика будет прозрачна.
+Программирование - это просто В комментариях к сеттерам записано, как это повлияет на внутреннее состояние класса. Как я понял, в данном случае, такую практику можно считать нормальной?
+ReasonX7 В принципе да, но если сеттер серьезно влияет на поведение, то я бы использовал лучше явный метод, что-то типа Set...(). Но это сугубо мое личное мнение )
Нет такого символа "Нижнее подчеркивание", в прочем как и верхнего... Символ "_" называется "Знак подчеркивания". Извините, но не смог не сказать об этом, очень режет слух.
Спасибо, благодаря урокам внедрил тестирование в свой проект.
Автор GrandMaster) уважение
Автор, вернись обратно! Не хватает нового контента от тебя!
Добрый день и спасибо за очередной потрясающий урок.
У меня возникли вопросы:
1. Я так и не понял зачем нам нужен именно Unit test. Почему я не могу подключить отдельный проект скажем консольный, подключить необходимые пространства имен для работы и написать обыкновенные методы в которых буду и реализовать ARRANGE ACT ASSERT. а после выводить результаты теста в консоль.
2. Что таит под собой атрибут [Test] и почему им надо помечать метод если в нем и так записана вся логика от объявления до вызова тестируемого метода и проверки.
3. Почему надо имя класса заканчивать на слово Test это как-то влияет на компилятор ? Как скажем у контроллеров в MVC ?
+Sargis Lefty Sanoyan
1. Можно и отдельный консольный проект, но через NUnit удобнее. Сам по себе NUnit ничего не делает, а только предоставляет удобную среду для запуска тестовых методов
2. Атрибут [Test] как раз и показывает среде NUnit, что данный метод - тестовый. Если атрибут не указать, то NUnit метод не увидит и запустить его через NUnit не получится.
3. Заканчивать тестовые классы на Test - это общепринятое соглашение, никак на компилятор не влияет. Влияют только атрибуты, как я уже говорил.
А может еще добавите проект на Github или в TFS? заодно можно покрыть тему систем контроля версий
Увлекательно и познавательно как всегда!!!
Особо радует, что Вы добрались до реальных примеров. Пока один вопрос: обязательно ли отделять слой данных от бизнес логики или это желательно, или это выбор только для данного примера и ничего страшного нет в том, что слой данных знает про/умеет создавать экземпляры типов бизнес логики?
Еще, если это возможно, хотелось бы, чтобы Вы сделали акцент на применении статических классов. В первую очередь где это во благо, а также где это зло вопиющее и ошибка новичка.
Спасибо.
+Сергей Ф Ну как сказать, конечно, Вселенная не взорвется, если слой данных будет обращаться к бизнес-логике ) И программа будет работать. Но с точки зрения классического подхода это категорически неверно. А дальше уже Вы сами решаете, как Вам строить архитектуру своего приложения )
Спасибо за ответ!
3:29 - а можно делегировать =).
После введения TestFixture в поле using не добавляется NUnit.Framework. Нужно подключить вручную?
Кстати, тем, кто захочет воспроизвести код, у меня была проблема такого рода с NUnit: не поддерживалась 3-я версия NUnit Resharper-ом Ultimate 2015.2 . Пока не поставил версию 10.2 ничего не прыгало. Пробовал 3 других варианта (с устаревшей графической оболочкой, с NUnit Test Adapter [тут какой-то результат вроде намечался, но я не дожал, т.к. то что я мог все таки получить меня не вдохновило] и дагунгрейдом NUnity до 2.6). Так что проверяйте версию ReSharper!
Поставил NUnit Test Adapter, но не знаю как его использовать в студии. Таким образом не могу запустить юнит-тесты. Кто-нибудь может подсказать как это сделать ?
Спасибо вам за уроки!
Наверноe мой вопрос будет немного не по теме, скорее это относится к рефакторингу.
Тестовый метод:
public void GenerateUser_NameRequired()
{
UserEntity entity = _generator.GenerateUser();
string name = entity.Name;
Assert.That(name, Is.Not.Empty);
}
Почему вы пишете именно так, а не например:
string name = _generator.GenerateUser().Name;
или сразу
Assert.That(_generator.GenerateUser().Name, Is.Not.Empty);
так лаконично и, в принципе, тоже понятно.
Есть какие то рекомендации или "правила хорошего тона" при написании кодa?
+Анжей Ковальски На мой взгляд, вариант в уроке куда читаемее, чем Assert.That(_generator.GenerateUser().Name, Is.Not.Empty); И еще одна причина: во время отладки можно сразу увидеть все переменные: entity со всеми полями, name в окне отладки Locals. Ведь юнит-тесты, помимо непосредственно тестирования, удобно использовать и для отладки.
+Программирование - это просто Понятно, спасибо.
Мне одному кажется, интерфейс IScriptGenerator замешал в себя две задачи? Задача первая- генерировать данные, т.е. poco, которые заполнены данными. Задача вторая- из данных, которые подаются ему на вход генерировать скрипт. Т.е. если у меня меняется скрипт, его формат, то это никак не должно влиять на генерацию данных. И наоборот. Я интерфейс разбил на две части.
Спасибо за урок!
Вопрос. Вы говорили, что один класс должен делать одну задачу. Класс, в котором хранятся данные, должен иметь только поля для данных без логики.
Но, что если поля данных жорстко зависят друг от друга? То есть, изменение одного поля, влечет немедленное изменение остальных полей. Может произойти ситуация, когда кто-то из разработчиков, начнет обращаться к классу хранения данных напрямую, игнорируя класс управления этими данными, и, естественно, рискует нарушить логику приложения.
Имеет ли смысл в этом случае писать setter-ы с нужной логикой прямо внутри класса хранения данных?
Надеюсь не сильно вас запутал. Еще раз, спасибо!
+ReasonX7 Любое изменение внутреннего состояния класса при обращении к его методам должно быть как-то задекларировано. Либо именем метода, либо XML-комментарием к методу, либо (что хуже) некоей сторонней справкой. Тогда логика будет прозрачна.
+Программирование - это просто В комментариях к сеттерам записано, как это повлияет на внутреннее состояние класса. Как я понял, в данном случае, такую практику можно считать нормальной?
+ReasonX7 В принципе да, но если сеттер серьезно влияет на поведение, то я бы использовал лучше явный метод, что-то типа Set...(). Но это сугубо мое личное мнение )
+Программирование - это просто Методы так и называются. setNameOfField(data) { ... }
Спасибо, за оперативные ответы!
Если у кого получилось с NUnit Test Adapter запустить тесты в VS, отпишитесь пожалуйста.
Сам себе отвечу... Нужно просто поставить NUnit3 Test Adapter.
+Егор Сухоруков Да, действительно, с NUnit3 Test Adapter всё работает, спасибо )
Нет такого символа "Нижнее подчеркивание", в прочем как и верхнего... Символ "_" называется "Знак подчеркивания". Извините, но не смог не сказать об этом, очень режет слух.
Сраные гуманитарии
вам случайно ученик не нужен собственный?)