Про юнит тесты
От: Ellin Россия www.rsdn.ru
Дата: 06.07.09 09:36
Оценка:
Оч. понравилась, конечно, идея разработки с тестами... Вот только уже давно не могу понять. Допустим есть у меня метод, который отсылает почту нескольким джентельменам, адреса которых берет из базы. Как писать тест? Не могу же я их почтовые ящики проверить. Дошло или нет.
Или допустим мой метод анализирует файлы по указанному пути... на выходе дает некоторую сумму. Файлы, допустим вперемешку ворд и эксель с жуткой структурой. Тоже непонятно как тестировать. Если копировать на локальный диск, в папку проекта, так нельзя распространять файлы эти... запрещено внутренними политиками и т.п.
Re: Про юнит тесты
От: Nuseraro Россия  
Дата: 06.07.09 09:42
Оценка:
Здравствуйте, Ellin, Вы писали:

E>Оч. понравилась, конечно, идея разработки с тестами... Вот только уже давно не могу понять. Допустим есть у меня метод, который отсылает почту нескольким джентельменам, адреса которых берет из базы. Как писать тест? Не могу же я их почтовые ящики проверить. Дошло или нет.

E>Или допустим мой метод анализирует файлы по указанному пути... на выходе дает некоторую сумму. Файлы, допустим вперемешку ворд и эксель с жуткой структурой. Тоже непонятно как тестировать. Если копировать на локальный диск, в папку проекта, так нельзя распространять файлы эти... запрещено внутренними политиками и т.п.

Правильный дизайн, заглушки и эмуляторы.

Вообще вечная тема, довольно часто обсуждается...
Homo Guglens
Re: Про юнит тесты
От: koandrew Канада http://thingselectronic.blogspot.ca/
Дата: 06.07.09 11:51
Оценка: 1 (1)
Здравствуйте, Ellin, Вы писали:

Вы допускаете наиболее распространённую ошибку начинающего использовать тесты.

E>Оч. понравилась, конечно, идея разработки с тестами... Вот только уже давно не могу понять. Допустим есть у меня метод, который отсылает почту нескольким джентельменам, адреса которых берет из базы. Как писать тест? Не могу же я их почтовые ящики проверить. Дошло или нет.

То, что вы говорите ("дошло или нет?") — это интеграционный тест. Юнит-тест здесь должен проверять, что на все адреса, которые он взял (из мока), вызван соответствующий метод сервиса, отвечающего за отправку писем...

E>Или допустим мой метод анализирует файлы по указанному пути... на выходе дает некоторую сумму. Файлы, допустим вперемешку ворд и эксель с жуткой структурой. Тоже непонятно как тестировать. Если копировать на локальный диск, в папку проекта, так нельзя распространять файлы эти... запрещено внутренними политиками и т.п.

Опять интеграционный тест. Во-первых, можно сварганить тестовые данные, во-вторых, можно эмулировать их содержимое.
Вообще главное правило тут — юнит-тест должен тестировать _один_ метод, при этом все его зависимости должны быть сымитированы моками
[КУ] оккупировала армия.
Re[2]: Про юнит тесты
От: Ellin Россия www.rsdn.ru
Дата: 06.07.09 11:54
Оценка: +1
Здравствуйте, koandrew, Вы писали:

E>>Или допустим мой метод анализирует файлы по указанному пути... на выходе дает некоторую сумму. Файлы, допустим вперемешку ворд и эксель с жуткой структурой. Тоже непонятно как тестировать. Если копировать на локальный диск, в папку проекта, так нельзя распространять файлы эти... запрещено внутренними политиками и т.п.

K>Опять интеграционный тест. Во-первых, можно сварганить тестовые данные, во-вторых, можно эмулировать их содержимое.
K>Вообще главное правило тут — юнит-тест должен тестировать _один_ метод, при этом все его зависимости должны быть сымитированы моками
Вот здесь в том то и проблема, что эмулировать эти данные раз в 5 ато и больше более трудоемко, чем сама разработка...
Re[3]: Про юнит тесты
От: Spiceman  
Дата: 06.07.09 11:58
Оценка:
Здравствуйте, Ellin, Вы писали:

E>Вот здесь в том то и проблема, что эмулировать эти данные раз в 5 ато и больше более трудоемко, чем сама разработка...


А кто сказал, что юнит-тесты это просто? В каждой задаче применим свой подход тестирования.
Re[3]: Про юнит тесты
От: Nuseraro Россия  
Дата: 06.07.09 13:16
Оценка: 3 (1)
Здравствуйте, Ellin, Вы писали:

E>Вот здесь в том то и проблема, что эмулировать эти данные раз в 5 ато и больше более трудоемко, чем сама разработка...


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

К тому же, я не уверен, что эмулировать данные так сложно: код возможно и будет больше, а вот трудоемкость едва ли. Во-первых есть библиотеки, помогающие эмулировать(тот же NMock), во-вторых выручает проектирование, особенно IoC, в-третьих выручает то, что эмулировать не обязательно программно, напротив лучше эмулировать физически: просто хранить объекты заранее сохраненными в нужных состояниях и использовать их.
Homo Guglens
Re[4]: Про юнит тесты
От: Ellin Россия www.rsdn.ru
Дата: 06.07.09 14:36
Оценка:
Здравствуйте, Nuseraro, Вы писали:

N>Здравствуйте, Ellin, Вы писали:


E>>Вот здесь в том то и проблема, что эмулировать эти данные раз в 5 ато и больше более трудоемко, чем сама разработка...


N>Это необычно, но нормально. А как собственно еще писать гарантированно работающий код? За счет уверенности в себе и метода пристального взгляда?..


N>К тому же, я не уверен, что эмулировать данные так сложно: код возможно и будет больше, а вот трудоемкость едва ли. Во-первых есть библиотеки, помогающие эмулировать(тот же NMock), во-вторых выручает проектирование, особенно IoC, в-третьих выручает то, что эмулировать не обязательно программно, напротив лучше эмулировать физически: просто хранить объекты заранее сохраненными в нужных состояниях и использовать их.

Хорошо. Например, метод возвращает список сотрудников организации. Нужно делать локальную базу данных с тестовыми записями? (ведь наша тестовая база может меняться другими программерами, другими модулями.)
Re[5]: Про юнит тесты
От: MozgC США http://nightcoder.livejournal.com
Дата: 06.07.09 14:42
Оценка: 1 (1)
Здравствуйте, Ellin, Вы писали:

E>Хорошо. Например, метод возвращает список сотрудников организации. Нужно делать локальную базу данных с тестовыми записями? (ведь наша тестовая база может меняться другими программерами, другими модулями.)


Я юнит тесты прогоняю на локальной (разработческой) БД. Она в принципе почти соответствует базе на продакшене. В некоторых сиутациях такой подход может в полне подойти. Для меня к примеру подходит.
Или можете сначала добавить данные, считать их и провериьт в тесте, а затем удалить. Можно это все в одной транзакции для простоты сделать.
Re[6]: Про юнит тесты
От: Аноним  
Дата: 06.07.09 17:48
Оценка:
Здравствуйте, MozgC, Вы писали:

MC>Здравствуйте, Ellin, Вы писали:


E>>Хорошо. Например, метод возвращает список сотрудников организации. Нужно делать локальную базу данных с тестовыми записями? (ведь наша тестовая база может меняться другими программерами, другими модулями.)


MC>Я юнит тесты прогоняю на локальной (разработческой) БД. Она в принципе почти соответствует базе на продакшене. В некоторых сиутациях такой подход может в полне подойти. Для меня к примеру подходит.

MC>Или можете сначала добавить данные, считать их и провериьт в тесте, а затем удалить. Можно это все в одной транзакции для простоты сделать.

В условиях сферического вакуума считается, что у Вас нет прямого доступа к базе — он делегируется через сущности data access layer. Соответственно, нужен мок-объект, который с помощью коллекции предопределенных данных будет эмулировать таблицу БД, и отсылка письма "превед, сатруднеги!" должна просто обратиться к некоему абстрактному сервису из data access layer, который и выплюнет необходимую коллекцию (или енумератор на неё, или еще что). Т.е. юнит-тест будет работать с мок-заглушкой, а реальное приложение — с реальной оберткой вокруг СУБД-движка.
Re[7]: Про юнит тесты
От: MozgC США http://nightcoder.livejournal.com
Дата: 06.07.09 17:52
Оценка:
Здравствуйте, Аноним, Вы писали:

А>В условиях сферического вакуума считается, что у Вас нет прямого доступа к базе — он делегируется через сущности data access layer. Соответственно, нужен мок-объект, который с помощью коллекции предопределенных данных будет эмулировать таблицу БД, и отсылка письма "превед, сатруднеги!" должна просто обратиться к некоему абстрактному сервису из data access layer, который и выплюнет необходимую коллекцию (или енумератор на неё, или еще что). Т.е. юнит-тест будет работать с мок-заглушкой, а реальное приложение — с реальной оберткой вокруг СУБД-движка.


Я привел пример когда юнит-тест тестирует именно DAL-метод.
Re[6]: Про юнит тесты
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 06.07.09 19:50
Оценка: :)
Здравствуйте, MozgC, Вы писали:

MC>Здравствуйте, Ellin, Вы писали:


E>>Хорошо. Например, метод возвращает список сотрудников организации. Нужно делать локальную базу данных с тестовыми записями? (ведь наша тестовая база может меняться другими программерами, другими модулями.)


