|
13.03.2017, 19:45 | #1 |
Участник
|
Как правильно выполнять unit-тестирования методов с параметрами по умолчанию на ваш взгляд?
А не побухтеть ли нам, уважаемые кроты?
Предположим, есть метод с кучей параметров по умолчанию. (см. скриншот) Для определенности возьмем, класс PriceDisc, метод findDisc. (Кстати, для этого метода мс таки и не написал unit test. И это хорошо для обсуждения) Предположим вам нужно написать unit test для этого метода. (да, я сознательно поставил задачу именно так. Если пойдете в сторону модификации формулировки, напишите что вам не нравится в этой формулировке задачи и как бы вы предложили сформулировать задачу) Как бы вы написали такой unit test? Какую стратегию вы считаете правильной для тестирования методов с параметрами по умолчанию? Почему? Какие статьи/книги/ссылки вы считаете релевантными по данной теме? Почему? X++: boolean findDisc(PriceType _relation, InventDimId _inventDimId, TableGroupAll _itemCode = 0, ItemId _itemRel = '', TableGroupAll _accountCode = 0, CustVendAC _accountRel = '', UnitOfMeasureSymbol _unitID = '', Qty _quantityAmount = 0, // <GEERU> CurrencyCode _currency = CompanyInfo::standardCurrency(), AgreementHeaderExtRecId_RU _agreementHeaderExtRecId = 0, CustVendAC _agreementPartnerCode = '') // </GEERU> { PriceDiscTable priceDiscTable; boolean discExist; container key; container cacheValue; int i; FromDate localFromDate; ToDate localToDate; AmountQty localQuantityAmountFrom; AmountQuantityTo localQuantityAmountTo; RecId localRecid; boolean cacheMode; |
|
|
За это сообщение автора поблагодарили: gl00mie (2), Raven Melancholic (2). |
13.03.2017, 22:27 | #2 |
Участник
|
А с какой целью мы это делаем ? Академический там интерес или просто code coverage набрать чтобы зачекинить или еще чего..
|
|
13.03.2017, 23:08 | #3 |
Участник
|
Цитата:
я постарался сформулировать максимально равноудаленно от возможных реальных целей - просто "надо". понимаю, что в зависимости от цели и правильно будет разным. поэтому ожидаю, что высказывающиеся расскажут не только о приемах правильного unit-тестирования, но и о том какие цели удовлетворяются при том или ином приеме. но надеюсь в возможном холиваре выяснить - а может существуют общие паттерны-приемы, которые будут работать при любой цели и при любом подходе. обобщить, так сказать. поэтому и спрашиваю. |
|
13.03.2017, 23:04 | #4 |
Banned
|
Если уж побухтеть, то не unit test для это писать нужно, а делать реинжиниринг AgreementHeaderExt_RU. Уродливая денормализованная таблица, нарушающая модель данных DirParty, да еще "умело" встроенная в общий метод findDisc так, чтобы функциональность было невозможно использовать где бы то ни было, кроме территорий субъектов и вассалов Российской Федерации.
|
|
13.03.2017, 23:13 | #5 |
Участник
|
Цитата:
но... честно, я совершенно не думал об этом, когда задавал вопрос. пока хотелось бы сосредоточиться именно на unit-тестировании, а не на реинжиниринге. готов рассматривать любой другой класс и метод с кучей параметров с дефолтными значениями. для аксапты и для x++ много параметров по умолчанию - это сложившаяся и широко применяющяся практика. |
|
13.03.2017, 23:34 | #6 |
Участник
|
Мне не особо понятно зачем были выделены "параметры по умолчанию" на самом деле от их наличия или отсутствия решение задачи не изменится.
Этот метод я бы вообще не тестировал потому что нам не известно, что он должен делать т.е. глядя на него мы можем догадаться но мы не знаем всех сценариев его использования поэтому покрыть мы их не можем и не хотим. Я думаю этот разговор имеет смысл только в контексте ISV где у вас есть требования к коду и вы можете покрыть каждый сценарий позитивными и негативными тестами. |
|
13.03.2017, 23:45 | #7 |
Участник
|
Цитата:
кроме того, приемов unit-тестов в части "параметров по умолчанию" нельзя просто так перенести с c# в аксапту - нужно допиливать. вопрос - что? и как? ))) понятно, что тем про unit-тестирование больше. с удовольствием послушаю и вообще о приемах. Цитата:
я специально выбрал аксаптовский метод. очень давнишний метод. очень активно использующийся в аксапте метод. и, как правильно заметил, EVGL "метод со странностями", которые появились в результате исторического развития. ))) Цитата:
разве для других правильные приемы unit-тестирования не актуальны? да, понятно, что мало кто будет покрывать тестами стандартную функциональность. но я специально постарался выбрать для примера хорошо известный аксаптовский метод, чтобы не нужно было вводить сценарии и спецификации. я надеюсь, что даже самые начинающие аксапта-программисты в курсе как работают методы поиска цены и скидки. Последний раз редактировалось mazzy; 13.03.2017 в 23:56. |
|
14.03.2017, 00:25 | #8 |
Участник
|
Цитата:
ISV я предложил потому что там мы чаще знаем что мы делаем и зачем и что мы хотим из этого покрыть тестами. Последний раз редактировалось skuull; 14.03.2017 в 00:39. |
|
|
За это сообщение автора поблагодарили: EVGL (1). |
14.03.2017, 01:02 | #9 |
Участник
|
|
|
14.03.2017, 01:14 | #10 |
Microsoft Dynamics
|
Просветите, а что не так с этими параметрами, у которых есть значения заданные по умолчанию? Unit-test для таких методов как-то должен существенно отличаться от методов с параметрами, у которых нет значений по умолчанию?
Первая страница гугла не дала мне внятной информации по этому поводу. |
|
14.03.2017, 07:22 | #11 |
Участник
|
Цитата:
ожидается результат - зеленое состояние в панели запуска тестов. А какие варианты бывают еще? 2. ))))) Цитата:
Сообщение от AlexSD
Просветите, а что не так с этими параметрами, у которых есть значения заданные по умолчанию? Unit-test для таких методов как-то должен существенно отличаться от методов с параметрами, у которых нет значений по умолчанию?
Первая страница гугла не дала мне внятной информации по этому поводу. Поэтому такая тема для бухтения и была выбрана. повторюсь, что с удовольствием послушаю и общие аспекты. |
|
|
За это сообщение автора поблагодарили: Ace of Database (1). |
14.03.2017, 07:39 | #12 |
Участник
|
Цитата:
например, сколько тестирующих методов должно быть для метода с дефолтными параметрами? = один тестирующий с несколькими ассертами? = столько тестирующих, сколько различных комбинаций параметров для того, чтобы покрыть все значимые комбинации параметров? причем в каждом тестирующем методе должен быть только один ассерт? = какое-то "достаточное" число test-методов? каков критерий достаточности? если тестирующий метод один, в котором тестируемый метод вызывается в цикле, то существует ли какой-нибудь общепринятный прием для генерации всех значимых для теста комбинаций параметров или надо явно задавать и все входящие, и все ожидаемые значения? в методе, который я привел в первом сообщении этой ветки, 8 параметров, для которых существенно "нулевое" значение в них или "ненулевое". создавать руками 2^8 = 256 тестирующих методов? нет? а каков критерий что "вот столько" достаточно? X++: boolean findDisc(PriceType _relation, InventDimId _inventDimId, TableGroupAll _itemCode = 0, ItemId _itemRel = '', TableGroupAll _accountCode = 0, CustVendAC _accountRel = '', UnitOfMeasureSymbol _unitID = '', Qty _quantityAmount = 0, // <GEERU> CurrencyCode _currency = CompanyInfo::standardCurrency(), AgreementHeaderExtRecId_RU _agreementHeaderExtRecId = 0, CustVendAC _agreementPartnerCode = '') // </GEERU> { Последний раз редактировалось mazzy; 14.03.2017 в 07:42. |
|
14.03.2017, 08:13 | #13 |
Участник
|
Выбор количества тестов зависит от количества доступных люде-ресурсов. Тестировать можно бесконечно. Тут надо спросить - а какой уровень качества будет достаточен для вашего клиента? Если они будут всегда использовать один флоу, вызывая этот метод с параметрами по-умолчанию, имеет ли смысл лично вам тестировать все остальные комбинации?
Что до собственно самого подхода к выбору комбинаций для тестирования - почитай про Pairwise testing. Вот, к примеру, статья. http://software-testing.ru/library/t...s/1304-pairing В VS есть различные адд-оны и встроенные инструменты для поддержки такого рода тестирования. У себя в МС мы тоже пару раз писали "фреймворки" для удобства использования в попарном тестировании именно для Х++ |
|
|
За это сообщение автора поблагодарили: mazzy (2), Ace of Database (2), Slava Chernenko (1). |
14.03.2017, 08:25 | #14 |
Участник
|
Цитата:
Цитата:
там разные подходы и приемы. а какой правильный? ссылку обязательно прочитаю. спасибо. |
|
14.03.2017, 08:40 | #15 |
Участник
|
Цитата:
Сообщение от kashperuk
Что до собственно самого подхода к выбору комбинаций для тестирования - почитай про Pairwise testing. Вот, к примеру, статья.
http://software-testing.ru/library/t...s/1304-pairing задача "протестировать все значимые комбинации параметров" сводится к задаче "протестировать разные значения пар" а минимизация случаев делается за счет явного перечисления "use case'ов" предположим. а как он может сработать на приведенном примере? да, _agreement можно отделить. тогда остается 2^6 = 64 варианта. причем все из них примерно равнозначные (разве что ненулевой itemCode чуть более вероятен, чем остальные) и как применять? |
|
14.03.2017, 09:37 | #16 |
Moderator
|
Вообще - немного странно что ты решил здесь этот вопрос задать, а не на каком-нибудь .net/java-форуме.
Во первых, по моим наблюдениям, на реальных внедрениях бюджет на тестирование весьма ограничен и ни на какие юнит-тесты его просто не хватит. Во вторых - окидывая глазами тот код на X++ который я за 16 лет написал: Наверное я могу припомнить два-три случая, когда логика в моей разработке была достаточно сложной чтобы в принципе оправдать какие-то затраты на юнит-тестирование. Но все равно - при моей занятности проще было собрать молодых консов и за 10-15 минут объяснить им про возможные комбинации параметров и подводные грабли. В то же время кодирование юнит-тестов потребовало бы от меня эдак часика 3-4 работы. Наконец - как ты сам знаешь, главный риск от разработки на внедрениях - это риск сломать какой-то микрософтовский механизм (причем скорее всего тот, о котором ты даже и не знаешь). А тут никакой юнит-тест не поможет. Как я могу протестировать что-то, о функционировании чего я вообще не догадываюсь ? На мой взгляд, думать о каком-то юнит-тестировании на внедрениях можно только после того как Микрософт начнет сама поставлять свои юнит-тесты и скрипты. А в данный момент - разумнее работать по старинке - оттестировать силами консультанта базовые сценарии, а потом поставить в продакшн и смотреть что сломается... |
|
14.03.2017, 09:53 | #17 |
Участник
|
Цитата:
в аксапте из-за слоев очень стабильный интерфейс классов (сложно расширяемый. extensions опять же, не к ночи будут помятуны) из-за стабильного интерфейса в аксапте принято добавлять параметры со значениями по умолчанию как средство изменения поведения. как правило, в аксапте значение по умолчанию порождает старое поведение. а какое-либо другое значение порождает совсем другое поведение. (типичный пример - два последних параметра в примере кода выше) таким образом, в аксапте параметры со значениями по умолчанию хорошо выявляют входящие экстремальные значения. в других средах, экстремальные значения еще и выявить надо (но после выявления, тестирование ничем не отличается от аксаптовского, тут согласен). да, согласен, что в конечном итоге сводится к набору тестируемых значений и ожидаемых результатов для каждой комбинации. Но как записывать эти наборы и ожидаемые результаты, если их под несколько сотен? Генерировать программно? Но это вроде противоречит самой сути unit-тестирования, где программист явно определяет ожидаемый результат для каждого набора... Ну и так далее. Цитата:
а теперь вижу, что и в юнит-тестах тоже вполне видны исторические пласты, ощущаются былые непримиримые холивары и попытки реализации разных подходов. а также вижу codeReview и слышу что на них говорят... как будто ходишь туристом по Риму. отсюда и вопрос. и именно применительно к аксапте. и надежда, что может кто-то уже ходил этой тропой и кому-нибудь есть что сказать. Цитата:
это тоже один из подходов к unit-тестированию - не делать его. Последний раз редактировалось mazzy; 14.03.2017 в 09:57. |
|
14.03.2017, 09:51 | #18 |
Участник
|
Не очень понятно зачем тестировать 64 варианта. и как вы будете генерить данные для стольких вариантов.
я бы если бы требовалось протестировать вручную сделал бы 2 теста - с параметрами по умолчанию, и со всеми параметрами. соответственно так-же если надо было автоматизировать это. соответственно в качестве данных ввел бы 2 записи. |
|
14.03.2017, 09:54 | #19 |
Участник
|
а почему этого достаточно?
|
|
14.03.2017, 10:18 | #20 |
Участник
|
ну по сути это минимальный набор который покажет - не поломался ли метод.
(к примеру после установки решения которое добавляет event handler и не обрабатывает параметр _agreementHeaderExtRecId) протестировать полностью имхо вы не сможете по любому, ибо для 64 комбинаций входных параметров вам надо учесть, что порядок сортировки данных которые выбираются при поиске цены может быть тоже разный и может получиться что при одном наборе данных правильное значение выберется случайно, хотя сам метод будет работать и неправильно на других данных. т.е. тут будут миллионы комбинаций |
|