gifts2017

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

Опубликовал Игорь Пашутин (Alien_job) в раздел Программирование - Практика программирования

Раньше я считал, что в 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
9
.7z 41,51Kb 9 Скачать

См. также

Подписаться Добавить вознаграждение

Комментарии

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

Мы применяем и наблюдаем положительный эффект.
2. Xer shi (Xershi) 24.02.15 10:22
Эта работа с тестами нужна чтобы выявить косяки разработки?
3. Игорь Пашутин (Alien_job) 24.02.15 10:27
(1) Evil Beaver, А как вы тестируете отчеты (табличные документы)? Если я рисую табличный документ заранее то он отличается от уже признаком "макет" и отсутствием имен полей. В конце концов я пришел к тому что сначала добиваюсь правильного внешнего вида отчета, сохраняю его в файл и загружаю файл в макет. В результате малейшее изменение требований (изменить формат даты в заголовке) приведет к падению всех тестов.
4. Артур Аюханов (artbear) 24.02.15 10:29
Молодец, что юзаешь наш продукт xUnitFor1C.спасибо за статью.
Только почему не указываешь прямую ссылку на проект?
И почему мало о нем знаешь? :)
есть сообщество, есть пользователи, есть разработчики, в тч и я, который фактически productOwner продукта.
есть много многолетнего опыта в тестировании для 1С
5. Игорь Пашутин (Alien_job) 24.02.15 10:31
(2) Xershi, работа с тестами конечно занимает время - но это время окупается сразу за счет отладки (при таком подходе отладка не нужна). Плюс на выходе получается код покрытый тестами, который проще сопровождать.
6. Игорь Пашутин (Alien_job) 24.02.15 11:01
(4) artbear, ссылку на проект указал. Сообщество (обсуждения) не нашел. Прочитал вики на сайте проекта. Пожалуй эта вся информация которую я смог найти. Не нашел сквозных примеров использования а без них мне непонятно как этим всем пользоваться.
7. Артур Аюханов (artbear) 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) 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) 24.02.15 11:37
(5) Alien_job, Дешево, быстро, качественно - выбирай любые два.
10. Игорь Пашутин (Alien_job) 24.02.15 11:47
(8) artbear, возможно после просмотра видео вопросов станет меньше. Сквозной пример - статья в которой демонстрируется написание обработки через тестирование. С использованием всех возможностей xUnitFor1C и с освещением типовых задач тестирования (модули, формы, отчеты, обмены, ...).
11. Максим Жохов (ZhokhovM) 24.02.15 12:23
(6) Alien_job, я тоже не нашел примеров. У меня свои наработки: Универсальное тестирование конфигурации (обычные и управляемые формы). Часть 1. Скоро выйдет в свет новая часть.
12. Игорь Пашутин (Alien_job) 24.02.15 13:07
(11) ZhokhovM, из описания не понятно можно ли вашей обработкой тестировать внешние обработки. У xUnitFor1C есть тесты_ОткрытиеФормКонфигурации.epf - формирует тесты на открытие всех форм и если в конфигурации есть синтаксические ошибки то часть тестов упадет. Правда на УПП 1.3 в лоб использовать её у меня не получилось - многие формы "не предназначены для открытия" =)
Примеры "нашлись" https://github.com/xDrivenDevelopment/xUnitFor1C/tree/develop/Tests/CommonA­pp .
13. Евгений Сосна (pumbaE) 24.02.15 13:19
(12) Alien_job, после первого запуска вы можете прописать себе исключения форм, которые не могут работать просто так.
artbear; vikad; +2 Ответить
14. Максим Жохов (ZhokhovM) 24.02.15 14:00
(12) Alien_job, я исключаю формы или предупреждения с помощью cmdow, а так моя публикация проверяет формы: получает объекты форм и открывает форму. А ошибки я копирую из окошка "Информация для технической поддержки", т.к. там показывают полные ошибки чем ошибки в ЖР.
15. Артур Аюханов (artbear) 24.02.15 14:03
(10) 1. К сожалению, Это слишком общая формулировка примера. описание будет слишком длинным и специализированным к конкретной конфигурации и задаче, и наверняка будет много лишних деталей, неинтересных читателям.
2. можно тестировать не отдельно модули, формы, отчеты, обмена, а делать тесты в целом под задачу. часто это бывает проще и эффективнее. Это разделение на юнит-тесты и на приемочные тесты.
16. Артур Аюханов (artbear) 24.02.15 14:11
(11) Ты там схитрил и удалил старые и полезные комментарии :(

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

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

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

Подскажите существует ли форум где можно задавать вопросы, обсуждать приемы использования xUnitFor1C?
21. Игорь Пашутин (Alien_job) 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) 24.03.15 09:25
(22) magnetto72,
у "Генерация макета на базе реальных данных для xUnitFor1C" есть "СоздатьМакетДанныхНаОснованииЗапроса". Думаю можно выбрать запросом движения документа, создать макет, сохранить его как эталон. В тесте создавать макет на основании запроса и сверять с эталоном.
24. Артур Аюханов (artbear) 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) 25.03.15 16:51
(22) Ответил в комментах к моей статье.
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа