IE2017

Написание простой обработки через тестирование

Программирование - Практика программирования

Раньше я считал, что в 1С невозможно юнит-тестирование (ведь тут нет вездесущих объектов, привычных классов и и. т.). Иногда на Инфостарте появлялись специализированные обработки, но часто они скорее отпугивали от темы тестирования, чем привлекали к ней. Потом я узнал про xUnitFor1C. Оказалось, что тестирование в 1С в общем не так уж и сложно, даже в сравнении с другими языками. В данной статье я расскажу о своем первом опыте.

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

А так-же разработчикам xUnitFor1C за замечательный набор инструментов.

Статья не претендует на истину в последней инстанции или на руководство. Скорее наоброт - я надеюсь, что она будет раскритикована и в комментариях гуру покажут мастер-класс написания тестов.

xUnitFor1C это набор внешних обработок 1с, облегчающих, а главное, упорядочивающих тестирование. В этой статье будет использоваться только xddTestRunner.epf (тестов выполнятель).

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

Готовим окружение. 

Набор тестов - это обработка, содержащаа экспортную функцию ПолучитьсписокТестов(ЮнитТестирование). В документации предложен шаблон такой обработки. Создаем её и сохраняем. Модуль обработки выглядит так:

Перем ЮТест; // ссылка на экземпляр фреймворка xUnitFor1C - объект обработки UnitTestRunner

Перем ОбработкаОбъект;
Перем ИмяФайлаВнешнейОбработки;

Функция ПолучитьСписокТестов(ЮнитТестирование) Экспорт

    	ЮТест = ЮнитТестирование;

    	ВсеТесты = Новый Массив;

    	ВсеТесты.Добавить("ТестДолжен_СложитьДваИДва");

    Возврат ВсеТесты;

КонецФункции

Процедура ПередЗапускомТеста() Экспорт
	ОбработкаОбъект = ВнешниеОбработки.Создать(ИмяФайлаВнешнейОбработки);
	НачатьТранзакцию();
КонецПроцедуры

Процедура ПослеЗапускаТеста() Экспорт
	Если ТранзакцияАктивна() Тогда
		ОтменитьТранзакцию();
	КонецЕсли;
  	ОбработкаОбъект = Неопределено;
КонецПроцедуры

Процедура ТестДолжен_СложитьДваИДва() Экспорт
    ЮТест.ПроверитьРавенство(2 + 2, 5, "2 + 2, 4");
КонецПроцедуры

/////////////////////////////////////////////////////////
//Здесь будем писать наши тесты

 
ИмяФайлаВнешнейОбработки = "E:\todo1c\develop\epf\todo1c.epf";

Запускаем xddTestRunner.epf. Для меня интерфейс оказался неожиданно дружелюбным. Загружаем тесты из каталога. Проверяем. Должен появиться один тест. Тест должен провалиться. Исправляем тест.

 ЮТест.ПроверитьРавенство(2 + 2, 4, "2 + 2, 4"); // ошибка исправлена

Теперь тест должен пройти успешно.

Цикл разработки.

1) Создаем неработающий тест

Функция ПолучитьСписокТестов(ЮнитТестирование) Экспорт

    	...
    	ВсеТесты.Добавить("ТестДолжен_ДобавитьЗадачу");
        ...
    
КонецФункции
Процедура ТестДолжен_ДобавитьЗадачу() Экспорт
	
    ОбработкаОбъект.ДобавитьЗадачу("Пройти первый тест");	
    
    ЮТест.ПроверитьРавенство(ОбработкаОбъект.СписокЗадач.Количество(), 1, "Задача не добавлена");
	
КонецПроцедуры

Перезагружаем список тестов, проверяем тестов теперь 2 и второй провалился.

2) Делаем ровно столько, чтобы тест прошел успешно.

Содаем табличную часть в обработке с полями "выполнена" и "текст".

Добавляем в модуль

Процедура ДобавитьЗадачу(ТекстЗадачи) Экспорт
	
	НоваяЗадача = СписокЗадач.Добавить();
	НоваяЗадача.Выполнена = Ложь;
	НоваяЗадача.Текст = ТекстЗадачи;
	
КонецПроцедуры

Проверяем, что тест прошел.

3) Рефакторинг.

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

Согласно TDD шаги 1,2,3 постоянно повторяются, причем длительность итерации должна быть как можно меньше. 

Независимость тестов.

Для обеспечения независимости предусмотрены следующие процедуры:

Процедура ПередЗапускомТеста() Экспорт
	ОбработкаОбъект = ВнешниеОбработки.Создать(ИмяФайлаВнешнейОбработки);
	НачатьТранзакцию();
КонецПроцедуры

