О Unit-тестах замолвите слово. Часть 2

22.07.19

Разработка - Инструментарий разработчика

Пара практических примеров написания Unit-тестах с использованием фреймворка Vanessa-ADD.

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

Наименование Файл Версия Размер
Шаблон обработки для написания Unit-теста
.epf 5,12Kb
2
.epf 5,12Kb 2 Скачать

Подготовка

Тесты будем писать с использованием фреймворка Vanessa-ADD.

Самый простой путь к его установке - менеджер пакетов OneScript. Скачать его можно тут: http://oscript.io/.

После того как будет установлен OneScript нам будет достаточно открыть командную строку и выполнить:

opm install add

После выполнения команды в папке с библиотеками OneScript (C:\Program Files (x86)\OneScript\Lib\) появится папка add. В ней будут лежать компоненты фреймворка Vanessa-Add.

Нас прежде всего интересуют файлы, относящиеся к части xUnit (фреймворк для Unit-тестирования):

  • Внешняя обработка xddTestRunner.epf - обработка для запуска Unit-тестов
  • Набор плагинов, который располагается в папке add/plugins

Подробнее о запуске тестов и использовании плагинов можно почитать в документации тут.

Организация хранения тестов и состав набора тестов

Для того чтобы практические примеры лучше читались, разберем как тесты хранятся и из чего состоят наборы тестов.

Тесты располагаются в модулях внешних обработок, каждая обработка может содержать несколько тестов, разделенных на группы.

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

-- модуль менеджера/модуль объекта либо функциональная область

Например, такая структура файлов и папок:
- Документ.Заказ клиента

-- Тест_ЗаказКлиентаОбъект.epf

-- Тест_ЗаказКлиентаМенеджер.epf

Каждая внешняя обработка состоит из следующих частей:

Инструментарий

В основном в тестах мы будем использовать следующие плагины:

  • ТекучиеУтверждения - плагин предоставляющий методы для проверки утверждений
// Пример проверки значения
// Ожидаем - плагин ТекучиеУтверждениея
// Что() - передаем плагину значение для проверки
// Равно() - вызываем процедуру сравнения переданного значения с эталоном
Ожидаем.Что(ПроверямоеЗначение).Равно(1);

// Пример проверки метода
// Что() - передаем плагину расположения проверяемого метода
// Метод() - передаем плагину имя метода и его параметры
// ВыбрасываетИсключение() - провермя, что метод выбросил определенное исключение
Ожидаем.Что(ОбщийМодуль).Метод(ИмяМетода).ВыбрасываетИсключение("Наше исключение");
  • Данные - плагин для генерации данных, необходимых для теста

// Данные - плагин
// НачатьСоздание() - Объявляем какой объект нужно создать Справочник, Документ, Набор записей регистра накопления  или сведений
// Реквизит() - объявляем, что у нашего объекта будет заполнен реквизит определенным значением
// ШапкаТабличнойЧасти() - объявляем, что у создаваемого объекта будет заполнены табличная часть и некоторые из её колонок
// СтрокаТЧ() - описываем какими именно значениями будет заполнена строка табличной части
// Создать() - завершаем создание объекта, по умолчанию объект записывается в базу и возвращается ссылка на него
Данные.НачатьСоздание("Документ.ДокументСДвижениями")
	.Реквизит("РеквизитПростойСправочник")
	.ШапкаТабличнойЧасти("ТЧ","Реквизит1", "РесурсЧисло")
		.СтрокаТЧ("Элемент1", 10)
		.СтрокаТЧ("Элемент2", 15).Создать();

Более подробно о плагинах можно прочитать на страницах документации.

К сожалению не для всех плагинов есть документация, но в них можно легко разобраться, открыв сами плагины в каталоге add/plugins =)

Пример теста: Распределение значений по базе

У нас реализована собственная подсистема Бюджетирования. Нам была необходима функция, которая будет распределять затраты, которые были сформированы в одних подразделениях на другие подразделения, в зависимости от их показателей.

Рассмотрим пример проверки функции распределения:

	// Создадим тестовые подразделения первичных затрат
	Подразделение1 = Данные.СоздатьЭлементСправочника("СтруктураПредприятия");
	Подразделение2 = Данные.СоздатьЭлементСправочника("СтруктураПредприятия");
	
	// Тут мы подготавливаем описание колонок таблиц, которые будут передваться нашей функции
	Колонка_АналитикаДоходовРасходов = Данные.ОписаниеКолонкиТЧ("АналитикаДоходовРасходов", Новый ОписаниеТипов("СправочникСсылка.СтруктураПредприятия"));
	Колонка_Ресурс1 = Данные.ОписаниеКолонкиТЧ("Ресурс1", Новый ОписаниеТипов("Число"));
	Колонка_Ресурс2 = Данные.ОписаниеКолонкиТЧ("Ресурс2", Новый ОписаниеТипов("Число"));
	Колонка_АналитикаРасходов = Данные.ОписаниеКолонкиТЧ("АналитикаРасходов", Новый ОписаниеТипов("СправочникСсылка.СтруктураПредприятия"));
	Колонка_Коэффициеннт = Данные.ОписаниеКолонкиТЧ("Коэффициент", Новый ОписаниеТипов("Число"));

	// Создадим тестовые подразделения, на которые необходимо распределить затраты
	ПодразделениеРаспределения3 = Данные.СоздатьЭлементСправочника("СтруктураПредприятия");
	ПодразделениеРаспределения4 = Данные.СоздатьЭлементСправочника("СтруктураПредприятия");
	
	// Формируем таблицу первоначальных затрат
	ИсходнаяТаблица = Данные.НачатьСоздание("ТаблицаЗначений")	
		.ШапкаТабличнойЧасти(, Колонка_АналитикаДоходовРасходов, Колонка_Ресурс1, Колонка_Ресурс2)
		.СтрокаТЧ(Подразделение1, 10, 10)
		.СтрокаТЧ(Подразделение2, 20, 10).Создать();
	 
	// Формируем таблицу коэффициентов
	ТаблицаКоэффицентов = Данные.НачатьСоздание("ТаблицаЗначений")	
		.ШапкаТабличнойЧасти(, Колонка_АналитикаРасходов, Колонка_Коэффициеннт)
		.СтрокаТЧ(ПодразделениеРаспределения3, 0.4)  
		.СтрокаТЧ(ПодразделениеРаспределения4, 0.6).Создать(); 

	// Формируем таблицу эталон, для проверки результата работы функции
	Эталон = Данные.НачатьСоздание("ТаблицаЗначений")	
		.ШапкаТабличнойЧасти(, Колонка_АналитикаДоходовРасходов, Колонка_Ресурс1, Колонка_Ресурс2, "АналитикаДоходовРасходовИсточник")
		.СтрокаТЧ(ПодразделениеРаспределения3, 4, 4, Подразделение1)
		.СтрокаТЧ(ПодразделениеРаспределения4, 6, 6, Подразделение1)
		.СтрокаТЧ(ПодразделениеРаспределения3, 8, 4, Подразделение2)
		.СтрокаТЧ(ПодразделениеРаспределения4, 12, 6, Подразделение2).Создать();
	

	// Выполняем функцию
	Справочники.ИсточникиДанныхБюджета.РаспределитьПоКоэффициентам(ИсходнаяТаблица, ТаблицаКоэффицентов);

	// Сравниваем эталон и результат работы нашей функции
	СравнениеТаблиц.ПроверитьРавенствоТаблиц(Эталон, ИсходнаяТаблица);

Стоит отметить, что коэффициенты и значения затрат подобраны не очень хорошо, т.к. при таких значениях не возникает проблемы копеек.

Пример теста: разбор информации об обновлениях мобильного приложения

На складе компании используется приложение на мобильной платформе 1С. Из-за политики безопасности мы не можем распространять обновления через GooglePlay. Поэтому мы написали приложение, которое проверяет наличие обновлений на сервере (сравнение версии установленного приложения с настройками, хранящимися на сервере) и устанавливает обновление, если оно есть. 

Мы рассмотрим тест на разбор файла настроек, которые загружаются с сервера:


Процедура Тест_ЧтениеИнформациисСервера_НесколькоНастроек() Экспорт
	
		
	Настройка = ШаблонНастройки("version_несколько_настроек");

    // Процедура читает файл переданной настройки и заполняет справочник "Конфигурации" 
	ОбновлениеКонфигурацийВызовСервера.ЗагрузитьОписаниеВерсийССервера(Настройка, Ложь);	
	
    // Проверяем, что настройка прочитана корректно
	ЗагруженнаяНастройка = Справочники.Конфигурации.НайтиПоНаименованию("ru.yarvet.mw");
	Ожидаем.Что(ЗагруженнаяНастройка.ИмяФайлаОбновления).Равно("тест")
		.Что(ЗагруженнаяНастройка.ВерсияСервера).Равно("2.1.0");
	
	ЗагруженнаяНастройка = Справочники.Конфигурации.НайтиПоНаименованию("ru.yarvet.launcher");
	Ожидаем.Что(ЗагруженнаяНастройка.ИмяФайлаОбновления).Равно("тест2")
		.Что(ЗагруженнаяНастройка.ВерсияСервера).Равно("1.1.0");
	
КонецПроцедуры

// Функция возвращает путь до файла с тетсовой настройки
Функция ШаблонНастройки(Настройка)

    // ИспользуемоеИмяФайла - путь до обработки теста, стандартный реквзит внешней обработки
	ОписаниеТеста = Новый Файл(ИспользуемоеИмяФайла);	
	Возврат ОписаниеТеста.Путь + ПолучитьРазделительПути() + Настройка+".json";

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

Собственно сам файл настройки выглядит так:

[
    {
        "application": "ru.yarvet.mw",
        "version":"2.1.0",
        "updateFile":"тест"
    },
    {
        "application": "ru.yarvet.launcher",
        "version":"1.1.0",
        "updateFile":"тест2"
    }
]

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

P.S.

Рассуждение о том, в каких случаях лучше писать unit-тесты было тут.

Unit-тесты

См. также

SALE! 20%

Infostart Toolkit: Инструменты разработчика 1С 8.3 на управляемых формах

Инструментарий разработчика Роли и права Запросы СКД Платформа 1С v8.3 Управляемые формы Запросы Система компоновки данных Конфигурации 1cv8 Платные (руб)

Набор инструментов программиста и специалиста 1С для всех конфигураций на управляемых формах. В состав входят инструменты: Консоль запросов, Консоль СКД, Консоль кода, Редактор объекта, Анализ прав доступа, Метаданные, Поиск ссылок, Сравнение объектов, Все функции, Подписки на события и др. Редактор запросов и кода с раскраской и контекстной подсказкой. Доработанный конструктор запросов тонкого клиента. Продукт хорошо оптимизирован и обладает самым широким функционалом среди всех инструментов, представленных на рынке.

13000 10400 руб.

02.09.2020    122174    670    389    

714

SALE! 25%

Infostart PrintWizard

Пакетная печать Печатные формы Инструментарий разработчика Платформа 1С v8.3 Запросы 1С:Зарплата и кадры бюджетного учреждения 1С:Конвертация данных 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 Платные (руб)

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

18000 15300 руб.

06.10.2023    7295    21    6    

39

SALE! 20%

Infostart УДиФ: Управление данными и формами

Инструменты администратора БД Инструментарий разработчика Роли и права Платформа 1С v8.3 Конфигурации 1cv8 Россия Платные (руб)

Расширение позволяет без изменения кода конфигурации выполнять проверки при вводе данных, скрывать от пользователя недоступные ему данные, выполнять код в обработчиках. Не изменяет данные конфигурации, легко устанавливается практически на любую конфигурацию на управляемых формах.

