Re: Как поймать тестами такой баг?
От: TarasCo  
Дата: 01.03.10 19:21
Оценка:
Чисто в теории, наверное надо использовать mock объекты, в частности для CustshipmentsAccessor. А дальше писать тест-кейс, в котором изобразить что-то вроде:

EXPECT_CALL( SetShipmentPricesForCustomer )

Но это в теории все прекрасно, а как написать нормальные тесты с mock объектами — я не знаю. Хотя опять же в теории тест-кейсы с мок-объекатми должны также прекрасно документировать код. Типа посмотрел на кейс и сразу виден весь алгоритм. Но это видимо сродни искусству....
Да пребудет с тобою сила
Re: Как поймать тестами такой баг?
От: Aikin Беларусь kavaleu.ru
Дата: 27.05.10 15:28
Оценка:
Здравствуйте, MozgC, Вы писали:

Оставлю свое мнение по вопросу, вдруг кому-то пригодится.
Первое что хочу сказать: не стоит пытаться обезопасится от таких ошибок с помощью тестирования. Придется написать тонны тестов, из которых хорошо если один стрельнет (а как извесно, хороший тест -- это тест который повалился).

Что же можно сделать чтобы уберечь себя от подобных ошибок? ИМХО, проектировать удобный "error free" интерфейс.

У меня есть 3 предложения по улучшению этого интерфейса:
1) ForAllCustomers и ForCustomer вынести в начало названия.
Получим ForAllCustomersSetShipmentPrices и ForCustomerSetShipmentPrices. Ошибиться стало намного сложнее.
Для пущего удобства чтения можно добваить подчеркивание: ForAllCustomers_SetShipmentPrices и ForCustomer_SetShipmentPrices (и шлите в лес всех кто говорит, что подчеркивчания "некошерны". ИМХО, кошерно все что удобно. Тут подчеркивание удобно).
Как бонус получаем разделение методов на две группы в автодополнении. (это, кстати, наведет вас на мысль, что класс играет две роли: работа с одним кастомером и со всем кастомерам, а оттуда недалеко до двух классов)


Не совсем понимаю как получается, что SetShipmentPricesForCustomer не получает параметром конкретного кастомера. Возможно, он передается из CustomerAccessor через какой-то контекст.
2) Можно передавать кастомера параметром в метод. Тогда SetShipmentPricesForAllCustomers банально не скомпилируется.
3) Можно проверять наличие кастомера в контексте из SetShipmentPricesForAllCustomers. И если он там есть выкидывать исключение (с пояснением что как и почему).


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


СУВ, Aikin
... << RSDN@Home 1.2.0 alpha 4 rev. 1466>>
Re[2]: Как поймать тестами такой баг?
От: MozgC США http://nightcoder.livejournal.com
Дата: 27.05.10 16:36
Оценка:
Здравствуйте, Aikin, Вы писали:

A>1) ForAllCustomers и ForCustomer вынести в начало названия.

Я уже типа того и сделал, только еще больше переименовал

A>Не совсем понимаю как получается, что SetShipmentPricesForCustomer не получает параметром конкретного кастомера. Возможно, он передается из CustomerAccessor через какой-то контекст.

A>2) Можно передавать кастомера параметром в метод. Тогда SetShipmentPricesForAllCustomers банально не скомпилируется.
Одна функция принимает первым параметром int customerID, а другая int countryID =) Поэтому так и вышло
Re[3]: Как поймать тестами такой баг?
От: Аноним  
Дата: 27.05.10 16:57
Оценка:
Здравствуйте, MozgC, Вы писали:

A>>2) Можно передавать кастомера параметром в метод. Тогда SetShipmentPricesForAllCustomers банально не скомпилируется.

MC>Одна функция принимает первым параметром int customerID, а другая int countryID =) Поэтому так и вышло
Недавно, кстати, AndrewK писал о типизированных Id.
Т.е. вместо int CountryId пишем Key<Country>, мне понравилось, начал использовать у себя
Re[3]: Как поймать тестами такой баг?
От: Aikin Беларусь kavaleu.ru
Дата: 27.05.10 17:33
Оценка:
Здравствуйте, MozgC, Вы писали:

A>>Не совсем понимаю как получается, что SetShipmentPricesForCustomer не получает параметром конкретного кастомера. Возможно, он передается из CustomerAccessor через какой-то контекст.

A>>2) Можно передавать кастомера параметром в метод. Тогда SetShipmentPricesForAllCustomers банально не скомпилируется.
MC>Одна функция принимает первым параметром int customerID, а другая int countryID =) Поэтому так и вышло
Теперь понятно. Опять проблема интерфейса.
Надо узнать что же предлагал AndrewK, а то у меня кроме экстеншен метода для int (id.of<Customer>()) и new Customer(id) ничего в голову не приходит.

СУВ, Aikin
... << RSDN@Home 1.2.0 alpha 4 rev. 1466>>
Re[4]: Как поймать тестами такой баг?
От: Aikin Беларусь kavaleu.ru
Дата: 27.05.10 17:33
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Недавно, кстати, AndrewK писал о типизированных Id.

А>Т.е. вместо int CountryId пишем Key<Country>, мне понравилось, начал использовать у себя
А можно пример? А еще лучше ссылку?

СУВ, Aikin
... << RSDN@Home 1.2.0 alpha 4 rev. 1466>>
Re[5]: Как поймать тестами такой баг?
От: MozgC США http://nightcoder.livejournal.com
Дата: 27.05.10 17:50
Оценка:
Здравствуйте, Aikin, Вы писали:

А>>Недавно, кстати, AndrewK писал о типизированных Id.