Процедура ПослеЗапускаТеста() Экспорт
	Если ТранзакцияАктивна() Тогда
		ОтменитьТранзакцию();
	КонецЕсли;
  	ОбработкаОбъект = Неопределено;
КонецПроцедуры

При необходимости повторить...

1) Тест

Процедура ТестДолжен_ВыполнитьЗадачу() Экспорт
	
    ОбработкаОбъект.ДобавитьЗадачу("Пройти второй тест");	
    ЮТест.ПроверитьРавенство(ОбработкаОбъект.СписокЗадач[0].Выполнена, Ложь, "Задача создана выполненной");
    ОбработкаОбъект.ВыполнитьЗадачу(0);	
    ЮТест.ПроверитьРавенство(ОбработкаОбъект.СписокЗадач[0].Выполнена, Истина, "Задача не выполнена");
	
КонецПроцедуры

2) Реализация

Процедура ВыполнитьЗадачу(ИндексЗадачи) Экспорт
	
	СписокЗадач[ИндексЗадачи].Выполнена = Истина;
	
КонецПроцедуры

При необходимости повторить снова..

Полностью процесс написания можно посмотреть по коммитам в репозитории на github 

https://github.com/Alienjob/todo1c/commits/master

Не нашел как сделать скачивание бесплатным, так что в том репозитории есть и приложенный к статье архив. 

Спасибо за внимание, надеюсь найдутся люди которые после этой статьи примут на вооружение описанные принципы и мир станет чуточку лучше.

P.S.: Кто здесь?

Когда появляется вопрос "как составить запрос", "как сделать печатную форму", ответ тут же находится. В конце концов, можно посмотреть, как это сделано в типовой конфигурации. Но когда появились вопросы "А что же мне писать в тесты? А как тестировать отчеты? А управляемые формы? А запись в базу?" в типовых конфигурациях ответов я не нашел. Ну и пришлось изобретать свои костыли..

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

Скачать файлы

Наименование Файл Версия Размер
Архив со всеми файлами
.7z 41,51Kb
24.02.15
12
.7z 41,51Kb 12 Скачать

См. также

Комментарии
1. Андрей Овсянкин (Evil Beaver) 4202 24.02.15 10:14 Сейчас в теме
кто-то уже применяет эти подходы (раз кто-то написал xddTestRunner)

Мы применяем и наблюдаем положительный эффект.
2. Xer shi (Xershi) 274 24.02.15 10:22 Сейчас в теме
Эта работа с тестами нужна чтобы выявить косяки разработки?
3. Игорь Пашутин (Alien_job) 114 24.02.15 10:27 Сейчас в теме
(1) Evil Beaver, А как вы тестируете отчеты (табличные документы)? Если я рисую табличный документ заранее то он отличается от уже признаком "макет" и отсутствием имен полей. В конце концов я пришел к тому что сначала добиваюсь правильного внешнего вида отчета, сохраняю его в файл и загружаю файл в макет. В результате малейшее изменение требований (изменить формат даты в заголовке) приведет к падению всех тестов.
4. Артур Аюханов (artbear) 877 24.02.15 10:29 Сейчас в теме
Молодец, что юзаешь наш продукт xUnitFor1C.спасибо за статью.
Только почему не указываешь прямую ссылку на проект?
И почему мало о нем знаешь? :)
есть сообщество, есть пользователи, есть разработчики, в тч и я, который фактически productOwner продукта.
есть много многолетнего опыта в тестировании для 1С
5. Игорь Пашутин (Alien_job) 114 24.02.15 10:31 Сейчас в теме
(2) Xershi, работа с тестами конечно занимает время - но это время окупается сразу за счет отладки (при таком подходе отладка не нужна). Плюс на выходе получается код покрытый тестами, который проще сопровождать.
6. Игорь Пашутин (Alien_job) 114 24.02.15 11:01 Сейчас в теме
(4) artbear, ссылку на проект указал. Сообщество (обсуждения) не нашел. Прочитал вики на сайте проекта. Пожалуй эта вся информация которую я смог найти. Не нашел сквозных примеров использования а без них мне непонятно как этим всем пользоваться.
7. Артур Аюханов (artbear) 877 24.02.15 11:30 Сейчас в теме
(6) По тестированию и ТДД есть мое старое выступление с Инфостарт 2012 - статья http://infostart.ru/public/326820
Также есть видео-обучение от Алексея Лустина и Евгения Павлюка http://infostart.ru/public/328695/
Также есть мое выступление с Инфостарт 2013 - где я рассказываю про xUnitFor1C
Примеры есть в самом репозитарии.
Конечно, я соглашусь, что информации маловато и нужно больше популяризовать.
endym; theshadowco; Alien_job; +3 Ответить
8. Артур Аюханов (artbear) 877 24.02.15 11:33 Сейчас в теме
(0) На мисте я периодически отвечаю на темы по тестированию
Например, http://www.forum.mista.ru/topic.php?id=730184 или http://www.forum.mista.ru/topic.php?id=710900