10000 8000 руб.

10.11.2023    3542    11    1    

34

SALE! 30%

PowerTools

Инструментарий разработчика Инструменты администратора БД Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Россия Платные (руб)

Универсальный инструмент программиста для администрирования конфигураций. Сборник наиболее часто используемых обработок под единым интерфейсом.

3600 2520 руб.

14.01.2013    177757    1073    0    

849

Многопоточность. Универсальный «Менеджер потоков» 2.1

Инструментарий разработчика Платформа 1С v8.3 Конфигурации 1cv8 Россия Платные (руб)

Восстановление партий или взаиморасчетов, расчет зарплаты, пакетное формирование документов или отчетов - теперь все это стало доступнее. * Есть желание повысить скорость работы медленных алгоритмов! Но... * Нет времени думать о реализации многопоточности? * о запуске и остановке потоков? * о поддержании потоков в рабочем состоянии? * о передаче данных в потоки и как получить ответ из потока? * об организации последовательности? Тогда ЭТО - то что надо!!!

5000 руб.

07.02.2018    99347    239    97    

296

[ЕХТ] Фреймворк для Расширений 1С

Инструментарий разработчика Платформа 1С v8.3 Управляемые формы Платные (руб)

"Фреймворк для Расширений 1С" это универсальное и многофункциональное решение, упрощающее разработку и поддержку создаваемых Расширений. Поставляется в виде комплекта из нескольких Расширений с открытым исходным кодом. Работает в любых Конфигурациях в режиме Управляемого приложения с режимом совместимости 8.3.12 и выше без необходимости внесения изменений в Конфигурацию.

3000 руб.

27.08.2019    18116    6    8    

39

1С HTML Шаблоны / HTML Templates

Инструментарий разработчика Платформа 1С v8.3 Конфигурации 1cv8 Платные (руб)

Быстрая и удобная обработка для работы с шаблонами HTML. Позволяет легко и быстро формировать код HTML.

2040 руб.

27.12.2017    28110    3    10    

15

Выполнение произвольного кода или запроса с параметрами через Web-сервис (замена COM-подключений)

Инструментарий разработчика Обмен между базами 1C Платформа 1С v8.3 Платные (руб)

В процессе работы в 1С часто возникает потребность получить данные из другой базы.  Обычно это делается через COM-соединение, и время выполнения запроса при этом оставляет желать лучшего. В данной публикации представлено универсальное решение, позволяющее практически моментально выполнить произвольный код или запрос с параметрами в другой информационной базе через Web-сервис.

2400 руб.

24.09.2019    23604    15    15    

32
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. artbear 1448 22.07.19 15:45 Сейчас в теме
(0) Хорошая статья, живые примеры!

Спасибо!
2. artbear 1448 22.07.19 15:45 Сейчас в теме
мелкая опечатка бросилась в глаза

>путь до файла с тетсовой настройки
3. artbear 1448 22.07.19 15:58 Сейчас в теме
(0) В примере теста Тест_ЧтениеИнформациисСервера_НесколькоНастроек() не видно, что проверяемые данные (Спр.Конфигурации) предварительно очищены. Без этой очистки боевой код может переиспользовать существующие элементы :(

Для примера это неважно, а вот в разработке важно.
4. Сурикат 393 22.07.19 18:44 Сейчас в теме
(3) Спасибо, за замечание =)

В других случаях можно делать параметризуемые шаблоны и формировать наименование случайным образом во избежании проблем с совпадением данных =)
5. ImHunter 312 23.07.19 10:00 Сейчас в теме
Не видел, чтобы кто-то упоминал про расширения, создаваемые в помощь тестированию.
А ведь это круто - расшаривать приватные методы в специальном расширении и писать авто-тесты для того, что скрыто за кадром.
artbear; Сурикат; +2 Ответить
6. Сурикат 393 23.07.19 11:14 Сейчас в теме
(5)
Очень здоровский комментарий! Спасибо!

