Готовлю большой класс с несколькими ДМЛ операциями к отправке в Прод.
Тест написан, но покрытие не впечатляющее - 82%.
Причина - тест не заходит в catch-и которые стоят на вставках\апдейтах.
И я не знаю как спровоцировать ДМЛ исключение - на объектах нет обязательных полей: вставляй, что хочешь - "жалко - нет".
Не знаю, что предпринять.
И по ходу возник еще вопрос: На объектах нет обязательных полей. Решил настраивать "обязательность" поля на лейауте. Причина: чтобы при добавлении новых полей к существующим в проде каст объектам случайно не добавить новое обязательное (на уровне объекта) поле, которые положит код в Проде, работающий с данным объектом и ничего не подозревающий о том новом, обязательном поле. Это правильно?
Всем привет!
Готовлю большой класс с несколькими ДМЛ операциями к отправке в Прод.
Тест написан, но покрытие не впечатляющее - 82%.
Причина - тест не заходит в catch-и которые стоят на вставках\апдейтах.
И я не знаю как спровоцировать ДМЛ исключение - на объектах нет обязательных полей: вставляй, что хочешь - "жалко - нет".
Не знаю, что предпринять.
И по ходу возник еще вопрос:
На объектах нет обязательных полей. Решил настраивать "обязательность" поля на лейауте.
Причина: чтобы при добавлении новых полей к существующим в проде каст объектам случайно не добавить новое обязательное (на уровне объекта) поле, которые положит код в Проде, работающий с данным объектом и ничего не подозревающий о том новом, обязательном поле.
Это правильно?
1) Попробуй заинсертить объект без обязательных полей. Но смотря какой catch стоит...если нужного не будет - не поможет.
1) Попробуй заинсертить объект без обязательных полей. Но смотря какой catch стоит...если нужного не будет - не поможет.
2) 82% - это очень неплохо...зачем еще больше?
Тут уже конкретно от задачи и бизнес-логики прыгать надо. Новое поле не должно положить, так как если ты написал грамотно тесты, то оно тебе при деплое на прод сообщит...
[quote="Den Brown"]
И по ходу возник еще вопрос:
На объектах нет обязательных полей. Решил настраивать "обязательность" поля на лейауте.
Причина: чтобы при добавлении новых полей к существующим в проде каст объектам случайно не добавить новое обязательное (на уровне объекта) поле, которые положит код в Проде, работающий с данным объектом и ничего не подозревающий о том новом, обязательном поле.
Это правильно?[/quote]
Тут уже конкретно от задачи и бизнес-логики прыгать надо. Новое поле не должно положить, так как если ты написал грамотно тесты, то оно тебе при деплое на прод сообщит...
Собственно для таких случаев и предусмотренно минимальное покрытие 75%. А 82% это очень даже хорошее покрытие для Salesforce.
А по поводу "не заходит" в try/catch - если не получается воссоздать ситуацию для срабатывания исключени стоит задуматься, а нужно ли оно :). В Salesforce и так предусмотрен механизм отката всех изменений в базе в случае ошибки выполнения в пределах рабочего цикла.
Если все же ошибки нужно перехватывать и выводить пользователю вместо "экрана смерти Salesforce", то можно обернуть весь метод в try/catch и просто сделать обработку и вывод ошибки для всего блока. А для покрытия внутри блока сделать вызвать кастомную ошибку например по определенному параметру, который выставляется из теста.
[quote]Тест написан, но покрытие не впечатляющее - 82%.
Причина - тест не заходит в catch-и которые стоят на вставках\апдейтах.[/quote]
Собственно для таких случаев и предусмотренно минимальное покрытие 75%. А 82% это очень даже хорошее покрытие для Salesforce.
А по поводу "не заходит" в try/catch - если не получается воссоздать ситуацию для срабатывания исключени стоит задуматься, а нужно ли оно :). В Salesforce и так предусмотрен механизм отката всех изменений в базе в случае ошибки выполнения в пределах рабочего цикла.
Если все же ошибки нужно перехватывать и выводить пользователю вместо "экрана смерти Salesforce", то можно обернуть весь метод в try/catch и просто сделать обработку и вывод ошибки для всего блока. А для покрытия внутри блока сделать вызвать кастомную ошибку например по определенному параметру, который выставляется из теста.
Ну не знаю у меня catch был больше чем try <!-- s:? --><img src="{SMILIES_PATH}/icon_e_confused.gif" alt=":?" title="Озадачен" /><!-- s:? --> .Ну есть несколько способов решить проблему,первый с которого я бы начал это проверил возможности метода addError() каждый sObject имеет этот метод который принимает Exception экземпляр или Стринг,насколько я помню addError работает только в контексте триггера,и возможно придется писать свой Exception класс для работы в контроллере.Второй способ попытатся про упдайтить не существующий объект или удалить.
[quote="Dmitry Shnyrev"][quote]Тест написан, но покрытие не впечатляющее - 82%.
Причина - тест не заходит в catch-и которые стоят на вставках\апдейтах.[/quote]
Собственно для таких случаев и предусмотренно минимальное покрытие 75%. А 82% это очень даже хорошее покрытие для Salesforce.
[/quote]
Ну не знаю у меня catch был больше чем try <!-- s:? --><img src="{SMILIES_PATH}/icon_e_confused.gif" alt=":?" title="Озадачен" /><!-- s:? --> .Ну есть несколько способов решить проблему,первый с которого я бы начал это проверил возможности метода addError() каждый sObject имеет этот метод который принимает Exception экземпляр или Стринг,насколько я помню addError работает только в контексте триггера,и возможно придется писать свой Exception класс для работы в контроллере.Второй способ попытатся про упдайтить не существующий объект или удалить.
Новое поле не должно положить, так как если ты написал грамотно тесты, то оно тебе при деплое на прод сообщит...
у меня не было опыта деплоить на прод.
Получается, что, например, пришел новый inbound change set in Prod, а в нем новые обязательные поля к старым объектам.
И в момент верификации система "крутит" не только те юнит-тесты, которые пришли с новым Сетом, а крутит ВСЕ юнит тесты в Проде, и некоторые из старых юнит тестов просто начнут падать из-за этого нового обязательного поля. И система сообщит об этом и не даст сделать деплой?
[quote="Art Vegas"]
Новое поле не должно положить, так как если ты написал грамотно тесты, то оно тебе при деплое на прод сообщит...[/quote]
у меня не было опыта деплоить на прод.
Получается, что, например, пришел новый inbound change set in Prod, а в нем новые обязательные поля к старым объектам.
И в момент верификации система "крутит" не только те юнит-тесты, которые пришли с новым Сетом, а крутит ВСЕ юнит тесты в Проде, и некоторые из старых юнит тестов просто начнут падать из-за этого нового обязательного поля. И система сообщит об этом и не даст сделать деплой?
И в момент верификации система "крутит" не только те юнит-тесты, которые пришли с новым Сетом, а крутит ВСЕ юнит тесты в Проде, и некоторые из старых юнит тестов просто начнут падать из-за этого нового обязательного поля. И система сообщит об этом и не даст сделать деплой?
Именно так и происходит). При валидации/деплое запускаются выполнения всех тестов на продакшене + тестов из ченж-сета.
По своему опыту скажу, у нас продакшен на одном проекте так разросься, что деплой ченж сетов достигал 8-9 часов. Потом, после обращения клиента в salesforce, оные ребята че-то подкрутили и стало нормальные 1-2 часа.
[quote="Den Brown"]
И в момент верификации система "крутит" не только те юнит-тесты, которые пришли с новым Сетом, а крутит ВСЕ юнит тесты в Проде, и некоторые из старых юнит тестов просто начнут падать из-за этого нового обязательного поля. И система сообщит об этом и не даст сделать деплой?[/quote]
Именно так и происходит). При валидации/деплое запускаются выполнения всех тестов на продакшене + тестов из ченж-сета.
По своему опыту скажу, у нас продакшен на одном проекте так разросься, что деплой ченж сетов достигал 8-9 часов. Потом, после обращения клиента в salesforce, оные ребята че-то подкрутили и стало нормальные 1-2 часа.
Именно так и происходит). При валидации/деплое запускаются выполнения всех тестов на продакшене + тестов из ченж-сета.
так вот зачем мы пишем все эти юнит-тесты.
не только (и вероятно не сколько) для текущего деплоймента, а для проверки на безопасность будущих, последующих изменений в системе.
[quote="Art Vegas"]
Именно так и происходит). При валидации/деплое запускаются выполнения всех тестов на продакшене + тестов из ченж-сета.
[/quote]
так вот зачем мы пишем все эти юнит-тесты.
не только (и вероятно не сколько) для текущего деплоймента, а для проверки на безопасность будущих, последующих изменений в системе.
так вот зачем мы пишем все эти юнит-тесты. не только (и вероятно не сколько) для текущего деплоймента, а для проверки на безопасность будущих, последующих изменений в системе.
Мне однажды даже жизненеобходимо было написать юнит-тесты, потому, что другого варианта проверки кода не было. Суть была в том, что у меня был managed package, который зависел от других пакетов (зависел, т.е не включен...а логика была в других). Орг, на котором я разрабатывал не имел возможности проинсталировать другие пакеты. И спасло то, что я писал юнит-тесты, где имитировал работу стороннего пакета (передаваемые данные) мне в пакет....
[quote="Den Brown"]
так вот зачем мы пишем все эти юнит-тесты.
не только (и вероятно не сколько) для текущего деплоймента, а для проверки на безопасность будущих, последующих изменений в системе.[/quote]
Мне однажды даже жизненеобходимо было написать юнит-тесты, потому, что другого варианта проверки кода не было. Суть была в том, что у меня был managed package, который зависел от других пакетов (зависел, т.е не включен...а логика была в других). Орг, на котором я разрабатывал не имел возможности проинсталировать другие пакеты. И спасло то, что я писал юнит-тесты, где имитировал работу стороннего пакета (передаваемые данные) мне в пакет....
Как-то так.
Мне однажды даже жизненеобходимо было написать юнит-тесты, потому, что другого варианта проверки кода не было. Суть была в том, что у меня был managed package, который зависел от других пакетов (зависел, т.е не включен...а логика была в других). Орг, на котором я разрабатывал не имел возможности проинсталировать другие пакеты. И спасло то, что я писал юнит-тесты, где имитировал работу стороннего пакета (передаваемые данные) мне в пакет....
Это что-то интересное. Я думаю подробности будут не лишними. Ты говоришь что один пакет ссылается на другой (использует логику другого) но при этом его можно поставить на орг без этих зависимых пакетов. Я так понял что ты используешь динамическое связывание? При явной ссылке одного пакета на другой salesforce даже не даст поставить один пакет без другого.
"Юнит тесты имитировали работу стороннего пакета" - значит твой пакет видел что нет другого пакета, логику которого он использует, поэтому обращался к методам из твоих тестов?
[quote]Мне однажды даже жизненеобходимо было написать юнит-тесты, потому, что другого варианта проверки кода не было. Суть была в том, что у меня был managed package, который зависел от других пакетов (зависел, т.е не включен...а логика была в других). Орг, на котором я разрабатывал не имел возможности проинсталировать другие пакеты. И спасло то, что я писал юнит-тесты, где имитировал работу стороннего пакета (передаваемые данные) мне в пакет....[/quote]
Это что-то интересное. Я думаю подробности будут не лишними. Ты говоришь что один пакет ссылается на другой (использует логику другого) но при этом его можно поставить на орг без этих зависимых пакетов. Я так понял что ты используешь динамическое связывание? При явной ссылке одного пакета на другой salesforce даже не даст поставить один пакет без другого.
"Юнит тесты имитировали работу стороннего пакета" - значит твой пакет видел что нет другого пакета, логику которого он использует, поэтому обращался к методам из твоих тестов?
Как-то так?
так вот зачем мы пишем все эти юнит-тесты. не только (и вероятно не сколько) для текущего деплоймента, а для проверки на безопасность будущих, последующих изменений в системе.
Мне однажды даже жизненеобходимо было написать юнит-тесты, потому, что другого варианта проверки кода не было. Суть была в том, что у меня был managed package, который зависел от других пакетов (зависел, т.е не включен...а логика была в других). Орг, на котором я разрабатывал не имел возможности проинсталировать другие пакеты. И спасло то, что я писал юнит-тесты, где имитировал работу стороннего пакета (передаваемые данные) мне в пакет....
[quote="Art Vegas"][quote="Den Brown"]
так вот зачем мы пишем все эти юнит-тесты.
не только (и вероятно не сколько) для текущего деплоймента, а для проверки на безопасность будущих, последующих изменений в системе.[/quote]
Мне однажды даже жизненеобходимо было написать юнит-тесты, потому, что другого варианта проверки кода не было. Суть была в том, что у меня был managed package, который зависел от других пакетов (зависел, т.е не включен...а логика была в других). Орг, на котором я разрабатывал не имел возможности проинсталировать другие пакеты. И спасло то, что я писал юнит-тесты, где имитировал работу стороннего пакета (передаваемые данные) мне в пакет....
Как-то так.[/quote]
Как то не очень понятно можешь пояснить ?
И в момент верификации система "крутит" не только те юнит-тесты, которые пришли с новым Сетом, а крутит ВСЕ юнит тесты в Проде, и некоторые из старых юнит тестов просто начнут падать из-за этого нового обязательного поля. И система сообщит об этом и не даст сделать деплой?
Именно так и происходит). При валидации/деплое запускаются выполнения всех тестов на продакшене + тестов из ченж-сета.
Почти так и происходит) да запускаются все тесты на продакшене,но в финальный расчет берутся только кастомные то есть если ты имешь manage packages на твоем продакшене тогда тесты тоже начнут отрабатывать,но в расчет для покрытия классов будут браться только кастомные. Я имел очень низкое покрытие для тестов из manage package но в финальные расчет брался только кастомный код то же самое относится и ошибкам. я бы сказал очень важная особенность.
[quote="Art Vegas"][quote="Den Brown"]
И в момент верификации система "крутит" не только те юнит-тесты, которые пришли с новым Сетом, а крутит ВСЕ юнит тесты в Проде, и некоторые из старых юнит тестов просто начнут падать из-за этого нового обязательного поля. И система сообщит об этом и не даст сделать деплой?[/quote]
Именно так и происходит). При валидации/деплое запускаются выполнения всех тестов на продакшене + тестов из ченж-сета.
[/quote]
Почти так и происходит) да запускаются все тесты на продакшене,но в финальный расчет берутся только кастомные то есть если ты имешь manage packages на твоем продакшене тогда тесты тоже начнут отрабатывать,но в расчет для покрытия классов будут браться только кастомные. Я имел очень низкое покрытие для тестов из manage package но в финальные расчет брался только кастомный код то же самое относится и ошибкам. я бы сказал очень важная особенность.
Как то не очень понятно можешь пояснить ?
Вся cуть вот в чем: К ответу Den зачем unit-test. Иногда нет возможности проверить свой код, как через апекс тесты
[quote="Sergey Prichepo"]
Как то не очень понятно можешь пояснить ?[/quote]
Вся cуть вот в чем:
К ответу Den зачем unit-test. Иногда нет возможности проверить свой код, как через апекс тесты
Как то не очень понятно можешь пояснить ?
Вся cуть вот в чем: К ответу Den зачем unit-test. Иногда нет возможности проверить свой код, как через апекс тесты
Это я понял) даже подход такой есть TDD.Сначало пишется тест а потом код на контроллер и триггер.Например у нас была проблема,я думаю что у некоторых она может возникнуть падали тест классы при создании пакета в чем дело очень долго никто не мог понять потому что если запускали по отдельности тесты все работало нормально.Оказалось что у нас был инсталирован зависимы пакет в дев орг.Дальше интереснее окзалось что там где в инсталиррованном пакете используются динамические запросы Database.query обязательно должна быть 30 versio api иначе созадать другой пакет где этот инсталирован не возможно.Пришлось пересоздавать пакет и занова исталировать.
[quote="Art Vegas"][quote="Sergey Prichepo"]
Как то не очень понятно можешь пояснить ?[/quote]
Вся cуть вот в чем:
К ответу Den зачем unit-test. Иногда нет возможности проверить свой код, как через апекс тесты[/quote]
Это я понял) даже подход такой есть TDD.Сначало пишется тест а потом код на контроллер и триггер.Например у нас была проблема,я думаю что у некоторых она может возникнуть падали тест классы при создании пакета в чем дело очень долго никто не мог понять потому что если запускали по отдельности тесты все работало нормально.Оказалось что у нас был инсталирован зависимы пакет в дев орг.Дальше интереснее окзалось что там где в инсталиррованном пакете используются динамические запросы Database.query обязательно должна быть 30 versio api иначе созадать другой пакет где этот инсталирован не возможно.Пришлось пересоздавать пакет и занова исталировать.
У нас нечто похожее было. Правда я с пакетами мало работал. На тех проектах, где сейчас работаю - используются change set'ы. Правда порой тоже были странные проблемы с code coverage 60% на продакшене вместо 75% минимально положенных) И не задеплоить...было..и грязные хаки (a++ в тестах делали)...короче...потом все как-то само вернулось..оказалось проблемы были у SF.
У нас нечто похожее было. Правда я с пакетами мало работал. На тех проектах, где сейчас работаю - используются change set'ы. Правда порой тоже были странные проблемы с code coverage 60% на продакшене вместо 75% минимально положенных) И не задеплоить...было..и грязные хаки (a++ в тестах делали)...короче...потом все как-то само вернулось..оказалось проблемы были у SF.
К вопросу поднятому Дмитрием: а нужны ли ставить try-catch на абсолютно всех ДМЛ, даже в тех, в которых мы не ожидаем никаких проблем?
например где-то по ходу выполнения кода я делаю единичный (и по существу - второстепенный ) апдейт. Я не ожидаю в этой оперции никакого подвоха. Нужно ли брать этот апдейт в try-catch или оставить его "голяком" в коде - и если на нем возникнут когда-то проблемы - то пусть весь код падает - все равно нужно будет разбираться детально, что там внезапно произошло.
Не знаю как правильнее: to catch or not to catch каждый ДМЛ в коде?
К вопросу поднятому Дмитрием: а нужны ли ставить try-catch на абсолютно всех ДМЛ, даже в тех, в которых мы не ожидаем никаких проблем?
например где-то по ходу выполнения кода я делаю единичный (и по существу - второстепенный ) апдейт. Я не ожидаю в этой оперции никакого подвоха. Нужно ли брать этот апдейт в try-catch или оставить его "голяком" в коде - и если на нем возникнут когда-то проблемы - то пусть весь код падает - все равно нужно будет разбираться детально, что там внезапно произошло.
Не знаю как правильнее: to catch or not to catch каждый ДМЛ в коде?
Try/catch нужно если у тебя предусмотрен альтернативный обработчик ошибки. если просто оборачивать каждую dml операцию чтобы вывести красиво ошибку то я думаю не стоит. Salesforce как CRM и там очень красиво показывает и обрабатывает ошибки.
Кстати в тему - когда пришел из PHP в SF то активно пользовался транзакциями собственно для которых и использовал try catch. Но особенность Salesforce полностью выкурила эту привычку. А именно Salesforce в случае ошибки (которую мы кстати не перехватили в try/catch) полностью откатывает все изменения в базе.
Так что я больше склоняюсь к тому чтобы не перехватывать, а наоборот как можно меньше использовать, а позволить SF самому разруливать ошибочные ситуации.
Try/catch нужно если у тебя предусмотрен альтернативный обработчик ошибки.
если просто оборачивать каждую dml операцию чтобы вывести красиво ошибку то я думаю не стоит. Salesforce как CRM и там очень красиво показывает и обрабатывает ошибки.
Кстати в тему - когда пришел из PHP в SF то активно пользовался транзакциями собственно для которых и использовал try catch. Но особенность Salesforce полностью выкурила эту привычку. А именно Salesforce в случае ошибки (которую мы кстати не перехватили в try/catch) полностью откатывает все изменения в базе.
Так что я больше склоняюсь к тому чтобы не перехватывать, а наоборот как можно меньше использовать, а позволить SF самому разруливать ошибочные ситуации.
Ну вот столкнулся с такой ситуацией.
контроллер который создает запись и может приатачить к ней 1 или 2 или 3 или 4 аттача.
каждый аттач индивидуально проверяется на наличие боди и имени в вставляется с индивидуальном трай-кетче. и если вставка обломилась - в кетче (в зависимости от порядка атача, удаляются предидущие аттачи, головная запись). Т.е. там много строк в Кетчах.
и я не могу в тесте зайти в кетч.
как спровоцировать Insert исключение для Аттачмента? ПарентАйДи приписывается самим контроллером...
или придется делать один трай-кетч блок для всех Аттачей чтоб сократить кол-во недостижимых строк в кетчах...
мне логика в несколькими трай-кетчами больше нравится...
Ну вот столкнулся с такой ситуацией.
контроллер который создает запись и может приатачить к ней 1 или 2 или 3 или 4 аттача.
каждый аттач индивидуально проверяется на наличие боди и имени в вставляется с индивидуальном трай-кетче.
и если вставка обломилась - в кетче (в зависимости от порядка атача, удаляются предидущие аттачи, головная запись). Т.е. там много строк в Кетчах.
и я не могу в тесте зайти в кетч.
как спровоцировать Insert исключение для Аттачмента? ПарентАйДи приписывается самим контроллером...
или придется делать один трай-кетч блок для всех Аттачей чтоб сократить кол-во недостижимых строк в кетчах...
мне логика в несколькими трай-кетчами больше нравится...
Я для таких ситуаций написал тест хелпер и метод в ньом ThrowExceptionIfTesting которий смотрит на Test.isRunningTest и на статическую булевую переменую, которой можно контролировать в каких ситуациях вибрасивать ексепшен. И етот метод пишу try блоке.
Я для таких ситуаций написал тест хелпер и метод в ньом ThrowExceptionIfTesting которий смотрит на Test.isRunningTest и на статическую булевую переменую, которой можно контролировать в каких ситуациях вибрасивать ексепшен. И етот метод пишу try блоке.
Я для таких ситуаций написал тест хелпер и метод в ньом ThrowExceptionIfTesting которий смотрит на Test.isRunningTest и на статическую булевую переменую, которой можно контролировать в каких ситуациях вибрасивать ексепшен. И етот метод пишу try блоке.
а что - идея. значит есть класс со стат булевой переменной и методом который просто выбрасывает исключение.
в тесте первый прогон со булевой переменной false - все прогоняем как положено.
затем переводим булеву переменную в true - и второй прогон: траи выпадают в исключение при условии (Test.isRunningTest&&булеваПеременная) и код уходит в кетчи
[quote="Alex Tsitsura"]Я для таких ситуаций написал тест хелпер и метод в ньом ThrowExceptionIfTesting которий смотрит на Test.isRunningTest и на статическую булевую переменую, которой можно контролировать в каких ситуациях вибрасивать ексепшен. И етот метод пишу try блоке.[/quote]
а что - идея.
значит есть класс со стат булевой переменной и методом который просто выбрасывает исключение.
в тесте первый прогон со булевой переменной false - все прогоняем как положено.
затем переводим булеву переменную в true - и второй прогон: траи выпадают в исключение при условии (Test.isRunningTest&&булеваПеременная) и код уходит в кетчи
Я для таких ситуаций написал тест хелпер и метод в ньом ThrowExceptionIfTesting которий смотрит на Test.isRunningTest и на статическую булевую переменую, которой можно контролировать в каких ситуациях вибрасивать ексепшен. И етот метод пишу try блоке.
так и сделал - залез один за другим во все Кетчи. покрытие 100%
[quote="Alex Tsitsura"]Я для таких ситуаций написал тест хелпер и метод в ньом ThrowExceptionIfTesting которий смотрит на Test.isRunningTest и на статическую булевую переменую, которой можно контролировать в каких ситуациях вибрасивать ексепшен. И етот метод пишу try блоке.[/quote]
так и сделал - залез один за другим во все Кетчи. покрытие 100%
Я для таких ситуаций написал тест хелпер и метод в ньом ThrowExceptionIfTesting которий смотрит на Test.isRunningTest и на статическую булевую переменую, которой можно контролировать в каких ситуациях вибрасивать ексепшен. И етот метод пишу try блоке.
Так делать в принципе не правильно. Код не должен подстраиваться под тесты. Все должно быть наоборот.
[quote="Alex Tsitsura"]Я для таких ситуаций написал тест хелпер и метод в ньом ThrowExceptionIfTesting которий смотрит на Test.isRunningTest и на статическую булевую переменую, которой можно контролировать в каких ситуациях вибрасивать ексепшен. И етот метод пишу try блоке.[/quote]
Так делать в принципе не правильно. Код не должен подстраиваться под тесты. Все должно быть наоборот.
Код не должен подстраиваться под тесты. Все должно быть наоборот.
звучит абсолютно правильно. но как в тесте спровоцировать ДМЛ исключение? изменить на-лету метадату, например сделав какое-то поле Required, а потом вернусь измененияч обратно? Хотя постойте-ка, а можно ли в коде, например, воткнуть в "телефооное" поле буквы? тогда код выпадет на ДМЛе и уйдет в Кетч...
[quote="Gres"] Код не должен подстраиваться под тесты. Все должно быть наоборот.[/quote]
звучит абсолютно правильно. но как в тесте спровоцировать ДМЛ исключение? изменить на-лету метадату, например сделав какое-то поле Required, а потом вернусь измененияч обратно? Хотя постойте-ка, а можно ли в коде, например, воткнуть в "телефооное" поле буквы? тогда код выпадет на ДМЛе и уйдет в Кетч...
покрывать catch блоки в тестах не обязательно и даже не нужно. Для этого в Salesforce и предусмотрено 75% покрытия (25% можно потратить на catch блоки) А то что при неправильных данных в поле у тебя доходит до exception DML Exception это жесть. А как же валидация входных данных и возвращение human readable error? А если тебе ОЧЕНЬ надо проверить супер логику в catch блоке, то вынеси ее в отдельный класс в static метод а из catch блока вызывай этот метод 1 строкой кода. Особо на покрытии не потеряешь из-за одной строки, а static метод сможешь проверить без всяких страшных извращений с вызовом exceptoin.
PS. Хотя для спортивного интереса можешь и поизвращаться
покрывать catch блоки в тестах не обязательно и даже не нужно. Для этого в Salesforce и предусмотрено 75% покрытия (25% можно потратить на catch блоки)
А то что при неправильных данных в поле у тебя доходит до exception DML Exception это жесть. А как же валидация входных данных и возвращение human readable error?
А если тебе ОЧЕНЬ надо проверить супер логику в catch блоке, то вынеси ее в отдельный класс в static метод а из catch блока вызывай этот метод 1 строкой кода. Особо на покрытии не потеряешь из-за одной строки, а static метод сможешь проверить без всяких страшных извращений с вызовом exceptoin.
PS. Хотя для спортивного интереса можешь и поизвращаться :D
Я для таких ситуаций написал тест хелпер и метод в ньом ThrowExceptionIfTesting которий смотрит на Test.isRunningTest и на статическую булевую переменую, которой можно контролировать в каких ситуациях вибрасивать ексепшен. И етот метод пишу try блоке.
Так делать в принципе не правильно. Код не должен подстраиваться под тесты. Все должно быть наоборот.
Абсолютно с Вами согласен, но иногда есть ситуации, какие нельзя воспроизвести в тесте.
[quote="Gres"][quote="Alex Tsitsura"]
Я для таких ситуаций написал тест хелпер и метод в ньом ThrowExceptionIfTesting которий смотрит на Test.isRunningTest и на статическую булевую переменую, которой можно контролировать в каких ситуациях вибрасивать ексепшен. И етот метод пишу try блоке.[/quote]Так делать в принципе не правильно. Код не должен подстраиваться под тесты. Все должно быть наоборот.[/quote]
Абсолютно с Вами согласен, но иногда есть ситуации, какие нельзя воспроизвести в тесте.
иногда есть ситуации, какие нельзя воспроизвести в тесте.
Если приходит такое понимание, то значит точно есть ошибка в проектировании.
[quote="Alex Tsitsura"]иногда есть ситуации, какие нельзя воспроизвести в тесте.[/quote]
Если приходит такое понимание, то значит точно есть ошибка в проектировании.
Поддержу Gres, не сталкивался с ситуациями, которые НЕЛЬЗЯ воспроизвести в тестах. Бывает это сложно сделать, особенно если код чужой и приходится заниматься реверс-инженерингом. Любой же код когда-нибудь вызывается. А если вызывается, то и тестами его можно покрыть. А если НЕ вызывается, то может он и не нужен в приложении
Поддержу Gres, не сталкивался с ситуациями, которые НЕЛЬЗЯ воспроизвести в тестах. Бывает это сложно сделать, особенно если код чужой и приходится заниматься реверс-инженерингом. Любой же код когда-нибудь вызывается. А если вызывается, то и тестами его можно покрыть. А если НЕ вызывается, то может он и не нужен в приложении :)
иногда есть ситуации, какие нельзя воспроизвести в тесте.
Если приходит такое понимание, то значит точно есть ошибка в проектировании.
А если у нас делаются калаути, как мы можем зайти в catch блок?
[quote="Gres"][quote="Alex Tsitsura"]
иногда есть ситуации, какие нельзя воспроизвести в тесте.[/quote]
Если приходит такое понимание, то значит точно есть ошибка в проектировании.[/quote]
А если у нас делаются калаути, как мы можем зайти в catch блок?
ок?
иногда есть ситуации, какие нельзя воспроизвести в тесте.
Если приходит такое понимание, то значит точно есть ошибка в проектировании.
А если у нас делаются калаути, как мы можем зайти в catch блок?
[quote="Alex Tsitsura"]ок?[/quote][quote="Alex Tsitsura"][quote="Gres"][quote="Alex Tsitsura"]
иногда есть ситуации, какие нельзя воспроизвести в тесте.[/quote]
Если приходит такое понимание, то значит точно есть ошибка в проектировании.[/quote]
А если у нас делаются калаути, как мы можем зайти в catch блок?[/quote]
Сгенерить ошибку в моке.
Я помню, что кто-то тут ратовал за TDD, просто интересно, как в рамках данной платформы он реализует эту методологию.
Я помню, что кто-то тут ратовал за TDD, просто интересно, как в рамках данной платформы он реализует эту методологию.
Gres, а в чем проблема использовать TDD. Если посмотрим чисто с практической точки зрения. Я конечно не начитанный малый, все познаю тупо из практики и может не понимаю что такое TDD. Но если руководствоваться вот этим
Разработка через тестирование (англ. test-driven development, TDD) — техника разработки программного обеспечения, которая основывается на повторении очень коротких циклов разработки: сначала пишется тест, покрывающий желаемое изменение, затем пишется код, который позволит пройти тест, и под конец проводится рефакторинг нового кода к соответствующим стандартам.
то почему сложно реализовать эту методологию внутки Salesforce? Типичный пример - писал недавно интеграцию и работал именно начиная с тестов. Пока не был готов реальный внешний сервис все данные подготавливались в тестах. И получалось что я сначала делал тесты, которые имитировали запросы и уже потом разрабатывал сами обработчики. Получилось очень классно. Как мне кажется это и есть TDD. Верно?
Gres, а в чем проблема использовать TDD.
Если посмотрим чисто с практической точки зрения.
Я конечно не начитанный малый, все познаю тупо из практики и может не понимаю что такое TDD.
Но если руководствоваться вот этим
[quote]Разработка через тестирование (англ. test-driven development, TDD) — техника разработки программного обеспечения, которая основывается на повторении очень коротких циклов разработки: сначала пишется тест, покрывающий желаемое изменение, затем пишется код, который позволит пройти тест, и под конец проводится рефакторинг нового кода к соответствующим стандартам.[/quote]
то почему сложно реализовать эту методологию внутки Salesforce?
Типичный пример - писал недавно интеграцию и работал именно начиная с тестов. Пока не был готов реальный внешний сервис все данные подготавливались в тестах. И получалось что я сначала делал тесты, которые имитировали запросы и уже потом разрабатывал сами обработчики. Получилось очень классно. Как мне кажется это и есть TDD. Верно?
ок?
иногда есть ситуации, какие нельзя воспроизвести в тесте.
Если приходит такое понимание, то значит точно есть ошибка в проектировании.
А если у нас делаются калаути, как мы можем зайти в catch блок?
[quote="Gres"][quote="Alex Tsitsura"]ок?[/quote][quote="Alex Tsitsura"][quote="Gres"][quote="Alex Tsitsura"]
иногда есть ситуации, какие нельзя воспроизвести в тесте.[/quote]
Если приходит такое понимание, то значит точно есть ошибка в проектировании.[/quote]
А если у нас делаются калаути, как мы можем зайти в catch блок?[/quote]
Сгенерить ошибку в моке.[/quote]
Да, об этом я не подумал(
Gres, а в чем проблема использовать TDD.
то почему сложно реализовать эту методологию внутки Salesforce?
Нужен удобный инструмент для моков, а также детерминированное время выполнения тестов.
[quote="Dmitry Shnyrev"]Gres, а в чем проблема использовать TDD. [/quote]
[quote="Dmitry Shnyrev"]то почему сложно реализовать эту методологию внутки Salesforce? [/quote]
Нужен удобный инструмент для моков, а также детерминированное время выполнения тестов.
Кст, могу посоветовать посмотреть - http://blog.byndyu.ru/2010/02/tdd_18.html
Т.е. ты сначала писал тесты, на методы без реализации, а потом релизовывал их так, чтобы тесты проходили?
Посмотрел видео. Отличное и понятное видео, несмотря на то что это для C#. Пока понял что моки в C# предоставляют более продвинутые механизмы для контроля за выполнением кода - те же проверки выполнился ли метод и с какими параметрами. В Salesforce же мы в этом случае ограничены - можем опираться только на возвращаемые функцией данные для того чтобы проверить их с помощью system.assert... Но все равно не увидел ничего такого что нельзя реализовать в Salesforce. Принципы тестирования те же самые, просто реализация другая: arrange - подготовка данных, act - вызов функционала assert - проверка результата. Т.е. если я правильно понял, то в C# это дело происходит красиво внутри моков и мы просто можем контролировать их состояние, то в Salesforce наши тесты это и есть сами моки и мы сами делаем много ручной работы. Но имхо это только упрощает понимание и исключает лишний слой абстракции
Т.е. ты сначала писал тесты, на методы без реализации, а потом релизовывал их так, чтобы тесты проходили?
В последнем случае что я описывал, да, именно сначала тесты и контроль результата, а потом уже реализация метода - прямо так как в видео.
Но в большинстве случаев мой принцип разработки получается не по феншую TDD, но его принципам. Дело в том что я в разработке никогда не проверяю функционал с помощью браузера (если он чуть сложнее простой странички). Т.е. критерием работы кода является именно тест. Я начинаю писать какой-то метод, когда код более менее сформирован (но не разу не запущен) пишу сразу тест и начинаю запускать тест и смотреть на результаты работы метода. Только после того как тест прошел и все user cases протестированы (в том числе искючительные ситуации) уже иду в браузер и наблюдаю идеально работающую страницу. PS. Хотя, да, что-то я погорячился это нифига не TDD, а я просто описал стандартную разработку логики с тестами Все-таки TDD - именно разработка через тестирование и все начинается с тестов !!!
Посмотрел видео. Отличное и понятное видео, несмотря на то что это для C#.
Пока понял что моки в C# предоставляют более продвинутые механизмы для контроля за выполнением кода - те же проверки выполнился ли метод и с какими параметрами. В Salesforce же мы в этом случае ограничены - можем опираться только на возвращаемые функцией данные для того чтобы проверить их с помощью system.assert...
Но все равно не увидел ничего такого что нельзя реализовать в Salesforce.
Принципы тестирования те же самые, просто реализация другая:
arrange - подготовка данных,
act - вызов функционала
assert - проверка результата.
Т.е. если я правильно понял, то в C# это дело происходит красиво внутри моков и мы просто можем контролировать их состояние, то в Salesforce наши тесты это и есть сами моки и мы сами делаем много ручной работы. Но имхо это только упрощает понимание и исключает лишний слой абстракции :)
[quote="Gres"]Т.е. ты сначала писал тесты, на методы без реализации, а потом релизовывал их так, чтобы тесты проходили?[/quote]
В последнем случае что я описывал, да, именно сначала тесты и контроль результата, а потом уже реализация метода - прямо так как в видео.
[i]Но в большинстве случаев мой принцип разработки получается не по феншую TDD, но его принципам. Дело в том что я в разработке никогда не проверяю функционал с помощью браузера (если он чуть сложнее простой странички). Т.е. критерием работы кода является именно тест. Я начинаю писать какой-то метод, когда код более менее сформирован (но не разу не запущен) пишу сразу тест и начинаю запускать тест и смотреть на результаты работы метода. Только после того как тест прошел и все user cases протестированы (в том числе искючительные ситуации) уже иду в браузер и наблюдаю идеально работающую страницу.
PS. Хотя, да, что-то я погорячился :) это нифига не TDD, а я просто описал стандартную разработку логики с тестами :) Все-таки TDD - именно разработка через тестирование и все начинается с тестов !!![/i]
Но все равно не увидел ничего такого что нельзя реализовать в Salesforce.
Я не говорил, что нельзя что-то сделать.
Я помню, что кто-то тут ратовал за TDD, просто интересно, как в рамках данной платформы он реализует эту методологию.
[quote="Dmitry Shnyrev"]Но все равно не увидел ничего такого что нельзя реализовать в Salesforce. [/quote]
Я не говорил, что нельзя что-то сделать.
[quote="Gres"]Я помню, что кто-то тут ратовал за TDD, просто интересно, как в рамках данной платформы он реализует эту методологию.[/quote]
Просто это не совсем удобно.
Различные тестовые объекты - http://habrahabr.ru/post/116372/
Но имхо это только упрощает понимание и исключает лишний слой абстракции
[quote="Dmitry Shnyrev"]Но имхо это только упрощает понимание и исключает лишний слой абстракции [/quote]
Зря ты не любишь абстракции (:
Кстати, первый раз видел исходники на C# - красиво очень напоминает Salesforce. Особенно понравилась структура проекта - сразу выделены BusinessLogic, Domains - сразу намекает на правильное разделение кода по слоям.
Кстати, первый раз видел исходники на C# - красиво :) очень напоминает Salesforce. Особенно понравилась структура проекта - сразу выделены BusinessLogic, Domains - сразу намекает на правильное разделение кода по слоям.
Кстати, первый раз видел исходники на C# - красиво
[quote="Dmitry Shnyrev"]Кстати, первый раз видел исходники на C# - красиво [/quote]
Попробуй, это еще и вкусно, и удобное, и приятно.
Зря ты не любишь абстракции (:
Вернее сказать у меня к ним двоякое отношение - с одной стороны абстракции позволяют уменьшить сложность и упростить разработку. А с другой стороны это добавляет "магию", которой надо владеть. С этой точки зрения assembler считаю идеальным языком потому что там надо знать только команды процессора, регистры и структуру памяти, что можно уместить наверное на лист формата А4 (это конечно в упрощенном виде для примера). Весь процесс как на ладони. Но конечно я бы не стал на нем программировать, потому что это ОЧЕНЬ долго. А вот абстракции надо знать чтобы уметь их варить. Вот типичный пример с этими моками. Я не знаю что ты под ними подразумеваешь, а могу лишь догадываться, потому что ты их, наверное, принес с собой из C#, а я тесты писал только под Salesforce. Может мы вообще говорим о разном, пытаясь перетянуть одеяло на свою сторону. А если сейчас придет Wilder, то у него вообще окажется своя реализация моков под Salesforce и кто-тогда будет главным?
[quote="Gres"]Зря ты не любишь абстракции (:[/quote]
Вернее сказать у меня к ним двоякое отношение - с одной стороны абстракции позволяют уменьшить сложность и упростить разработку. А с другой стороны это добавляет "магию", которой надо владеть. С этой точки зрения assembler считаю идеальным языком :D потому что там надо знать только команды процессора, регистры и структуру памяти, что можно уместить наверное на лист формата А4 (это конечно в упрощенном виде для примера). Весь процесс как на ладони. Но конечно я бы не стал на нем программировать, потому что это ОЧЕНЬ долго.
А вот абстракции надо знать чтобы уметь их варить. Вот типичный пример с этими моками. Я не знаю что ты под ними подразумеваешь, а могу лишь догадываться, потому что ты их, наверное, принес с собой из C#, а я тесты писал только под Salesforce. Может мы вообще говорим о разном, пытаясь перетянуть одеяло на свою сторону. А если сейчас придет Wilder, то у него вообще окажется своя реализация моков под Salesforce и кто-тогда будет главным?
[quote="Dmitry Shnyrev"]Я не знаю что ты под ними подразумеваешь[/quote]
Выше ссылка на примерное описание различных тестовых объектов.
Кст, вот такая штука есть, но она мне не оч нравится - https://github.com/financialforcedev/fflib-apex-mocks
Попробуй, это еще и вкусно, и удобное, и приятно.
Возможно, но пока оставлю на будущее. Думаю что мой мозг взорвется, если я туда еще c# начну пихать.
[quote="Gres"]Попробуй, это еще и вкусно, и удобное, и приятно.[/quote]
Возможно, но пока оставлю на будущее. Думаю что мой мозг взорвется, если я туда еще c# начну пихать.
А если сейчас придет Wilder, то у него вообще окажется своя реализация моков под Salesforce и кто-тогда будет главным?
Зачем кто-то главный. Все равно все останутся при своем мнении.
[quote="Dmitry Shnyrev"]А если сейчас придет Wilder, то у него вообще окажется своя реализация моков под Salesforce и кто-тогда будет главным?[/quote]
Зачем кто-то главный. Все равно все останутся при своем мнении.
Зачем кто-то главный. Все равно все останутся при своем мнении.
А если работать в команде? Что из этого получится?
С одной стороны статья немного прояснила тему тестирования, но с другой еще больше вопросов появилось:
Внешняя зависимость — это объект, с которым взаимодействует код и над которым нет прямого контроля. Для ликвидации внешних зависимостей в модульных тестах используются тестовые объекты, например такие как stubs (заглушки).
Получается что Mock объект - эта заглушка(одна из пяти разновидностей), которая передается в метод:
— mock object (мок-объект), очень похож на тестовый шпион, однако не записывает последовательность вызовов с переданными параметрами для последующей проверки, а может сам выкидывать исключения при некорректно переданных данных. Т.е. именно мок-объект проверяет корректность поведения тестируемого объекта.
Млин, эта теория только еще больше запутывает. Gres, проясни плиз. Если взять простые стандартные тесты в Salesforce и положить их на эту статью, то чем мы тогда занимаемся? Как это квалифицировать?
[quote="Gres"]Просто это не совсем удобно.
Различные тестовые объекты - http://habrahabr.ru/post/116372/[/quote]
С одной стороны статья немного прояснила тему тестирования, но с другой еще больше вопросов появилось:
[quote]Внешняя зависимость — это объект, с которым взаимодействует код и над которым нет прямого контроля. Для ликвидации внешних зависимостей в модульных тестах используются тестовые объекты, например такие как stubs (заглушки).[/quote]
Получается что Mock объект - эта заглушка(одна из пяти разновидностей), которая передается в метод:
[quote]— mock object (мок-объект), очень похож на тестовый шпион, однако не записывает последовательность вызовов с переданными параметрами для последующей проверки, а может сам выкидывать исключения при некорректно переданных данных. Т.е. именно мок-объект проверяет корректность поведения тестируемого объекта.[/quote]
Млин, эта теория только еще больше запутывает.
Gres, проясни плиз. Если взять простые стандартные тесты в Salesforce и положить их на эту статью, то чем мы тогда занимаемся? Как это квалифицировать?
Короче, могу теперь точно сказать, что про тестирование я нихрена не знаю :D.
[quote="Dmitry Shnyrev"]А если работать в команде? Что из этого получится?[/quote]
В команде должны быть определенные стандарты, которые известны всем и всех их поддерживают.
Получается что Mock объект - эта заглушка(одна из пяти разновидностей), которая передается в метод:
Считается, что объекты типа mock содержат в себе некое поведение.
[quote="Dmitry Shnyrev"]Получается что Mock объект - эта заглушка(одна из пяти разновидностей), которая передается в метод: [/quote]
Считается, что объекты типа mock содержат в себе некое поведение.
Если взять простые стандартные тесты в Salesforce и положить их на эту статью, то чем мы тогда занимаемся?
Ну тесты, это тесты, а тут мы говорим про разлизные объекты для тестов. В СФ мы в основном использует стабы.
[quote="Dmitry Shnyrev"]Если взять простые стандартные тесты в Salesforce и положить их на эту статью, то чем мы тогда занимаемся?[/quote]
Ну тесты, это тесты, а тут мы говорим про разлизные объекты для тестов.
В СФ мы в основном использует стабы.
Короче, могу теперь точно сказать, что про тестирование я нихрена не знаю :D.
[quote="Dmitry Shnyrev"]Короче, могу теперь точно сказать, что про тестирование я нихрена не знаю :D. [/quote]
Могу посоветовать The Art of Unit Testing - http://artofunittesting.com/
Короче, могу теперь точно сказать, что про тестирование я нихрена не знаю :D.
Да не парься, ты же не на собеседовании. Главное, чтобы твой код хорошо работал.
[quote="Dmitry Shnyrev"]Короче, могу теперь точно сказать, что про тестирование я нихрена не знаю :D. [/quote]
Да не парься, ты же не на собеседовании. Главное, чтобы твой код хорошо работал.
Да не парься, ты же не на собеседовании. Главное, чтобы твой код хорошо работал.
Ну, незнание многих теоретических тем, это парит меня меньше всего . Знание практических аспектов webdev, я уверен, перекрывает этот скромный недостаток . Парит то, что мой старый уже мозг отказывается воспринимать английский язык и продавать свои навыки. Вот это косяк.
[quote="Gres"]Да не парься, ты же не на собеседовании. Главное, чтобы твой код хорошо работал.[/quote]
Ну, незнание многих теоретических тем, это парит меня меньше всего :) . Знание практических аспектов webdev, я уверен, перекрывает этот скромный недостаток :) .
Парит то, что мой старый уже мозг отказывается воспринимать английский язык и продавать свои навыки. Вот это косяк.
сопутствующий вопрос:
всегда ли вы берете DML операцию в трай-кетч (в контроллерах к примеру) или даете самому СФ "обработать" исключительную ситуацию с DML? я это к тому, что может все эти мои Кетчи и не нужны вовсе...
сопутствующий вопрос:
всегда ли вы берете DML операцию в трай-кетч (в контроллерах к примеру) или даете самому СФ "обработать" исключительную ситуацию с DML? я это к тому, что может все эти мои Кетчи и не нужны вовсе...
сопутствующий вопрос:
всегда ли вы берете DML операцию в трай-кетч (в контроллерах к примеру) или даете самому СФ "обработать" исключительную ситуацию с DML? я это к тому, что может все эти мои Кетчи и не нужны вовсе...
У меня все DML в *DAO классах, которые используют реализацию IDatabase (insert, update, delete) Соответственно, есть всего 3 конструкции на весь проект.
[quote="Den Brown"]сопутствующий вопрос:
всегда ли вы берете DML операцию в трай-кетч (в контроллерах к примеру) или даете самому СФ "обработать" исключительную ситуацию с DML? я это к тому, что может все эти мои Кетчи и не нужны вовсе...[/quote]
У меня все DML в *DAO классах, которые используют реализацию IDatabase (insert, update, delete)
Соответственно, есть всего 3 конструкции на весь проект.
IDatabase
Ну и ты доволен своей реализацией, особенно если нужно работать с sObject ? как насчет Upsert ?
[quote="wilder"]Ну и ты доволен своей реализацией, особенно если нужно работать с sObject ?[/quote]
Доволен, в IDatabase как раз sObject.
[quote="wilder"]как насчет Upsert ?[/quote]
Если он необходим реализуется в *DAO.
Я все жду пока они доделают нормальную реализацию апсерта.
[quote="Gres"]У меня все DML в *DAO классах, которые используют реализацию IDatabase (insert, update, delete) [/quote]
Получается, что вы создали для ДМЛ оперций свои собственные классы, с блекджеком и шл... и кастомной обработкой исключений??
У меня все DML в *DAO классах, которые используют реализацию IDatabase (insert, update, delete)
Получается, что вы создали для ДМЛ оперций свои собственные классы, с блекджеком и шл... и кастомной обработкой исключений??
[quote="Den Brown"][quote="Gres"]У меня все DML в *DAO классах, которые используют реализацию IDatabase (insert, update, delete) [/quote]
Получается, что вы создали для ДМЛ оперций свои собственные классы, с блекджеком и шл... и кастомной обработкой исключений??[/quote]
И не только для DML, а так да, правильно.
У меня все DML в *DAO классах, которые используют реализацию IDatabase (insert, update, delete)
[quote="Den Brown"]У меня все DML в *DAO классах, которые используют реализацию IDatabase (insert, update, delete)[/quote]
А где можно узнать поподробней об этом для SF?
У меня все DML в *DAO классах, которые используют реализацию IDatabase (insert, update, delete)
А где можно узнать поподробней об этом для SF?
Можешь просто прочитать про паттерны Data Access Object и Repository
[quote="DevNull"][quote="Den Brown"]У меня все DML в *DAO классах, которые используют реализацию IDatabase (insert, update, delete)[/quote]
А где можно узнать поподробней об этом для SF?[/quote]
Можешь просто прочитать про паттерны Data Access Object и Repository
Я для таких ситуаций написал тест хелпер и метод в ньом ThrowExceptionIfTesting которий смотрит на Test.isRunningTest и на статическую булевую переменую, которой можно контролировать в каких ситуациях вибрасивать ексепшен. И етот метод пишу try блоке.
Так делать в принципе не правильно. Код не должен подстраиваться под тесты. Все должно быть наоборот.
А как быть, если необходимо отключить триггер в тестах?
[quote="Gres"][quote="Alex Tsitsura"]Я для таких ситуаций написал тест хелпер и метод в ньом ThrowExceptionIfTesting которий смотрит на Test.isRunningTest и на статическую булевую переменую, которой можно контролировать в каких ситуациях вибрасивать ексепшен. И етот метод пишу try блоке.[/quote]
Так делать в принципе не правильно. Код не должен подстраиваться под тесты. Все должно быть наоборот.[/quote]
А как быть, если необходимо отключить триггер в тестах?
Я для таких ситуаций написал тест хелпер и метод в ньом ThrowExceptionIfTesting которий смотрит на Test.isRunningTest и на статическую булевую переменую, которой можно контролировать в каких ситуациях вибрасивать ексепшен. И етот метод пишу try блоке.
Так делать в принципе не правильно. Код не должен подстраиваться под тесты. Все должно быть наоборот.
А как быть, если необходимо отключить триггер в тестах?
Для отключения триггера используются кастом сеттинги.
[quote="ogoblin"][quote="Gres"][quote="Alex Tsitsura"]Я для таких ситуаций написал тест хелпер и метод в ньом ThrowExceptionIfTesting которий смотрит на Test.isRunningTest и на статическую булевую переменую, которой можно контролировать в каких ситуациях вибрасивать ексепшен. И етот метод пишу try блоке.[/quote]
Так делать в принципе не правильно. Код не должен подстраиваться под тесты. Все должно быть наоборот.[/quote]
А как быть, если необходимо отключить триггер в тестах?[/quote]
Для отключения триггера используются кастом сеттинги.
Для отключения триггера используются кастом сеттинги.
даю свой +1 за этот метод. Отличное кстати решение - отключение функционала по настройкам в custom settings.
[quote="Gres"]Для отключения триггера используются кастом сеттинги.[/quote]
даю свой +1 за этот метод. Отличное кстати решение - отключение функционала по настройкам в custom settings.
Возможно вы и правы оба. Только в таком случае не вижу разницы, что проверять - переменную в триггере или сеттинги. Задача была до горя простая. Речь о тест-юните в пакете. 1. Отключить триггер. 2. Залить старые данные. 3. Проверить конвертацию. Эта вся муть выполняется после установки пакета в процессе тестов.
Возможно вы и правы оба. Только в таком случае не вижу разницы, что проверять - переменную в триггере или сеттинги.
Задача была до горя простая. Речь о тест-юните в пакете.
1. Отключить триггер.
2. Залить старые данные.
3. Проверить конвертацию.
Эта вся муть выполняется после установки пакета в процессе тестов.