Обновить
0
Сергей@SergejSh

Programmer

1
Подписчики
Отправить сообщение
Так то оно так но есть к сожалению троглодиты которые книжек ни читают и тесты не пишут
Главная задача для меня — получать удовольствие от программирования.

Как бы это… тут мы как представители древнейшей профессии (приятно, да еще и деньги платят не малые).
А по поводу высоком уровне. В Зависимости от задачи отвечаю на вопросы
Что должно произойти в системе?
Как это может быть исполнено?
Ну и пишу соответствующие тесты и интерфейсы которые пока мокаются.
в дальнейшем заменяю моки реализацией.
В общем BDD
К стати я тоже стараюсь сначала писать тесты только мотивация у меня совсем не такая.
Я работаю скорее по BDD начинаю проектировать на каком то достаточно высоком уровне и постепенно спускаюсь к более низкоуровневым конструкциям, но до тестов одного класса доходит редко обычно в случае если там какая то особо заумная функция есть.
И мотивация только одна сделать свою работу как можно лучше. А все что Вы перечислили это только дополнительные стимулы.
Юнит тесты тестируют именно поведение классов. Модули, состоящие из множества классов тестируют интеграционными тестами.

Вот именно с этим я и спорю Интереса ради почитайте искусство автономного тестирования автор Рой Ошероув
Вот определение UnitTest которое он дает

Единица работы
— это совокупность действий от момента вызова какого-то
открытого метода в системе до единственного конечного результата, замет-
ного тесту системы. Этот конечный результат можно наблюдать, не исследуя
внутреннее состояние системы, а только с помощью открытых API и поведе-
ния.
Автономный тест – это часть кода, которая
вызывает единицу работы и затем проверяет ее конечный результат. Если
предположения о конечном результате не подтверждаются, считается, что
автономный тест завершился неудачно. Объектом автономного тестиро-
вания может быть как единственный метод, так и совокупность нескольких
классов.

Баги часто встречаются именно при взаимодействии классов. Если несколько классов предоставляют некую сущность которую можно протестировать вместе то лучше так и делать. И если вы считаете этот тест интеграционным, ну это ваше дело.
Цель За меньшее время написать тесты имеющие наибольшее покрытие.
вот к стати статья в которой автор рассуждает об интеграционных и юнит тестов https://habrahabr.ru/post/275249/
В общем все правильно но пару маленьких замечаний.
1) Статья некая обзорная лекция о тестировании применимая думаю на любой платформе и любом языке.
Зачем в заглавии слово Android?
2) Скорее вопрос. Я согласен с определениием юнит тестов.
Но скажите пожалуйста у Вас в фирме при написании тестов действительно «Чаще всего в качестве юнита выбирается какой-либо класс».
Думаю, что это скорее исключениие. Реально выбирается модуль состоящий обычно из множества классов.
Ну для примера можно скачать с GitHab нескольно приложений в который есть тесты.
Специально я не исследовал, но на вскидку не нашел ни одного в котором тестировался бы каждый класс отдельно.
Почему я на это обратил внимание?
В фирме где я работаю начитались таких утверждений и считают это образцом.
Ну а так как классов у нас тысячи (порядка 5 000) и в каждом классе минимум пять функций,
то написание Юнит тестов это хотя и надо, но непозволительно долго.
3) Утверждение что Написание тестов значительно увеличивает время разработки справедливо в первую очередь если UnitTest пишется на объекты низкого уровня.
Если разработчик не парится по поводу размера юнита, а пишет тесты исходя из здравого смысла, то возможно даже и сокращает.
1)Смысл в том что мои «считалки» идут в разрез с общей терминологией. И общая практика вроде бы как раз писать больше чистых Unit тестов.
2) Наши базы это эталонные базы соответствующих версий. Так как я тесты провожу в одной транзакции с последующим откатом, то насрать туда нереально.
Единственный мой мок базы в том, что я использую всегда один коннект и начинаю транзакцию перед тестом.
(Система построена так, что все внутренние транзакции в таком случае создают savePoint)

У каждого естественно своя ситуация и он сам может определить для себя СТОИМОСТЬ-ЭФФЕКТИВНОСТЬ.
1) Да система то же Unit (только очень большой)
2) Да я для себя считаю все тесты Unit хотя на самом деле почти все мои тесты интеграционные.
3)Базу я не мокаю потому, что по очень долго заполнять все свойства из параметров теста и прочее
реально встречаются очень сложные объекты с десятками свойств и вложенных свойств.
их в моем конкретном случае проще начитать из базы.
Вообще где то в планах сделать для теста кешируемое обращение к базе.
я для себя сделал такое определение Unit для юнит теста это класс или группа классов имеющих какое то законченное поведение.
И в тесте я проверяю именно соответствие этому поведению.
Про взаимодействие с базой.
Естественно взаимодействие с базой у нас через интерфейсы и при желании их можно подменить но
  1. При любом раскладе я должен проверить корректность «Маппинга» полей в базе на свойства класса
  2. Откуда брать корректурные значения для заполнения свойств классов?
  3. То же самое и про метаданные

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


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

Увы во всей компании только я один использую тесты
Тесты разбиты по категориям 'дневной' и 'ночной' и TeemCity гоняет их после каждого комита (не только моего) дневные тесты ходят обычно минут 5 и это сопоставимо с временем сборки всех проектов.
А на своем компе я гоняю обычно тесты того что я разрабатываю и опять время выполнения тестов не на много больше времени сборки. Так что быстродействие тестов пока для меня не критично.
Но мой опыт говорит, что в отдельном классе даже тестировать зачастую нечего и классов таких достаточно много.

Ну так не тестируйте, никто ж не заставляет.

Да не заставляет, но концепция UnitTest именно в том, что бы тестировать классы по отдельности.

Вместе они образуют некий Unit который я и тестирую

А вот это уже странно.
Много классов, в которых тестировать нечего, вместе не могут образовывать нечто, где есть, что тестировать.
Ну или вы умалчиваете, что у вас есть что-то, что объединяет эти классы, что вы на самом деле и тестируете.

Тут уже словоблудие, естевственно я тестирую именно взаимодействие классов.

При этом я не мокую базу ибо это долго

Почему долго-то? В коде с корректно разделенными ответственностями это быстро.

Потому что наш код тесно переплетен с базой.
Все объекты берут свои метаданные из базы и… в общем случае корректно создать класс без обращения к базе весьма и весьма долгона
На самом деле я давно думаю написать какую ни будь заглушку, что бы кешировать обращение к базе.

да он ходит относительно долго но его быстро написать

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

И у меня есть такие примеры. Однако общее время написания одного интеграционного теста все равно в разы меньше, чем время написания Unit на каждый класс внего входящий, а потом еще интеграционный тест.

скорее покажет что возникла ошибка.

Почему «скорее»? Выполняется он медленнее, и вариантов тоже покрывает меньше.

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

Кроме того он не устареет если к примеру изменится название поля в базе

Правда? А откуда у вас берется БД с актуальными названиями полей (да еще и доступная с CI-сервера)?
А представьте, что у вас одновременно пошли тесты по трем версиям, у каждой из которых своя БД?

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

И да, мои юнит-тесты тоже не устаревают, когда меняется название поля в БД. Им вообще плевать на названия полей в БД.

Но вы все равно вынуждены писать тесты на корректную работу с базой.

Писать тесты на каждый класс на самом деле безумно долго

Не надо писать на каждый. Надо писать на те, где это оправданно.

Что я и делаю.

Тесты будут зачастую простые до идиотизма

Это же прекрасно. Простой тест — меньше ошибок в самом тесте, меньше ложных срабатываний, проще сетап.

Ответ в вы сами дали в пункте выше.

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

Почему вдруг?

Изменив один класс я должен переписать все моки этого класса. И хорошо еще если ни чего не забуду.

А общий интеграционный тест все равно необходим.