Еще ведь можно заменять вызов каких-то процедур, например обращение к файловой системе или выполнение сложного запроса с помощью расширения
8. artbear 1448 23.07.19 11:51 Сейчас в теме
(6)Да, расширения и для мокирования вполне удобно использовать, давно об этом думаю.
7. artbear 1448 23.07.19 11:50 Сейчас в теме
(5) Писать тесты для приватных методов - это зло.

если вдруг появилась такая потребность, подумайте, возможно, АПИ системы немного неверно :) и стоит его доработать.

Но идея с расширениями, конечно, полезная и уже есть примеры реализаций.
9. ImHunter 312 23.07.19 11:58 Сейчас в теме
(7) Да ладно - зло:))

Как протестировать работу какого-то достаточно сложного метода? Правильно! Написать интеграционный тест!
Но блин, в 50% случаев, нужно потратить на это кучу времени. А если приватные составляющие не протестированы - можно ведь и вообще надолго залипнуть.

В общем-то, я тоже сначала размышлял - заниматься ли таким хаком. Практика показала, что так спокойнее процесс проходит.
12. artbear 1448 23.07.19 12:16 Сейчас в теме
(9) А может быть, не делать сложные методы ? :)

а создавать несколько публичных интерфейсов/классов/модулей/обработок и тестировать их по отдельности.

как раз и получится и чистый ТДД по отдельным модулям/классам.
13. ImHunter 312 23.07.19 12:28 Сейчас в теме
(12) Не всегда ведь нужно публиковать составляющие какого-то метода. Ибо нефиг.
А так, пользуясь хаком, "приколачиваю" внутреннее поведение к заданным паттернам. Если кто-то что-то переделает - будет детальная картина, где сломались механизмы.
10. ImHunter 312 23.07.19 12:02 Сейчас в теме
И еще трюк:) Иногда пишу самотестируемые внешки.

Т.е., это целевая функциональная внешка. В ней еще дописан интерфейс для xUnit/ADD.
11. artbear 1448 23.07.19 12:12 Сейчас в теме
(10) я с этого начинал много лет назад. По ТДД создавал тесты и код в одной обработке.

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

так легче и разрабатывать, и сопровождать.

приходится придумывать и реализовывать более точное АПИ.
14. for_sale 971 28.07.19 16:14 Сейчас в теме
Очень хорошая статья, большое спасибо!
Вопрос - можно ли где-то со всем этим функционалом ознакомиться более детально?
Ведь для данных примеров просто взяты некоторые функции, но их там, по идее, в разы больше. Где-то (кроме сурскода) можно почитать описание возможностей? Плагины, инициализация и т.п.
15. Сурикат 393 28.07.19 21:22 Сейчас в теме
(14)

https://github.com/silverbulleters/add/tree/master/doc/xdd - для части плагинов есть описание. Для части только читать исходники =(

Также можно поизучать тесты на модули - https://github.com/silverbulleters/add/tree/master/tests/xunit/Plugins. Тесты даже лучше, чем документация =)
for_sale; +1 Ответить
16. for_sale 971 29.07.19 16:20 Сейчас в теме
(15)
Спасибо за ссылки! По поводу документации - давно присматриваюсь и к АДД, и к ВА, первое время просто не мог поверить, что такие титанические труды не имеют никакой официальной документации!
17. artbear 1448 29.07.19 18:14 Сейчас в теме
(16) Документация есть, но, конечно, ее очень не хватает.
Кодить мы все любим, а с документацией не дружим.
18. artbear 1448 29.07.19 18:16 Сейчас в теме
По Vanessa-ADD есть уже немало статей.
И здесь на Инфостарте есть цикл статей,
и в документации на гитхабе Vanessa-ADD https://github.com/silverbulleters/add/blob/master/doc/README.mdе сть первые же ссылки - "почитать статьи, посмотреть видео"
Оставьте свое сообщение