MC>Я юнит тесты прогоняю на локальной (разработческой) БД. Она в принципе почти соответствует базе на продакшене. В некоторых сиутациях такой подход может в полне подойти. Для меня к примеру подходит.

MC>Или можете сначала добавить данные, считать их и провериьт в тесте, а затем удалить. Можно это все в одной транзакции для простоты сделать.

Только это не unit-тест, как бы тебе не хотелось обратного
Re[7]: Про юнит тесты
От: MozgC США http://nightcoder.livejournal.com
Дата: 06.07.09 20:24
Оценка:
Здравствуйте, gandjustas, Вы писали:

MC>>Я юнит тесты прогоняю на локальной (разработческой) БД. Она в принципе почти соответствует базе на продакшене. В некоторых сиутациях такой подход может в полне подойти. Для меня к примеру подходит.

MC>>Или можете сначала добавить данные, считать их и провериьт в тесте, а затем удалить. Можно это все в одной транзакции для простоты сделать.

G>Только это не unit-тест, как бы тебе не хотелось обратного


Это смотря что тестировать. Если я тестирую логику в какой-то функции, где используется БД, то да, тут можно сказать что есть зависимость от БД. Но если я тестирую DAL-метод который просто делает запрос в БД, то мне как раз нужно проверить корреткность выполнения этого запроса — и это будет именно именно unit-test соответствующего DAL-метода.
Re: Про юнит тесты
От: ppvrt  
Дата: 07.07.09 05:57
Оценка: -1
Здравствуйте, Ellin, Вы писали:

E>Оч. понравилась, конечно, идея разработки с тестами... Вот только уже давно не могу понять. Допустим есть у меня метод, который отсылает почту нескольким джентельменам, адреса которых берет из базы. Как писать тест? Не могу же я их почтовые ящики проверить. Дошло или нет.

E>Или допустим мой метод анализирует файлы по указанному пути... на выходе дает некоторую сумму. Файлы, допустим вперемешку ворд и эксель с жуткой структурой. Тоже непонятно как тестировать. Если копировать на локальный диск, в папку проекта, так нельзя распространять файлы эти... запрещено внутренними политиками и т.п.

Юнит-тесты — это глобальное зло.

Вот как можно оттестировать, отработал ли Javascript, который меняет стиль у кнопки, кладёт в hidden-поле какое-то значение?
Как можно определить, сохранилась информация в базе или insert сохранил информацию неправильно?
Как же так?

Юнит-тестирование — это всего лишь попытка эмуляции ситуаций развития событий, но никак не попытка устранить ошибки в системе.
Re[2]: Про юнит тесты
От: Tom Россия http://www.RSDN.ru
Дата: 07.07.09 06:32
Оценка: -1
P>Юнит-тесты — это глобальное зло.
Почему? Что предлагается взамен?
Народная мудрось
всем все никому ничего(с).
Re: Про юнит тесты
От: Tom Россия http://www.RSDN.ru
Дата: 07.07.09 06:34
Оценка: +1
Здравствуйте, Ellin, Вы писали:

E>Оч. понравилась, конечно, идея разработки с тестами... Вот только уже давно не могу понять. Допустим есть у меня метод, который отсылает почту нескольким джентельменам, адреса которых берет из базы. Как писать тест? Не могу же я их почтовые ящики проверить. Дошло или нет.

E>Или допустим мой метод анализирует файлы по указанному пути... на выходе дает некоторую сумму. Файлы, допустим вперемешку ворд и эксель с жуткой структурой. Тоже непонятно как тестировать. Если копировать на локальный диск, в папку проекта, так нельзя распространять файлы эти... запрещено внутренними политиками и т.п.

Посмотри на typemock.net, он позволит тебе прозрачно для твоего кода, тоесть не меняя его вообще изолировать от внешней среды.
На самом деле их решение является для рынка революционным и пока я не видел аналогов.
Народная мудрось
всем все никому ничего(с).
Re[3]: Про юнит тесты
От: ppvrt  
Дата: 07.07.09 06:48
Оценка: :))) :)
Здравствуйте, Tom, Вы писали:

P>>Юнит-тесты — это глобальное зло.

Tom>Почему?

Потому что стоимость разработки и поддержки этих юнит-тестов иногда даже больше, чем 50% стоимости проекта.

Tom>Что предлагается взамен?


Полуручное тестирование (желательно большим числом людей).
Это простое, дешевое и надёжное средство.
Re[5]: Про юнит тесты
От: Nuseraro Россия  
Дата: 07.07.09 06:57
Оценка:
Здравствуйте, Ellin, Вы писали:

E>Хорошо. Например, метод возвращает список сотрудников организации. Нужно делать локальную базу данных с тестовыми записями? (ведь наша тестовая база может меняться другими программерами, другими модулями.)


Если все, что функция делает, это возвращает список сотрудников организации(а так и должно быть), то на уровне unit-тестов я бы её не тестировал вовсе.

На уровне функциональных тестов ресторится база, и по ней бегают тесты на тот ключевой функционал, который составляет суть работы программы. Если будут проблемы с чтением из базы — функциональные тесты на этот функционал не отработают.
Homo Guglens
Re[4]: Про юнит тесты
От: Nuseraro Россия  
Дата: 07.07.09 07:00
Оценка:
Здравствуйте, ppvrt, Вы писали:

P>>>Юнит-тесты — это глобальное зло.

P>Потому что стоимость разработки и поддержки этих юнит-тестов иногда даже больше, чем 50% стоимости проекта.

Во сколько % оцените стоимость тестирования и отладки ошибок в связи с изменениями в проектах без юнит-тестов и того же качества?
Homo Guglens
Re[4]: Про юнит тесты
От: samius Япония http://sams-tricks.blogspot.com
Дата: 07.07.09 08:19
Оценка: :)
Здравствуйте, ppvrt, Вы писали:

Tom>>Что предлагается взамен?


P>Полуручное тестирование (желательно большим числом людей).

P>Это простое, дешевое и надёжное средство.

Большое число людей это просто дешево и надежно?
Не хватает еще термина "быстро"
Re[4]: Про юнит тесты
От: Tom Россия http://www.RSDN.ru
Дата: 07.07.09 08:30
Оценка: 1 (1)
P>Потому что стоимость разработки и поддержки этих юнит-тестов иногда даже больше, чем 50% стоимости проекта.
Мне кажется ты неправильно считаешь деньги. лучше посчитать какое количество денег и времени они экономят

P>Полуручное тестирование (желательно большим числом людей).

Это пять, без коментариев даже.

ЗЫ:
Вообще у нас в проекте наибольшую эффективность показали именно интеграционные тесты. Когда код не пытаются изолировать, ну или изолируют но минимально.
В юнит тестах я вообще не помню что бы мы нашли какие то баги а в интеграционных — постоянно.
Народная мудрось
всем все никому ничего(с).
Re: статейку для начинающих подкиньте
От: Аноним  
Дата: 07.07.09 08:47
Оценка: :)
про тесты, желательно попроще и попонятней — язык русский-англ.
спасибо.
Re[2]: статейку для начинающих подкиньте
От: Ellin Россия www.rsdn.ru
Дата: 07.07.09 10:24
Оценка:
Здравствуйте, Аноним, Вы писали:

А>про тесты, желательно попроще и попонятней — язык русский-англ.

А>спасибо.
Не надо мне статейку... я сам разбирусь...
Re[2]: Про юнит тесты
От: Ellin Россия www.rsdn.ru
Дата: 07.07.09 11:36
Оценка:
Здравствуйте, Tom, Вы писали:

Tom>Посмотри на typemock.net, он позволит тебе прозрачно для твоего кода, тоесть не меняя его вообще изолировать от внешней среды.

Tom>На самом деле их решение является для рынка революционным и пока я не видел аналогов.
Хорошо, посмотрю, спасибо...
А вот еще скажите в плане юнит тестирования лучше NUnit или можно обойтись штатными средствами VS Team Edition? Я так смотрю даже EntLib написана с использованием NUnit. (хотя и недочетов там есть определенное колличество.... )
Re[3]: Про юнит тесты
От: MozgC США http://nightcoder.livejournal.com
Дата: 07.07.09 11:40
Оценка:
Здравствуйте, Ellin, Вы писали:

E>А вот еще скажите в плане юнит тестирования лучше NUnit или можно обойтись штатными средствами VS Team Edition? Я так смотрю даже EntLib написана с использованием NUnit. (хотя и недочетов там есть определенное колличество.... )


Мне NUnit нравится. Он кстати очень удобно интегрируется в студию с помощью ReSharper'а.
Re[3]: статейку для начинающих подкиньте
От: Аноним  
Дата: 07.07.09 11:41
Оценка:
Здравствуйте, Ellin, Вы писали:

E>Здравствуйте, Аноним, Вы писали:


А>>про тесты, желательно попроще и попонятней — язык русский-англ.

А>>спасибо.
E>Не надо мне статейку... я сам разбирусь...
рад за вас — а вот я бы не отказался
Re[3]: Про юнит тесты
От: samius Япония http://sams-tricks.blogspot.com
Дата: 07.07.09 11:46
Оценка:
Здравствуйте, Ellin, Вы писали:

E>А вот еще скажите в плане юнит тестирования лучше NUnit или можно обойтись штатными средствами VS Team Edition? Я так смотрю даже EntLib написана с использованием NUnit. (хотя и недочетов там есть определенное колличество.... )


Только не встроенная тулза!!! Много раз пожалели что с ней связались. NUnit однозначно лучше. Но можно так же глянуть в сторону MbUnit
Re[4]: Про юнит тесты
От: Ellin Россия www.rsdn.ru
Дата: 07.07.09 11:47
Оценка:
Здравствуйте, samius, Вы писали:

S>Здравствуйте, Ellin, Вы писали:


E>>А вот еще скажите в плане юнит тестирования лучше NUnit или можно обойтись штатными средствами VS Team Edition? Я так смотрю даже EntLib написана с использованием NUnit. (хотя и недочетов там есть определенное колличество.... )


S>Только не встроенная тулза!!! Много раз пожалели что с ней связались. NUnit однозначно лучше. Но можно так же глянуть в сторону MbUnit

А почему встроенная тулза плохая? Лично я вчера никак не мог понять, почему он не перебилдевает мои сборки при прогоне тестов... т.е. тесты постоянно валились, хотя я баги исправил...
Re[4]: статейку для начинающих подкиньте
От: MozgC США http://nightcoder.livejournal.com
Дата: 07.07.09 11:49
Оценка: 9 (4)
Здравствуйте, Аноним, Вы писали:

А>>>про тесты, желательно попроще и попонятней — язык русский-англ.

А>рад за вас — а вот я бы не отказался

Если с английским все в порядке, то вот есть книжка:
Pragmatic Unit Testing with C#
Re[5]: статейку для начинающих подкиньте
От: Аноним  
Дата: 07.07.09 12:17
Оценка:
Здравствуйте, MozgC, Вы писали:
MC>Если с английским все в порядке, то вот есть книжка:
MC>Pragmatic Unit Testing with C#

спасибо.
Re[5]: Про юнит тесты
От: samius Япония http://sams-tricks.blogspot.com
Дата: 07.07.09 12:33
Оценка: 16 (2)
Здравствуйте, Ellin, Вы писали:

E>Здравствуйте, samius, Вы писали:


S>>Только не встроенная тулза!!! Много раз пожалели что с ней связались. NUnit однозначно лучше. Но можно так же глянуть в сторону MbUnit

E>А почему встроенная тулза плохая? Лично я вчера никак не мог понять, почему он не перебилдевает мои сборки при прогоне тестов... т.е. тесты постоянно валились, хотя я баги исправил...

Во-первых, встроенная тулза ОЧЕНЬ долгая. На нескольких тысячах тестов разница заметна на глаз.
Во-вторых, у встроенной тулзы большие проблемы с иерархиями тестов.
В-третьих, у встроенной тулзы возможен разный порядок выполнения тестов, оттого инициализация и деинициализация Fixture производится как-попало. Если в NUnit-е фактически есть гарантия того, что все тесты одного Fixture выполняются подряд между [FixtureSetUp] и [FixtureTearDown], то во встроенной тулзе между этими методами могут быть вызваны другие тесты от других Fixture. Фактически они гарантируют только то, что каждый тест выполнится между своими методами инициализации и деинициализации. Отсюда сложности с Arrange + Act + Assert подходом к тестированию; сложности с тем, чтобы скажем в методе инициализации FixtureSetUp открыть транзакцию, прогнать несколько тестов и потом в FixtureTearDown откатить транзакцию, потому как между открытием транзакции и закрытием могут попасть тесты из других классов, которые будут выполняться в своей транзакции.
В четвертых, встроенная тулза не производит реюз класса для сценария с несколькими тестами. Для каждого теста класс теста создается заново. Это тоже приводит к некоторым проблемам. Для того, чтобы сохранить общее для нескольких тестов состояние, приходится использовать статические переменные. Время жизни таких переменных не определено, т.к. FixtureTearDown метод вызовется когда-нибудь, а не сразу по завершению всех тестов данного класса.

Не исключаю, что я не умею правильно готовить эту тулзу, но проблем от нее видал предостаточно.
Re[6]: Про юнит тесты
От: _FRED_ Черногория
Дата: 07.07.09 12:51
Оценка:
Здравствуйте, samius, Вы писали:

S>>>Только не встроенная тулза!!! Много раз пожалели что с ней связались. NUnit однозначно лучше. Но можно так же глянуть в сторону MbUnit

E>>А почему встроенная тулза плохая? Лично я вчера никак не мог понять, почему он не перебилдевает мои сборки при прогоне тестов... т.е. тесты постоянно валились, хотя я баги исправил...

S>Во-первых, встроенная тулза ОЧЕНЬ долгая. На нескольких тысячах тестов разница заметна на глаз.


Да, есть такое западло :о)

S>Во-вторых, у встроенной тулзы большие проблемы с иерархиями тестов.


Что значит "иерархии тестов" и какие проблемы?

S>В-третьих, у встроенной тулзы возможен разный порядок выполнения тестов, …


Да, это, я так понял, by design. а разве плох сам подход, заключающийся в том, что каждый тест должен быть изолирован от других? Зачем нужно поддерживать связанность между тестами?

S>В четвертых, встроенная тулза не производит реюз класса для сценария с несколькими тестами. Для каждого теста класс теста создается заново.


Ты про работу визарда? Я тесты все руками набираю, как хочу, так и организовываю.

S>Не исключаю, что я не умею правильно готовить эту тулзу, но проблем от нее видал предостаточно.


Да я тоже не большой специалист, так, балуюсь, но — удобно. Можно посмотреть, какие строки не покрыты и другие подобные прелести чуда "из коробки" весьма вдохновляют. Конечно, оно не так заточено как NUnit, но в чём-то подкупает.
Help will always be given at Hogwarts to those who ask for it.
Re[7]: Про юнит тесты
От: Ellin Россия www.rsdn.ru
Дата: 07.07.09 13:06
Оценка:
Здравствуйте, _FRED_, Вы писали:
_FR>Да я тоже не большой специалист, так, балуюсь, но — удобно. Можно посмотреть, какие строки не покрыты и другие подобные прелести чуда "из коробки" весьма вдохновляют. Конечно, оно не так заточено как NUnit, но в чём-то подкупает.
Как это?
Re[6]: Про юнит тесты
От: Tom Россия http://www.RSDN.ru
Дата: 07.07.09 13:11
Оценка: 1 (1)
S>Во-первых, встроенная тулза ОЧЕНЬ долгая. На нескольких тысячах тестов разница заметна на глаз.
S>Во-вторых, у встроенной тулзы большие проблемы с иерархиями тестов.
А что такое иерархия тестов?

S>В-третьих, у встроенной тулзы возможен разный порядок выполнения тестов, оттого инициализация и деинициализация Fixture производится как-попало. Если в NUnit-е фактически есть гарантия того, что все тесты одного Fixture выполняются подряд между [FixtureSetUp] и [FixtureTearDown], то во встроенной тулзе между этими методами могут быть вызваны другие тесты от других Fixture.

Разный порядок выполнения — это нормально и даже плюс. Тесты по определению должны быть независимые друг от друга.

S>В четвертых, встроенная тулза не производит реюз класса для сценария с несколькими тестами. Для каждого теста класс теста создается заново.

Это не проблема, это нормально
Народная мудрось
всем все никому ничего(с).
Re[3]: Про юнит тесты
От: Tom Россия http://www.RSDN.ru
Дата: 07.07.09 13:12
Оценка:
Здравствуйте, Ellin, Вы писали:

E>Здравствуйте, Tom, Вы писали:


Tom>>Посмотри на typemock.net, он позволит тебе прозрачно для твоего кода, тоесть не меняя его вообще изолировать от внешней среды.

Tom>>На самом деле их решение является для рынка революционным и пока я не видел аналогов.
E>Хорошо, посмотрю, спасибо...
E>А вот еще скажите в плане юнит тестирования лучше NUnit или можно обойтись штатными средствами VS Team Edition? Я так смотрю даже EntLib написана с использованием NUnit. (хотя и недочетов там есть определенное колличество.... )

Лично нам (моей компании и мне лично) ничего кроме студии и typemock для работы с тестами не надо.
В принципе всё устраивает.
Народная мудрось
всем все никому ничего(с).
Re[8]: Про юнит тесты
От: Tom Россия http://www.RSDN.ru
Дата: 07.07.09 13:15
Оценка: 1 (1)
Здравствуйте, Ellin, Вы писали:

E>Здравствуйте, _FRED_, Вы писали:

_FR>>Да я тоже не большой специалист, так, балуюсь, но — удобно. Можно посмотреть, какие строки не покрыты и другие подобные прелести чуда "из коробки" весьма вдохновляют. Конечно, оно не так заточено как NUnit, но в чём-то подкупает.
E>Как это?
При выполнении тестов студия записывает какие строки кода выполнялись. Называется это code coverage. Очень удобно для того что бы понимать какой процент кода покрыт тестами, какие test case-ы надо реалитзовать итп...
Народная мудрось
всем все никому ничего(с).
Re[8]: Про юнит тесты
От: _FRED_ Черногория
Дата: 07.07.09 13:16
Оценка: 1 (1)
Здравствуйте, Ellin, Вы писали:

E>Здравствуйте, _FRED_, Вы писали:

_FR>>Да я тоже не большой специалист, так, балуюсь, но — удобно. Можно посмотреть, какие строки не покрыты и другие подобные прелести чуда "из коробки" весьма вдохновляют. Конечно, оно не так заточено как NUnit, но в чём-то подкупает.
E>Как это?

В окне Test Results правой кнопкой на тесте, выбираешь Code Coverage Results, там встаёшь на методе, правой кнопкой, Go to source code. Покажется source code, различные регионы которого закрашемы различными цветами. Легенда цветов — Tools\Options\Environment\Fonts and Colors: "Coverage Not Touched Area", "Coverage Partially Touched Area", "Coverage Touched Area".
Help will always be given at Hogwarts to those who ask for it.
Re[7]: Про юнит тесты
От: samius Япония http://sams-tricks.blogspot.com
Дата: 07.07.09 14:32
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Здравствуйте, samius, Вы писали:


S>>Во-вторых, у встроенной тулзы большие проблемы с иерархиями тестов.


_FR>Что значит "иерархии тестов" и какие проблемы?

Допустим, есть несколько реализаций некоторого интерфейса. И есть общие тесты для этих реализаций. В NUnit я могу создать базовый класс с N тестами, определить в нем виртуальный фабричный метод, создать несколько производных классов, перекрыть в них метод создания экземпляра и таким образом получу N*M тестов, где M кол-во производных классов с тестами. С vsts такой трюк не прокатывает. Приходится копипастить.


S>>В-третьих, у встроенной тулзы возможен разный порядок выполнения тестов, …


_FR>Да, это, я так понял, by design. а разве плох сам подход, заключающийся в том, что каждый тест должен быть изолирован от других? Зачем нужно поддерживать связанность между тестами?

Это немного другая связность. В методах FixtureSetUp и FixtureTearDown и их аналогах в vsts принято производить инициализацию общую для всех тестов Fixture. Беда в том, что Test1.FixtureSetUp и Test2.FixtureSetUp могут использовать общие ресурсы типа глобальных состояний, или БД (не кидайте камни, знаю что глобальные состояния зло, просто пример привел).
Так вот, допустим FixtureSetUp метод кладет что-то в БД, а FixtureTearDown производит очистку из БД. А теперь представим следующий сценарий

vsts:

F1.FixtureSetUp();
F1.Test1();
F2.FixtureSetUp();
F2.Test1();
F1.Test2(); <---- этот тест видит в БД совсем не те данные, что ждет.
F1.FixtureTearDown();
F2.FixtureTearDown();

в NUnit-е такой сценарий невозможен.

Я понимаю, всю инициализацию и деинициализацию таких тестов можно положить в SetUp и TearDown методы. Однако, когда тестов тысячи, то очень хочется сэкономить и использовать общую инициализацию, особенно в случае с БД.

S>>В четвертых, встроенная тулза не производит реюз класса для сценария с несколькими тестами. Для каждого теста класс теста создается заново.


_FR>Ты про работу визарда? Я тесты все руками набираю, как хочу, так и организовываю.


Нет, я про то, что для каждого теста во время выполнения тестов создается новый экземпляр класса теста, в то время как в NUnit-е экземпляр Fixture создается один раз.
Re[7]: Про юнит тесты
От: samius Япония http://sams-tricks.blogspot.com
Дата: 07.07.09 14:35
Оценка:
Здравствуйте, Tom, Вы писали:

S>>Во-первых, встроенная тулза ОЧЕНЬ долгая. На нескольких тысячах тестов разница заметна на глаз.

S>>Во-вторых, у встроенной тулзы большие проблемы с иерархиями тестов.
Tom>А что такое иерархия тестов?
Ответил выше

S>>В-третьих, у встроенной тулзы возможен разный порядок выполнения тестов, оттого инициализация и деинициализация Fixture производится как-попало. Если в NUnit-е фактически есть гарантия того, что все тесты одного Fixture выполняются подряд между [FixtureSetUp] и [FixtureTearDown], то во встроенной тулзе между этими методами могут быть вызваны другие тесты от других Fixture.

Tom>Разный порядок выполнения — это нормально и даже плюс. Тесты по определению должны быть независимые друг от друга.
Разный порядок — хорошо. Но вот перепутанные инициализации от разных тестов — это зло.

S>>В четвертых, встроенная тулза не производит реюз класса для сценария с несколькими тестами. Для каждого теста класс теста создается заново.

Tom>Это не проблема, это нормально

Допустим, fixture использует некоторые общие данные для нескольких тестов. Генерить их перед каждым тестом — это сказывается на времени выполнения тестов. Складывать их в статические переменные? Это не нормально.
Re[8]: Про юнит тесты
От: Tom Россия http://www.RSDN.ru
Дата: 07.07.09 15:23
Оценка:
Tom>>А что такое иерархия тестов?
S>Ответил выше
Где выше. Можно ссылку?

Tom>>Разный порядок выполнения — это нормально и даже плюс. Тесты по определению должны быть независимые друг от друга.

S>Разный порядок — хорошо. Но вот перепутанные инициализации от разных тестов — это зло.
Это как вообще?

S>>>В четвертых, встроенная тулза не производит реюз класса для сценария с несколькими тестами. Для каждого теста класс теста создается заново.

Tom>>Это не проблема, это нормально

S>Допустим, fixture использует некоторые общие данные для нескольких тестов. Генерить их перед каждым тестом — это сказывается на времени выполнения тестов. Складывать их в статические переменные? Это не нормально.

Почему это не нормально? Тоесть статические переменные — это не нормально, а один инстанс класса для нескольких тестов — это нормально?
Народная мудрось
всем все никому ничего(с).
Re[9]: Про юнит тесты
От: samius Япония http://sams-tricks.blogspot.com
Дата: 07.07.09 15:35
Оценка:
Здравствуйте, Tom, Вы писали:

Tom>>>А что такое иерархия тестов?

S>>Ответил выше
Tom>Где выше. Можно ссылку?
http://www.rsdn.ru/forum/dotnet/3459197.1.aspx
Автор: samius
Дата: 07.07.09


Tom>>>Разный порядок выполнения — это нормально и даже плюс. Тесты по определению должны быть независимые друг от друга.

S>>Разный порядок — хорошо. Но вот перепутанные инициализации от разных тестов — это зло.
Tom>Это как вообще?
По той же ссылке

S>>>>В четвертых, встроенная тулза не производит реюз класса для сценария с несколькими тестами. Для каждого теста класс теста создается заново.

Tom>>>Это не проблема, это нормально

S>>Допустим, fixture использует некоторые общие данные для нескольких тестов. Генерить их перед каждым тестом — это сказывается на времени выполнения тестов. Складывать их в статические переменные? Это не нормально.

Tom>Почему это не нормально? Тоесть статические переменные — это не нормально, а один инстанс класса для нескольких тестов — это нормально?
Один инстанс для нескольких тестов — это классика. Так работает все: NUnit, MbUnit, csUnit. лишь vsts отличилась.
Если бы методы одного теста работали вместе и сразу за ними производилась бы деинициализация fixture, то статические переменные были бы вполне ничего в этом случае. А в той ситуации, что есть — неизвестно когда наступит деинициализация потому статические переменные будут держать ссылки на данные неопределенное время. В программах, активно работающих с памятью это критично.
Допустим — требуется проверить работу алгоритма обработки снимка на реальных данных (большой снимок около 40Мб). Вчитывать его перед каждым тестов в методе SetUp (TestInitialize) не разумно. Хранить его в статической переменной — тоже, т.к. неизвестно, когда наступит FixtureTearDown/ClassCleanup или что-там. (да, это не совсем юнит тест, но можно считать это интеграционным тестом, исполненным в качестве юнит теста)
Внятного сценария работы с такими тестовыми данными для vsts я не вижу.
Re[10]: Про юнит тесты
От: Tom Россия http://www.RSDN.ru
Дата: 07.07.09 16:27
Оценка: +1
Tom>>Это как вообще?
S>По той же ссылке
Странно, никогда такой проблемы не наблюдал. Возможно это связано с многопоточностью и студия пытается использовать все имеющиеся ядра.

S>>>Допустим, fixture использует некоторые общие данные для нескольких тестов. Генерить их перед каждым тестом — это сказывается на времени выполнения тестов. Складывать их в статические переменные? Это не нормально.

Tom>>Почему это не нормально? Тоесть статические переменные — это не нормально, а один инстанс класса для нескольких тестов — это нормально?
S>Один инстанс для нескольких тестов — это классика. Так работает все: NUnit, MbUnit, csUnit. лишь vsts отличилась.
Да бред это а не классика. Тесты должны быть изолированы и точка. Любое состояние класса является нарушением изоляции. Конечно за исключением специфических случаев. Другое дело что VS могла бы и иметь атрибуты позволяющие явно задавать настройки изоляции. Мне бы например для некоторых тестов хотелось бы использовать изоляцию на уровне домена.


S>Если бы методы одного теста работали вместе и сразу за ними производилась бы деинициализация fixture, то статические переменные были бы вполне ничего в этом случае. А в той ситуации, что есть — неизвестно когда наступит деинициализация потому статические переменные будут держать ссылки на данные неопределенное время. В программах, активно работающих с памятью это критично.

Ну так не храни в состоянии столько данных. Это же тесты, я не дцумаю что пару гигов в статических переменных тут нормально.

S>Допустим — требуется проверить работу алгоритма обработки снимка на реальных данных (большой снимок около 40Мб). Вчитывать его перед каждым тестов в методе SetUp (TestInitialize) не разумно. Хранить его в статической переменной — тоже, т.к. неизвестно, когда наступит FixtureTearDown/ClassCleanup или что-там. (да, это не совсем юнит тест, но можно считать это интеграционным тестом, исполненным в качестве юнит теста)

S>Внятного сценария работы с такими тестовыми данными для vsts я не вижу.
Я думаю можно попытаться явно задавать порядок тестам, и в последнем освободить ресурсы. Можно использовать отдельную сборку и AssemblyCleanupAttribute. Можно приоритет прикрутить.
Народная мудрось
всем все никому ничего(с).
Re[11]: Про юнит тесты
От: samius Япония http://sams-tricks.blogspot.com
Дата: 07.07.09 16:49
Оценка:
Здравствуйте, Tom, Вы писали:

Tom>>>Это как вообще?

S>>По той же ссылке
Tom>Странно, никогда такой проблемы не наблюдал. Возможно это связано с многопоточностью и студия пытается использовать все имеющиеся ядра.
Нет, тесты выполняются последовательно вне зависимости от кол-ва ядер. Студия грузит несколько доменов для выполнения тестов, но они все-равно последовательно отрабатывают.

S>>Один инстанс для нескольких тестов — это классика. Так работает все: NUnit, MbUnit, csUnit. лишь vsts отличилась.

Tom>Да бред это а не классика. Тесты должны быть изолированы и точка. Любое состояние класса является нарушением изоляции. Конечно за исключением специфических случаев. Другое дело что VS могла бы и иметь атрибуты позволяющие явно задавать настройки изоляции. Мне бы например для некоторых тестов хотелось бы использовать изоляцию на уровне домена.

Тесты изолированы от тестовых данных?


S>>Если бы методы одного теста работали вместе и сразу за ними производилась бы деинициализация fixture, то статические переменные были бы вполне ничего в этом случае. А в той ситуации, что есть — неизвестно когда наступит деинициализация потому статические переменные будут держать ссылки на данные неопределенное время. В программах, активно работающих с памятью это критично.

Tom>Ну так не храни в состоянии столько данных. Это же тесты, я не дцумаю что пару гигов в статических переменных тут нормально.
Не храни — это хорошо. Грузить/создавать данные перед каждым тестом?

S>>Допустим — требуется проверить работу алгоритма обработки снимка на реальных данных (большой снимок около 40Мб). Вчитывать его перед каждым тестов в методе SetUp (TestInitialize) не разумно. Хранить его в статической переменной — тоже, т.к. неизвестно, когда наступит FixtureTearDown/ClassCleanup или что-там. (да, это не совсем юнит тест, но можно считать это интеграционным тестом, исполненным в качестве юнит теста)

S>>Внятного сценария работы с такими тестовыми данными для vsts я не вижу.

Tom>Я думаю можно попытаться явно задавать порядок тестам, и в последнем освободить ресурсы. Можно использовать отдельную сборку и AssemblyCleanupAttribute. Можно приоритет прикрутить.


Можно пытаться — это не решение на все случаи жизни. Плодить сборки на 5 тестов — тоже не выход.
А в NUnit просто нет таких проблем.
Re[5]: Про юнит тесты
От: ppvrt  
Дата: 07.07.09 19:20
Оценка:
Здравствуйте, Nuseraro, Вы писали:

P>>>>Юнит-тесты — это глобальное зло.

P>>Потому что стоимость разработки и поддержки этих юнит-тестов иногда даже больше, чем 50% стоимости проекта.

N>Во сколько % оцените стоимость тестирования и отладки ошибок в связи с изменениями в проектах без юнит-тестов и того же качества?


Примерно 4%.
Re[5]: Про юнит тесты
От: ppvrt  
Дата: 07.07.09 19:23
Оценка: -1
Здравствуйте, samius, Вы писали:

Tom>>>Что предлагается взамен?


P>>Полуручное тестирование (желательно большим числом людей).

P>>Это простое, дешевое и надёжное средство.

S>Большое число людей это просто дешево и надежно?

Да. Это просто — нажать на кнопку и посмотреть на результат. Надёжность — 100%. Так как в данном случае мы исключаем ошибки самого юнит-тестирования и программы, осуществляющей юнит-тестирование.
Re[5]: Про юнит тесты
От: ppvrt  
Дата: 07.07.09 19:27
Оценка:
Здравствуйте, Tom, Вы писали:

Tom>ЗЫ:

Tom>Вообще у нас в проекте наибольшую эффективность показали именно интеграционные тесты. Когда код не пытаются изолировать, ну или изолируют но минимально.
Tom>В юнит тестах я вообще не помню что бы мы нашли какие то баги а в интеграционных — постоянно.

Согласен. Именно на эту область и надо как-то налегать.
Однако, дальше будет только хуже. Потому что изменяется не только программный код определённой программы, но и среда окружения (выходят новые операционные системы, новые базы данных и т.д.).
Re[6]: Про юнит тесты
От: samius Япония http://sams-tricks.blogspot.com
Дата: 07.07.09 20:35
Оценка: 1 (1)
Здравствуйте, ppvrt, Вы писали:

P>Здравствуйте, samius, Вы писали:


Tom>>>>Что предлагается взамен?


P>>>Полуручное тестирование (желательно большим числом людей).

P>>>Это простое, дешевое и надёжное средство.

S>>Большое число людей это просто дешево и надежно?

P>Да. Это просто — нажать на кнопку и посмотреть на результат. Надёжность — 100%.
И чего это народ мается? Автоматизированное тестирование не дает надежности 100%, а кнопка дает! Не все еще нашли эту кнопку

Кстати, сколько раз придется потыкать в кнопку, чтобы убедиться в работоспособности вот такой функции
http://www.rsdn.ru/forum/dotnet/3299673.1.aspx
Автор: andy1618
Дата: 20.02.09
?
Да и будет ли такая экзотическая кнопка в конечном приложении?

P>Так как в данном случае мы исключаем ошибки самого юнит-тестирования и программы, осуществляющей юнит-тестирование.

Как-правило надо исключать ошибки в другом месте.
Re[3]: Про юнит тесты
От: koandrew Канада http://thingselectronic.blogspot.ca/
Дата: 07.07.09 20:59
Оценка:
Здравствуйте, Ellin, Вы писали:

E>А вот еще скажите в плане юнит тестирования лучше NUnit или можно обойтись штатными средствами VS Team Edition? Я так смотрю даже EntLib написана с использованием NUnit. (хотя и недочетов там есть определенное колличество.... )


Мы вот пользуемся MSTest — никаких проблем не обнаружено... Главное для нас его преимущество — встроенность. Ну и к ccnet он подключился без проблем...
[КУ] оккупировала армия.
Re[6]: Про юнит тесты
От: koandrew Канада http://thingselectronic.blogspot.ca/
Дата: 07.07.09 21:16
Оценка:
Здравствуйте, samius, Вы писали:

S>Не исключаю, что я не умею правильно готовить эту тулзу, но проблем от нее видал предостаточно.

Видимо таки не умеешь готовить

S>Во-первых, встроенная тулза ОЧЕНЬ долгая. На нескольких тысячах тестов разница заметна на глаз.

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

S>Во-вторых, у встроенной тулзы большие проблемы с иерархиями тестов.

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

S>В-третьих, у встроенной тулзы возможен разный порядок выполнения тестов, оттого инициализация и деинициализация Fixture производится как-попало. Если в NUnit-е фактически есть гарантия того, что все тесты одного Fixture выполняются подряд между [FixtureSetUp] и [FixtureTearDown], то во встроенной тулзе между этими методами могут быть вызваны другие тесты от других Fixture. Фактически они гарантируют только то, что каждый тест выполнится между своими методами инициализации и деинициализации. Отсюда сложности с Arrange + Act + Assert подходом к тестированию; сложности с тем, чтобы скажем в методе инициализации FixtureSetUp открыть транзакцию, прогнать несколько тестов и потом в FixtureTearDown откатить транзакцию, потому как между открытием транзакции и закрытием могут попасть тесты из других классов, которые будут выполняться в своей транзакции.

S>В четвертых, встроенная тулза не производит реюз класса для сценария с несколькими тестами. Для каждого теста класс теста создается заново. Это тоже приводит к некоторым проблемам. Для того, чтобы сохранить общее для нескольких тестов состояние, приходится использовать статические переменные. Время жизни таких переменных не определено, т.к. FixtureTearDown метод вызовется когда-нибудь, а не сразу по завершению всех тестов данного класса.

Не вполне понял, что имеется в виду, но может OrderedTest поможет...
[КУ] оккупировала армия.
Re[7]: Про юнит тесты
От: samius Япония http://sams-tricks.blogspot.com
Дата: 07.07.09 21:46
Оценка:
Здравствуйте, koandrew, Вы писали:

K>Здравствуйте, samius, Вы писали:


S>>Не исключаю, что я не умею правильно готовить эту тулзу, но проблем от нее видал предостаточно.

K>Видимо таки не умеешь готовить

Научи!

S>>Во-первых, встроенная тулза ОЧЕНЬ долгая. На нескольких тысячах тестов разница заметна на глаз.

K>Есть такое дело, но это небольшая проблема, ибо все тесты прогоняются только на билд-сервере после билда, разработчик же обычно прогоняет только часть тестов...