А>>Т.е. вместо int CountryId пишем Key<Country>, мне понравилось, начал использовать у себя
A>А можно пример? А еще лучше ссылку?

Трактат о ключевых полях
Автор: IT
Дата: 09.02.10
Re[6]: Как поймать тестами такой баг?
От: Aikin Беларусь kavaleu.ru
Дата: 27.05.10 18:14
Оценка:
Здравствуйте, MozgC, Вы писали:

MC>Трактат о ключевых полях
Автор: IT
Дата: 09.02.10

Угу, об этом я знаю. Еще МакКоннел в совершенном коде писал. Вот только совсем не затронут более важный вопрос: как удобно создать этот ключ.
Мест где нужно передать ключ намного больше чем мест где ключ объявлен. Поэтому нужно думать о юзабилити создания ключа из int'а, а не о том как же удобно описать сам ключ.
Я до сих пор использовал new Customer(id) в случаях когда нужна типизация.

СУВ, Aikin
... << RSDN@Home 1.2.0 alpha 4 rev. 1466>>
Re[3]: Как поймать тестами такой баг?
От: Head Ache  
Дата: 30.09.10 03:36
Оценка:
Здравствуйте, MozgC, Вы писали:

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


fk0>> НАДО ДАВАТЬ ФУНКЦИЯМ НОРМАЛЬНЫЕ ИМЕНА. ЧИИИИТААААЕЕЕМЫЫЫЫЕЕЕЕЕ! А не блаблабла в пол-экрана шириной.


MC>Понимаете, в чем дело, щас не старинные экраны в которые по 60 символов влезает, а широкоформатные мониторы, к тому же современные IDE избавляют от необходимости полностью имена классов и методов печатать. Зато если я сам посмотрю на свой код через год — у меня не возникнет вопросов "а что делает этот метод?" — это ясно из названия. То же самое если в проект придет новый человек — ему будет проще понять что делает конкретный класс или метод просто по одному названию.


В чем проблема-то?

Customer.SetPrice
AllCustomers.SetPrice
Этот аккаунт покинут.
Re[3]: Как поймать тестами такой баг?
От: Аноним  
Дата: 30.09.10 06:23
Оценка: +1
Здравствуйте, MozgC, Вы писали:

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


fk0>> НАДО ДАВАТЬ ФУНКЦИЯМ НОРМАЛЬНЫЕ ИМЕНА. ЧИИИИТААААЕЕЕМЫЫЫЫЕЕЕЕЕ! А не блаблабла в пол-экрана шириной.


MC>Понимаете, в чем дело, щас не старинные экраны в которые по 60 символов влезает, а широкоформатные мониторы, к тому же современные IDE избавляют от необходимости полностью имена классов и методов печатать. Зато если я сам посмотрю на свой код через год — у меня не возникнет вопросов "а что делает этот метод?" — это ясно из названия. То же самое если в проект придет новый человек — ему будет проще понять что делает конкретный класс или метод просто по одному названию.


И что, теперь моск тоже со скоростью видеокарты работает

От перепутывания и опечаток не спасут и короткие имена.
Попробуйте не перепутать i и j в каком-нибудь алгоритме сортировки.
Re[5]: Как поймать тестами такой баг?
От: Воронков Василий Россия  
Дата: 15.10.10 13:41
Оценка: 1 (1)
Здравствуйте, MozgC, Вы писали:

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

fk0>>Не, я конечно тоже против 6-буквенных имён, но есть две крайности...
MC>Т.е. по вашему SetCustomerShipmentPrices() — это крайность?

А ты как сам печатаешь подобные названия? Вручную или через автокомплит? ИМХО длинность названия как раз и провоцирует пользоваться автокомплитом, а он как раз создает благодатную почву для таких ошибок.
Re[6]: Как поймать тестами такой баг?
От: Aikin Беларусь kavaleu.ru
Дата: 18.10.10 12:21
Оценка:
Здравствуйте, Воронков Василий, Вы писали:

ВВ>А ты как сам печатаешь подобные названия? Вручную или через автокомплит? ИМХО длинность названия как раз и провоцирует пользоваться автокомплитом, а он как раз создает благодатную почву для таких ошибок.

код чаще читают, чем пишут

Стив МакКонел. Совершенный код


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

СУВ, Aikin
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
Re: Как поймать тестами такой баг?
От: AlexVinS Россия  
Дата: 20.10.10 12:30
Оценка:
Здравствуйте, MozgC, Вы писали:


MC>Но вопрос в том — как лучше тестировать чтобы такая ошибка обнаружилась. Ведь если для каждой функции писать кучу тестов и код, который проверяет как изменилось состояние БД (не затронулись ли другие строки и таблицы), то с ума можно сойти (я все-таки не маньяк-тестировщик, тесты в основном пишу только на наиболее критичные для бизнеса, либо сложные функции). Можно ли как-то проще?


первое что пришло на ум

1) Ослабить связь между слоями логики и доступа к данным, так чтобы ко всем XXXAccessor можно было MOK-объекты сделать. (можно и на слой ниже)
2) дальше само собой получится, что CustshipmentsAccessor.SetShipmentPricesForCustomer будет ожидаемым вызовом в тесте
3) НО это не спасет от случая когда 2 раза и в коде и в тесте будет вызов не того метода.


Умный человек знает не многое, но нужное
Re: Как поймать тестами такой баг?
От: Mr.Delphist  
Дата: 13.12.10 15:12
Оценка:
Здравствуйте, MozgC, Вы писали:

Для себя выработал правило: не должно быть в интерфейсе имен вида
  1. CommonName
  2. CommonNameExtra

Допустимы только непустые суффиксы:
  1. CommonNameOne
  2. CommonNameTwo
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.