(6) Что такое "сквозной пример использования" ?
Еще какие вопросы есть?
Пиши вопросы по тестированию.
Готов ответить.

Можно в личку hangouts "aartbear@gmail.com" или skype "aartbear"
9. Василий Казьмин (awk) 679 24.02.15 11:37 Сейчас в теме
(5) Alien_job, Дешево, быстро, качественно - выбирай любые два.
10. Игорь Пашутин (Alien_job) 114 24.02.15 11:47 Сейчас в теме
(8) artbear, возможно после просмотра видео вопросов станет меньше. Сквозной пример - статья в которой демонстрируется написание обработки через тестирование. С использованием всех возможностей xUnitFor1C и с освещением типовых задач тестирования (модули, формы, отчеты, обмены, ...).
11. Максим Жохов (ZhokhovM) 283 24.02.15 12:23 Сейчас в теме
(6) Alien_job, я тоже не нашел примеров. У меня свои наработки: Универсальное тестирование конфигурации (обычные и управляемые формы). Часть 1. Скоро выйдет в свет новая часть.
12. Игорь Пашутин (Alien_job) 114 24.02.15 13:07 Сейчас в теме
(11) ZhokhovM, из описания не понятно можно ли вашей обработкой тестировать внешние обработки. У xUnitFor1C есть тесты_ОткрытиеФормКонфигурации.epf - формирует тесты на открытие всех форм и если в конфигурации есть синтаксические ошибки то часть тестов упадет. Правда на УПП 1.3 в лоб использовать её у меня не получилось - многие формы "не предназначены для открытия" =)
Примеры "нашлись" https://github.com/xDrivenDevelopment/xUnitFor1C/tree/develop/Tests/CommonA­pp .
13. Евгений Сосна (pumbaE) 552 24.02.15 13:19 Сейчас в теме
(12) Alien_job, после первого запуска вы можете прописать себе исключения форм, которые не могут работать просто так.
artbear; vikad; +2 Ответить
14. Максим Жохов (ZhokhovM) 283 24.02.15 14:00 Сейчас в теме
(12) Alien_job, я исключаю формы или предупреждения с помощью cmdow, а так моя публикация проверяет формы: получает объекты форм и открывает форму. А ошибки я копирую из окошка "Информация для технической поддержки", т.к. там показывают полные ошибки чем ошибки в ЖР.
15. Артур Аюханов (artbear) 877 24.02.15 14:03 Сейчас в теме
(10) 1. К сожалению, Это слишком общая формулировка примера. описание будет слишком длинным и специализированным к конкретной конфигурации и задаче, и наверняка будет много лишних деталей, неинтересных читателям.
2. можно тестировать не отдельно модули, формы, отчеты, обмена, а делать тесты в целом под задачу. часто это бывает проще и эффективнее. Это разделение на юнит-тесты и на приемочные тесты.
16. Артур Аюханов (artbear) 877 24.02.15 14:11 Сейчас в теме
(11) Ты там схитрил и удалил старые и полезные комментарии :(

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

были и еще замечания, но ты их потер :(
17. Максим Жохов (ZhokhovM) 283 24.02.15 15:12 Сейчас в теме
(16) artbear, нет, там были ошибки в редактировании публикации после отказа заключения договора с отделом продаж, поэтому я её удалил и перенес всю информацию на новую, меня просто не устраивал стартмани 1$m.
18. Леонид Паутов (Pr-Mex) 104 25.02.15 14:18 Сейчас в теме
(8) artbear, люди хотят больше реальных примеров.
Помнишь тему, чтобы сделать примером разработки через тестирование на типовых конфах?

От себя добавлю, что тоже использую xUnitFor1C в повседневной разработке.
Наша команда разрабатывает конфу, которой уже 7 лет. И только недавно перешли на разработку через тесты. По полной столкнулись с проблемами рефакторинга, легаси кода и т.д.
Итого - бояться тут нечего. Всё решаемо. Билд сервер крутится, отчет о прохождении тестов приходит.
19. Максим Жохов (ZhokhovM) 283 27.02.15 12:36 Сейчас в теме
(16) artbear, пока я изучу тесты и реализаций Тесты_ОткрытиеФормКонфигурации.epf и возможно у себя переделаю.
20. gorokhov.vladislav (magnetto72) 23.03.15 14:35 Сейчас в теме
Большое спасибо за статью, позволяющую быстро понять как освоить технику и инструмент.
Подскажите, пожалуйста, каким образом, можно написать тест на процедуру проведения документа? Ведь в ней могут вызываться другие связанные функции и процедуры.
Можно ли где-то посмотреть пример тестирования кода проведения документов?

Подскажите существует ли форум где можно задавать вопросы, обсуждать приемы использования xUnitFor1C?
21. Игорь Пашутин (Alien_job) 114 24.03.15 07:18 Сейчас в теме
(20) gorokhov.vladislav, полагаю нужно после проведения получить коллекцию движений документа и сравнить её с эталоном.
форум где можно задавать вопросы, обсуждать приемы использования xUnitFor1C

почему бы не инфостарт?
пример тестирования

https://github.com/xDrivenDevelopment/xUnitFor1C/tree/develop/Tests/CommonA­­pp , других нет
22. Владислав Горохов (magnetto72) 24.03.15 08:06 Сейчас в теме
(21) Alien_job,
Спасибо за ответ. Я не могу понять как создать/зафиксировать эталон движений, где он должен сохраниться.
При тестировании отчета формирую его, создаю макет "Эталон", копирую в него табличный документ, получаю эталон с правильным результатами.
В "1С:Сценарное тестирование" для этого есть специальное действие "Сравнить движение документа с эталоном", которое снимает "слепок" с эталонной базы, сохраняет все значения в сценарий и затем при прогоне сверяет с тем, что получилось.

А как зафиксировать эталон для движений в xUnitFor1C?
23. Игорь Пашутин (Alien_job) 114 24.03.15 09:25 Сейчас в теме
(22) magnetto72,
у "Генерация макета на базе реальных данных для xUnitFor1C" есть "СоздатьМакетДанныхНаОснованииЗапроса". Думаю можно выбрать запросом движения документа, создать макет, сохранить его как эталон. В тесте создавать макет на основании запроса и сверять с эталоном.
24. Артур Аюханов (artbear) 877 25.03.15 16:39 Сейчас в теме
(20) gorokhov.vladislav,
По xUnitFor1C предложение и обсуждение удобнее всего вести в одном из 2 вариантах:
1. Можно на Инфостарте в комментах к моей статье http://infostart.ru/public/326820/ (Методики и механизмы разработки/тестирования в 1С)
или
2. Можно на Гитхабе https://github.com/xDrivenDevelopment/xUnitFor1C/issues
25. Артур Аюханов (artbear) 877 25.03.15 16:51 Сейчас в теме
(22) Ответил в комментах к моей статье.
26. Alex Strizh (strizhhh) 20.02.17 16:04 Сейчас в теме
Было бы неплохо поработать над документацией, так как инструмент добротный, а вот порог вхождения для пользователей такой, что нужно код читать, чтобы понять как этим пользоваться.
klinval; ivanov660; +2 Ответить 2
27. Тимур - (leemuar) 21.02.17 14:57 Сейчас в теме
(26) Задача такая есть. Подключитесь, помогите с этим
28. ivanov660 ivanov660 (ivanov660) 339 28.02.17 17:27 Сейчас в теме
(26) Соглашусь с коллегой.
У нас появилась задача интеграции в наш механизм тестирования юнит тестов автора. Вот с написанием и особенно отладкой тестов что-то не совсем заладилось.
Простой тест 2+2<>4 написали без проблем, а вот реальный тест проверки формирования по входным документам набора выходных документов пока тяжко.
29. Alex Strizh (strizhhh) 28.02.17 18:18 Сейчас в теме
(28) Насколько я понимаю, авторы (команда разработчиков) внедряют решения с помощью этих своих разработках за деньги (что логично и понятно), поэтому ждать понятной "для любителя" документации, думаю, не стоит.
30. Артур Аюханов (artbear) 877 02.03.17 10:04 Сейчас в теме
(29) Не совсем так.
С документацией всегда сложно, разработчики ее не любят делать :)
Тут процесс итерационный, документация набирается постепенно.
пробовали на Вики проекта xUnitFor1C заходить, там накоплено много информации
Вики xUnitFor1C
31. Alex Strizh (strizhhh) 02.03.17 10:34 Сейчас в теме
(30) Лично я заходил и некоторая информация мне оттуда помогла, бесспорно. Но там много устаревшей и не актуальной информации. Да и утверждение моё о документации было связано с порогом вхождения: я два дня потратил чтобы найти, вычленить нужную мне часть, отбросить лишнее (устаревшее и нерабочее) и прийти к выводу, что времени только на понятие и практику применения ушло в десятки раз больше, чем на другие инструменты. Конечно, я не отрицаю того факта, что я просто тупой.

Не хватает также демонстрации реальной (боевой) практики применения инструмента на реальных проектах. Что закрыло бы много вопросов, как мне кажется.
Оставьте свое сообщение