Это проблема существенная, особенно после того как сравнишь как быстро прогоняется часть тестов NUnit-ом и как долго MSTest-ом. Просто хотя бы потому, что NUnit гонит их по месту, а MSTest копирует в TestResult каталог со всеми зависимостями, коих бывает много.

S>>Во-вторых, у встроенной тулзы большие проблемы с иерархиями тестов.

K>Не очень понимаю, зачем это может быть нужно, но имеется поддержка иерархических списков...
Списки не решают проблемы запуска одного набора тестов для разных сущностей.
И вообще списки — отвратительная фича. Представь тысячу тестов в солюшне, они постоянно добавляются, удаляются, переименовываются и т.п. Кто будет раскладывать их по спискам и удалять из списков старые тесты? В системе контроля версий списки хранятся двоичным файлом — это вообще бред! Если более одного разработчика одновременно редактирует список, рождается такой нехилый конфликт, решать который иногда приходится через удаление списка. И еще эти списки регулярно дублируются в солюшне... Чем меньше трогаешь эти списки, тем меньше проблем.

S>>В-третьих, у встроенной тулзы возможен разный порядок выполнения тестов, оттого инициализация и деинициализация Fixture производится как-попало. Если в NUnit-е фактически есть гарантия того, что все тесты одного Fixture выполняются подряд между [FixtureSetUp] и [FixtureTearDown], то во встроенной тулзе между этими методами могут быть вызваны другие тесты от других Fixture. Фактически они гарантируют только то, что каждый тест выполнится между своими методами инициализации и деинициализации. Отсюда сложности с Arrange + Act + Assert подходом к тестированию; сложности с тем, чтобы скажем в методе инициализации FixtureSetUp открыть транзакцию, прогнать несколько тестов и потом в FixtureTearDown откатить транзакцию, потому как между открытием транзакции и закрытием могут попасть тесты из других классов, которые будут выполняться в своей транзакции.

S>>В четвертых, встроенная тулза не производит реюз класса для сценария с несколькими тестами. Для каждого теста класс теста создается заново. Это тоже приводит к некоторым проблемам. Для того, чтобы сохранить общее для нескольких тестов состояние, приходится использовать статические переменные. Время жизни таких переменных не определено, т.к. FixtureTearDown метод вызовется когда-нибудь, а не сразу по завершению всех тестов данного класса.

K>Не вполне понял, что имеется в виду, но может OrderedTest поможет...

Имеется в виду вопрос размещения общего кода инициализации/деинициализации для тестов одного Fixture, так чтобы этот код не перемешивался с кодом инициализации/деинициализации тестов другого Fixture.

Боюсь, что OrderedTest не поможет, тем более что он не исключает запуска в нем расположенных тестов из общего списка.
Re[8]: Про юнит тесты
От: koandrew Канада http://thingselectronic.blogspot.ca/
Дата: 07.07.09 22:57
Оценка:
Здравствуйте, samius, Вы писали:

S>Научи!

Ну попробую

S>Это проблема существенная, особенно после того как сравнишь как быстро прогоняется часть тестов NUnit-ом и как долго MSTest-ом. Просто хотя бы потому, что NUnit гонит их по месту, а MSTest копирует в TestResult каталог со всеми зависимостями, коих бывает много.

MSTest тоже умеет прогонять тесты "на месте", без копирования — соответствующая галочка имеется в настройках...

K>>Не очень понимаю, зачем это может быть нужно, но имеется поддержка иерархических списков...

S>Списки не решают проблемы запуска одного набора тестов для разных сущностей.
S>И вообще списки — отвратительная фича. Представь тысячу тестов в солюшне, они постоянно добавляются, удаляются, переименовываются и т.п. Кто будет раскладывать их по спискам и удалять из списков старые тесты? В системе контроля версий списки хранятся двоичным файлом — это вообще бред! Если более одного разработчика одновременно редактирует список, рождается такой нехилый конфликт, решать который иногда приходится через удаление списка. И еще эти списки регулярно дублируются в солюшне... Чем меньше трогаешь эти списки, тем меньше проблем.
Хз, может быть это и проблема, но лично я с ней не сталкивался Может быть дело в том, что у нас в команде мало разработчиков...

K>>Не вполне понял, что имеется в виду, но может OrderedTest поможет...

S>Имеется в виду вопрос размещения общего кода инициализации/деинициализации для тестов одного Fixture, так чтобы этот код не перемешивался с кодом инициализации/деинициализации тестов другого Fixture.
S>Боюсь, что OrderedTest не поможет, тем более что он не исключает запуска в нем расположенных тестов из общего списка.
У меня есть правило никогда не использовать Startup-teardown в юнит-тестах, а вместо этого всё необходимое делать в самом тесте (общий код инициализации конечно можно вынести в отдельные методы) , ибо по моему глубочайшему убеждению юнит-тест должен быть "вещью в себе" и ни коим образом не зависить от любых внешних условий (физических файлов, порядка выполнения) и не иметь никакого состояния. То, что вы говорите, может быть проблемой для интеграционных тестов, но их целесообразоно запускать только на билд-сервере — ибо они обычно выполняются долго, т.к. используют реальные БД/файлы/etc., а не их моки, как юнит-тесты...

В общем, тот подход, который я лично применяю, работает отлично на почти любом тест-фреймворке, ибо использует самый минимум его фич, но MSTest подкупает его встроенностью во все выпуски студии, начиная с Professional, а поскольку мне всё равно, то использовать какую-то внешнюю либу при наличии аналогичной встроенной считаю неразумным...
Опять же в ccnet это дело встало как влитое, благо готовые трансформации поставляются вместе с системой (ну разумеется я их немного допилил напильником под наши нужды, но изменений там самый минимум — буквально пара строчек).
[КУ] оккупировала армия.
Re[9]: Про юнит тесты
От: samius Япония http://sams-tricks.blogspot.com
Дата: 08.07.09 05:26
Оценка:
Здравствуйте, koandrew, Вы писали:

K>Здравствуйте, samius, Вы писали:


S>>Научи!

K>Ну попробую

S>>Это проблема существенная, особенно после того как сравнишь как быстро прогоняется часть тестов NUnit-ом и как долго MSTest-ом. Просто хотя бы потому, что NUnit гонит их по месту, а MSTest копирует в TestResult каталог со всеми зависимостями, коих бывает много.

K>MSTest тоже умеет прогонять тесты "на месте", без копирования — соответствующая галочка имеется в настройках...

Не попадалась на глаза такая галочка.

K>>>Не очень понимаю, зачем это может быть нужно, но имеется поддержка иерархических списков...

S>>Списки не решают проблемы запуска одного набора тестов для разных сущностей.
S>>И вообще списки — отвратительная фича. Представь тысячу тестов в солюшне, они постоянно добавляются, удаляются, переименовываются и т.п. Кто будет раскладывать их по спискам и удалять из списков старые тесты? В системе контроля версий списки хранятся двоичным файлом — это вообще бред! Если более одного разработчика одновременно редактирует список, рождается такой нехилый конфликт, решать который иногда приходится через удаление списка. И еще эти списки регулярно дублируются в солюшне... Чем меньше трогаешь эти списки, тем меньше проблем.
K>Хз, может быть это и проблема, но лично я с ней не сталкивался Может быть дело в том, что у нас в команде мало разработчиков...
У нас тоже мало разработчиков, но все равно предпочитаем эти списки не трогать. Разве что прибиваем лишние, когда они самопроизвольно размножаются.

K>У меня есть правило никогда не использовать Startup-teardown в юнит-тестах, а вместо этого всё необходимое делать в самом тесте (общий код инициализации конечно можно вынести в отдельные методы)

Вообще-то принято выносить инициализацию/деинициализацию в специальные методы SetUp/TearDown.

K>ибо по моему глубочайшему убеждению юнит-тест должен быть "вещью в себе" и ни коим образом не зависить от любых внешних условий (физических файлов, порядка выполнения) и не иметь никакого состояния.

Согласен, тем не менее, методы TestInitialize и TestCleanup в MSTest имеют слишком неопределенный порядок выполнения, чтобы ими вообще можно было пользоваться. Инициализацию и деинициализацию БД в них не положить, к сожалению.

K>То, что вы говорите, может быть проблемой для интеграционных тестов, но их целесообразоно запускать только на билд-сервере — ибо они обычно выполняются долго,

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

K>т.к. используют реальные БД/файлы/etc., а не их моки, как юнит-тесты...

Бывает что и юнит-тесты используют реальные БД. Например, юнит-тесты DAL. А бывают еще юнит-тесты мутаторов БД. Этим вообще перед каждым тестом нужна свежая копия БД с некоторой промежуточной схемой и тестовыми данными. Если не пытаться оптимизировать работу таких тестов, то это означает что каждый такой юнит-тест будет отрабатывать десятки секунд (а тестов сотни). Надеюсь, не надо объяснять, какой это дискомфорт при разработке?

K>В общем, тот подход, который я лично применяю, работает отлично на почти любом тест-фреймворке, ибо использует самый минимум его фич, но MSTest подкупает его встроенностью во все выпуски студии, начиная с Professional, а поскольку мне всё равно, то использовать какую-то внешнюю либу при наличии аналогичной встроенной считаю неразумным...

А мне не все равно. Того минимума, с которым MSTest работает без проблем, мне не хватает для комфортной повседневной работы.