Конечно, необходим. Но если у вас есть покрытие юнит-тестами, то вы можете покрывать интеграционными тестами меньшее количество сценариев (а, значит, общее время выполнения сократится). И это не говоря о том, что есть вещи, которые интеграционными тестами покрыть сложно (а вот юнит-тестами они покрываются легко).

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

РЕЗЮМЕ:
Писать тесты нужно исходя из критерия СТОИМОСТЬ-ЭФФЕКТИВНОСТЬ.
Стомость-время затраченное на написание (Поддержку).
Эффективность — шанс найти ошибки.
И я нахожу, что по этому критерию большая часть должна быть именно интеграционных тестов.

Oно конечно так. Но мой опыт говорит, что в отдельном классе даже тестировать зачастую нечего и классов таких достаточно много. Вместе они образуют некий Unit который я и тестирую
При этом я не мокую базу ибо это долго и в результате я получаю один тест (testCase возможно много), да он ходит относительно долго но его быстро написать и он более или менее корректный и скорее покажет что возникла ошибка.
Кроме того он не устареет если к примеру изменится название поля в базе или любое другое взаимодействие внутри моего Unit.
Когда я пробовал мокать базу я потратил на написание теста много больше времени и все равно вынужден был писать тест на взаимодействие с базой.
Писать тесты на каждый класс на самом деле безумно долго Тесты будут зачастую простые до идиотизма. и любое изменение потребует переписать кучу тестов.
А общий интеграционный тест все равно необходим.
Полностью поддерживаю автора.
Использование аля интеграционных тестов вместо классических unit
Экономит много больше времени. чем поиск ошибок когда покраснело несколько тестов.
во первых вы пишите тесты на один класс и косвенно тестируете еще множество классов.
во вторых вы не тратите время на написание и отладку моков, стабов, и тп.
Исходя из практике ломаются как правило не отдельные классы а «стыки» то есть то самое что интеграционные тесты и тестируют.
Вообще вызов из OnSelectedObjectChanged там я проверяю, на случай если объект уже найден и путь на него есть ну и если нет то вызываю вот эту функцию.
 public void SelectItem()
        {
            List<int> path = new List<int>();
            FindedPath = FindPathByObject(this.ItemsSource, path);//найти путь для объекта
            if (FindedPath != null)
            {
               
                failCount = 0;//сбросили счетчик падений
                SelectNodeByPath(this, FindedPath);
            }
        }
Спасибо.
Обязательно буду разбираться так как часть BringIngexIntoView самая проблемная.

У нас существует достаточно много работающего кода в котором в treeView отображается иерархическая коллекция бизнес объектов и в которых нет и не должно быть свойств IsSelected, IsExpanded.
некоторые из них весьма большие.
И у всех из них одномоментно появился работающий поиск без всякого усилия со стороны разработчиков(кроме меня).
Можно конечно каждый раз при получении ItemSource автоматически создавать вьюмодельную коллекцию оболочку, но извините а сколько времени это займет когда коллекция имеет 1000 узлов. Ох долго.
В общем это не мой путь.
А за пример кода спасибо посмотрю разберусь что нибудь очень возможно и скопипащу.
Этот блог я даже не видел, все что аналогично в нем FindVisualChild но таких множество в инете.
Идея похожа но… весьма отдаленно.
полностью согласен отвыкать надо
Обычно использую StringBuilder когда надо собрать большой текст и потери заметны.
а тут по большому счету копейки. Не в этом суть поста

Поиск происходит по коллекции ItemsSource которую отображает TreeView.
и как бы при поиске все дочерние элементы то же будут загружены.
Как бы там вы поиск не организовывали окажутся в памяти.
При моем подходе не происходит построения визуального дерева пока не надо показать выбранный объект.
А проход по ресурсам которых тысячи ну да замедлит работу на доли секунды. Тут к сожалению без вариантов.
Зато универсально работает без дополнительных усилий разработчиков.

Информация

В рейтинге
Не участвует
Откуда
Москва, Москва и Московская обл., Россия
Дата рождения
Зарегистрирован
Активность