K>Опять же в ccnet это дело встало как влитое, благо готовые трансформации поставляются вместе с системой (ну разумеется я их немного допилил напильником под наши нужды, но изменений там самый минимум — буквально пара строчек).

Полагаю, что c NUnit-ом у ccnet тоже все в порядке.
Re[5]: Про юнит тесты
От: Ziaw Россия  
Дата: 08.07.09 06:00
Оценка: +1
Здравствуйте, Tom, Вы писали:

Tom>Вообще у нас в проекте наибольшую эффективность показали именно интеграционные тесты. Когда код не пытаются изолировать, ну или изолируют но минимально.

Tom>В юнит тестах я вообще не помню что бы мы нашли какие то баги а в интеграционных — постоянно.

Юнит тесты не ищут баги, у них другие задачи:
1. При использовании TDD понять, что требуется от класса и помочь задизайнить сам класс
2. Обеспечить управление требованиями к модулю который они тестируют, т.о. обезопасить дальнейшие рефакторинги системы.

Непонятно как может юнит тест найти ошибку, если он неотделим от написанного кода, т.е. комитится вместе с ним и комитится зеленым. Зато он отлично находит места, когда кто-то удалил "лишний" код и изменненый модуль престал корректно обрабатывать ошибку найденную 4 года назад и давно похороненную в багтрекере.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[10]: Про юнит тесты
От: koandrew Канада http://thingselectronic.blogspot.ca/
Дата: 08.07.09 15:45
Оценка:
Здравствуйте, samius, Вы писали:

S>Не попадалась на глаза такая галочка.

Дабл-клик на *.testrunconfig -> Deployment -> Enable Deployment

S>Вообще-то принято выносить инициализацию/деинициализацию в специальные методы SetUp/TearDown.

А у меня вот не принято Может потому мне и хватает встроенного инструмента, а вам(тебе — хз как правильно) — нет

S>Согласен, тем не менее, методы TestInitialize и TestCleanup в MSTest имеют слишком неопределенный порядок выполнения, чтобы ими вообще можно было пользоваться. Инициализацию и деинициализацию БД в них не положить, к сожалению.

Для интеграционных тестов я использую создание БД с нуля из скриптов, а потом снос её по завершению. Поскольку тесты независимые, то всё проходит нормально. Может быть тут дело в том, как я пишу эти интеграционные тесты — например тест CRUD — это один тест у меня, выполняется самым первым, остальные тесты выполняются только при условии успешного выполнения CRUD, при необходимости используют CRUD-методы для создания необходимых сущностей в БД, а затем подчищают их, откатывая транзакцию либо используя внутри уже протестированные CRUD-методы.

S>Это не означает, что не следует предпринимать попыток по ускорению запуска интеграционных тестов.

Для меня лично это не проблема, потому что мне, если честно, всё равно, сколько они будут выполняться — у себя на машине разработчики их, как правило, не запускают...

S>Бывает что и юнит-тесты используют реальные БД. Например, юнит-тесты DAL. А бывают еще юнит-тесты мутаторов БД. Этим вообще перед каждым тестом нужна свежая копия БД с некоторой промежуточной схемой и тестовыми данными. Если не пытаться оптимизировать работу таких тестов, то это означает что каждый такой юнит-тест будет отрабатывать десятки секунд (а тестов сотни). Надеюсь, не надо объяснять, какой это дискомфорт при разработке?

У меня нет отдельных юнит-тестов DAL, он тестируется в составе интеграционных тестов...

S>А мне не все равно. Того минимума, с которым MSTest работает без проблем, мне не хватает для комфортной повседневной работы.

Каждому своё...

S>Полагаю, что c NUnit-ом у ccnet тоже все в порядке.

Совершенно верно.

Ещё использование встроенного фреймворка даёт мне некоторые нетехнические преимущества, но это уже тема отдельной беседы...
[КУ] оккупировала армия.
Re[11]: Про юнит тесты
От: samius Япония http://sams-tricks.blogspot.com
Дата: 08.07.09 16:07
Оценка:
Здравствуйте, koandrew, Вы писали:

K>Здравствуйте, samius, Вы писали:


S>>Не попадалась на глаза такая галочка.

K>Дабл-клик на *.testrunconfig -> Deployment -> Enable Deployment

---------------------------
Microsoft Visual Studio
---------------------------
The following error occurred:

Deployment must be enabled for the following:
1. Code Coverage
2. Remote Execution
3. Device Test Project

Please make sure there are no Device test projects, turn off Code Coverage and Remote Execution and try again.

The current operation will be aborted.
---------------------------
OK
---------------------------


S>>Вообще-то принято выносить инициализацию/деинициализацию в специальные методы SetUp/TearDown.

K>А у меня вот не принято Может потому мне и хватает встроенного инструмента, а вам(тебе — хз как правильно) — нет
Не возражаю на "ты".

S>>Согласен, тем не менее, методы TestInitialize и TestCleanup в MSTest имеют слишком неопределенный порядок выполнения, чтобы ими вообще можно было пользоваться. Инициализацию и деинициализацию БД в них не положить, к сожалению.

K>Для интеграционных тестов я использую создание БД с нуля из скриптов, а потом снос её по завершению. Поскольку тесты независимые, то всё проходит нормально. Может быть тут дело в том, как я пишу эти интеграционные тесты — например тест CRUD — это один тест у меня, выполняется самым первым, остальные тесты выполняются только при условии успешного выполнения CRUD, при необходимости используют CRUD-методы для создания необходимых сущностей в БД, а затем подчищают их, откатывая транзакцию либо используя внутри уже протестированные CRUD-методы.

Я тоже использую создание БД из скриптов. Вопрос в том, когда ее можно грохнуть, чтобы создать БД другой версии из скриптов, т.к. тестируются в том числе мутаторы.
Сейчас БД создается перед каждым тестом и удаляется после каждого теста. Не совсем так, но практически так. Вместо создания и удаления используется Attach/detach, но это все равно долго.

А вообще, не имею привычку делать checkin пока не удостоверюсь, что все тесты (например DAL) идут (чтобы скомпилировать и прогнать все интеграционные мне нужно минут 40), потому запускаю DAL тесты на своей машине. Если бы с самого начала использовал NUnit, то с созданием БД на несколько тестов не было бы проблем и все тесты пролетали бы мухой.

S>>Это не означает, что не следует предпринимать попыток по ускорению запуска интеграционных тестов.

K>Для меня лично это не проблема, потому что мне, если честно, всё равно, сколько они будут выполняться — у себя на машине разработчики их, как правило, не запускают...
Ладно интеграционные, а юнит тесты того же DAL (у меня-то они есть и с невыполненными тестами DAL я не стану делать checkout, который требуется чтобы прогнать интеграционные).

S>>А мне не все равно. Того минимума, с которым MSTest работает без проблем, мне не хватает для комфортной повседневной работы.

K>Каждому своё...
Точно. Имея под рукой инструмент, ограничивать себя в его использовании — это не для всех.

K>Ещё использование встроенного фреймворка даёт мне некоторые нетехнические преимущества, но это уже тема отдельной беседы...

психологические?
Re[12]: Про юнит тесты
От: koandrew Канада http://thingselectronic.blogspot.ca/
Дата: 08.07.09 17:32
Оценка:
Здравствуйте, samius, Вы писали:

S>

---------------------------
S>Microsoft Visual Studio
S>---------------------------
S>The following error occurred:

S>Deployment must be enabled for the following:
S> 1. Code Coverage
S> 2. Remote Execution
S> 3. Device Test Project

S>Please make sure there are no Device test projects, turn off Code Coverage and Remote Execution and try again.

S>The current operation will be aborted.
S>---------------------------
S>OK
S>---------------------------

Угу, но поскольку у меня стоит Professional, то покрытия нема всё равно =) Хотя и копированием честно говоря проблем особых не вижу, ибо время копирования исчезающе мало по сравнению с временем прогона тестов при более-менее плотном покрытии кода тестами...

S>Не возражаю на "ты".

Ок, принято.

S>Я тоже использую создание БД из скриптов. Вопрос в том, когда ее можно грохнуть, чтобы создать БД другой версии из скриптов, т.к. тестируются в том числе мутаторы.

S>Сейчас БД создается перед каждым тестом и удаляется после каждого теста. Не совсем так, но практически так. Вместо создания и удаления используется Attach/detach, но это все равно долго.
Ну хз — у меня имеется пустая база, на которую я и накатываю скрипты при старте, и сношу все объекты по окончании. Работает конечно не слишком шустро, но вполне терпимо. Аттач/детач тоже пробовал, но уж очень медленно как-то оно...

S>А вообще, не имею привычку делать checkin пока не удостоверюсь, что все тесты (например DAL) идут (чтобы скомпилировать и прогнать все интеграционные мне нужно минут 40), потому запускаю DAL тесты на своей машине. Если бы с самого начала использовал NUnit, то с созданием БД на несколько тестов не было бы проблем и все тесты пролетали бы мухой.

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

S>Ладно интеграционные, а юнит тесты того же DAL (у меня-то они есть и с невыполненными тестами DAL я не стану делать checkout, который требуется чтобы прогнать интеграционные).

Ну хз — я решил от тестов DAL отказаться, ибо необходимость их на нашем проекте весьма неочевидна ввиду того, что сама по себе БД изменяется довольно редко. Кстати изменение БД — это один из случаев, когда я прогоняю все тесты (в т.ч. интеграционные) у себя локально, ибо это тоже в принципе рефакторинг, и всё вышесказанное про него применимо и здесь.

S>Точно. Имея под рукой инструмент, ограничивать себя в его использовании — это не для всех.

В том-то и дело, что "под рукой" у меня MSTest , а nUnit ещё устанавливать надо...

S>психологические?

Нет, организационные. Дело в том, что мы часто отдаём части системы на аутсорсинг, и среди аутсорсеров попадаются товарищи с очень разной квалицикацией. Верите или нет, то иногда приходится объяснять человеку, как скомпилить приложение, если оно после взятия из SVN'а почему-то ругается на отсутствующие зависимости. С учётом этого вводить ещё одну в общем-то ненужную зависимость мы считаем неразумным...
[КУ] оккупировала армия.
Re[13]: Про юнит тесты
От: samius Япония http://sams-tricks.blogspot.com
Дата: 08.07.09 18:02
Оценка:
Здравствуйте, koandrew, Вы писали:

K>Здравствуйте, samius, Вы писали:


S>>

S>>The following error occurred:

S>>Deployment must be enabled for the following:
S>> 1. Code Coverage

K>Угу, но поскольку у меня стоит Professional, то покрытия нема всё равно =) Хотя и копированием честно говоря проблем особых не вижу, ибо время копирования исчезающе мало по сравнению с временем прогона тестов при более-менее плотном покрытии кода тестами...
случалось до 20 секунд вместе с инструментированием под покрытие кода. Использую TestDriven.NET для быстрого запуска. Но он не всегда справляется. Deployment, например, игнорирует.

Кстати, о покрытии. Если бы его можно было включать/выключать одним кликом, то было бы проще. Чаще всего оно включено, потому подтормаживает выполнение тестов.

S>>Сейчас БД создается перед каждым тестом и удаляется после каждого теста. Не совсем так, но практически так. Вместо создания и удаления используется Attach/detach, но это все равно долго.

K>Ну хз — у меня имеется пустая база, на которую я и накатываю скрипты при старте, и сношу все объекты по окончании. Работает конечно не слишком шустро, но вполне терпимо. Аттач/детач тоже пробовал, но уж очень медленно как-то оно...

В моем случае аттач много быстрее, чем создать БД со всеми таблицами, ключами и т.п.

K>Ну хз — я решил от тестов DAL отказаться, ибо необходимость их на нашем проекте весьма неочевидна ввиду того, что сама по себе БД изменяется довольно редко. Кстати изменение БД — это один из случаев, когда я прогоняю все тесты (в т.ч. интеграционные) у себя локально, ибо это тоже в принципе рефакторинг, и всё вышесказанное про него применимо и здесь.

А у нас БД переживает стадию бурного развития. К тому же, как это пошло ни звучит, закладываем возможность использования нескольких СУБД. Потому и актуально написание теста один раз и выполнения его для разных DAL реализаций.

S>>Точно. Имея под рукой инструмент, ограничивать себя в его использовании — это не для всех.

K>В том-то и дело, что "под рукой" у меня MSTest , а nUnit ещё устанавливать надо...
Если бы его еще и ломать приходилось бы, то тогда конечно

S>>психологические?

K>Нет, организационные. Дело в том, что мы часто отдаём части системы на аутсорсинг, и среди аутсорсеров попадаются товарищи с очень разной квалицикацией. Верите или нет, то иногда приходится объяснять человеку, как скомпилить приложение, если оно после взятия из SVN'а почему-то ругается на отсутствующие зависимости. С учётом этого вводить ещё одну в общем-то ненужную зависимость мы считаем неразумным...

У меня устойчивое ощущение что NUnit гораздо более широко распространен, чем MSTest, просто даже из-за своей доступности. И даже Microsoft NUnit-ом не брезгует. Статистики, конечно нет.

Еще один аргумент в пользу NUnit: он до сих пор развивается, обрастает удобными фичами и синтаксисом, атрибутами, констрейнтами, extension-ами... А MSTest фактически застрял в том виде, в котором был выпущен в 2005-м (уже тогда он уступал NUnit-у в плане возможностей). И даже косяки со списками не исправили к очередному выпуску студии.

Повелись вот на его встроенность, все не можем решиться перейти на NUnit (может потребоваться несколько дней для разруливания ситуаций, где не обойтись Search&Replace-ом).
Re[14]: Про юнит тесты
От: koandrew Канада http://thingselectronic.blogspot.ca/
Дата: 08.07.09 18:40
Оценка:
Здравствуйте, samius, Вы писали:


S>Кстати, о покрытии. Если бы его можно было включать/выключать одним кликом, то было бы проще. Чаще всего оно включено, потому подтормаживает выполнение тестов.

Поставь Pro — и не будет никакого покрытия

S>В моем случае аттач много быстрее, чем создать БД со всеми таблицами, ключами и т.п.


S>А у нас БД переживает стадию бурного развития. К тому же, как это пошло ни звучит, закладываем возможность использования нескольких СУБД. Потому и актуально написание теста один раз и выполнения его для разных DAL реализаций.

Так это можно покрыть интеграционными тестами. Ибо по-любому сетап-тирдаун будет разным для разных БД, и тесты придётся пилить напильником под каждую конкретную БД

S>У меня устойчивое ощущение что NUnit гораздо более широко распространен, чем MSTest, просто даже из-за своей доступности. И даже Microsoft NUnit-ом не брезгует. Статистики, конечно нет.

Ну так уж выходит, что у нас в компании я являюсь основным евангелистом автоматического тестирования, потому остальные вообще не имеют своего мнения на тему nUnit vs MSTest А своё мнение я уже высказал.

S>Еще один аргумент в пользу NUnit: он до сих пор развивается, обрастает удобными фичами и синтаксисом, атрибутами, констрейнтами, extension-ами... А MSTest фактически застрял в том виде, в котором был выпущен в 2005-м (уже тогда он уступал NUnit-у в плане возможностей). И даже косяки со списками не исправили к очередному выпуску студии.

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

S>Повелись вот на его встроенность, все не можем решиться перейти на NUnit (может потребоваться несколько дней для разруливания ситуаций, где не обойтись Search&Replace-ом).

Значит, не очень-то и надо Было бы действительно надо — давно перешли бы. Или у вас тесты считаются чем-то необязательным, только отнимающим время?
[КУ] оккупировала армия.
Re[15]: Про юнит тесты
От: samius Япония http://sams-tricks.blogspot.com
Дата: 09.07.09 00:16
Оценка:
Здравствуйте, koandrew, Вы писали:

K>Здравствуйте, samius, Вы писали:


S>>Кстати, о покрытии. Если бы его можно было включать/выключать одним кликом, то было бы проще. Чаще всего оно включено, потому подтормаживает выполнение тестов.

K>Поставь Pro — и не будет никакого покрытия

Ну почему же, можно и NCover прикрутить бесплатную версию.

S>>А у нас БД переживает стадию бурного развития. К тому же, как это пошло ни звучит, закладываем возможность использования нескольких СУБД. Потому и актуально написание теста один раз и выполнения его для разных DAL реализаций.

K>Так это можно покрыть интеграционными тестами. Ибо по-любому сетап-тирдаун будет разным для разных БД, и тесты придётся пилить напильником под каждую конкретную БД

В том-то и дело, что тесты одинаковые, а разные только инициализация движка. В NUnit-е это можно сделать прозрачно за счет наследования методов тестов, а в MSTest приходится копипастить методы тестов, т.к. он не подбирает методы из базового Fixture!

S>>Повелись вот на его встроенность, все не можем решиться перейти на NUnit (может потребоваться несколько дней для разруливания ситуаций, где не обойтись Search&Replace-ом).

K>Значит, не очень-то и надо Было бы действительно надо — давно перешли бы. Или у вас тесты считаются чем-то необязательным, только отнимающим время?
Кое-кто в команде так считает, но основная причина — есть другие приоритеты.
Re[16]: Про юнит тесты
От: Lloyd Россия  
Дата: 09.07.09 00:20
Оценка:
Здравствуйте, samius, Вы писали:

S>В том-то и дело, что тесты одинаковые, а разные только инициализация движка. В NUnit-е это можно сделать прозрачно за счет наследования методов тестов, а в MSTest приходится копипастить методы тестов, т.к. он не подбирает методы из базового Fixture!


Если речь идет о TestInitialize-нутых методах, то MSTest все прекрасно "подбирает".
Re[17]: Про юнит тесты
От: samius Япония http://sams-tricks.blogspot.com
Дата: 09.07.09 00:28
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Здравствуйте, samius, Вы писали:


S>>В том-то и дело, что тесты одинаковые, а разные только инициализация движка. В NUnit-е это можно сделать прозрачно за счет наследования методов тестов, а в MSTest приходится копипастить методы тестов, т.к. он не подбирает методы из базового Fixture!


L>Если речь идет о TestInitialize-нутых методах, то MSTest все прекрасно "подбирает".

не совсем. Он не подбирает ClassInitialize методы из базового класса, определенном в другой сборке.

А вообще, меня интересует такой сценарий:

BaseFixture::Test1()
BaseFixture::Test2()
abstract BaseFixture::Initialize()

AFixture::Initialize()
BFixture::Initialize()
...

И мы автоматом получаем 2*{число производных классов} тестов. Потом просто дописываем BaseFixture::Test3 и Test3 умножается на число производных Fixture.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.