Ни разу не постил на Хабр, а тут такой интересный повод нарисовался!
Вопросы, обсуждаемые в статье:
- Выбрать публичность или приватность — вот в чем вопрос!
- Кто главнее — клиент или сервер?
- Прочтите статью и вы увидите, как на эти вопрос отвечает 1С в своей платформе 🙂
- И еще неожиданный интересный факт о Google узнают те, кто дочитает до конца!
- Я кратко расскажу, как я нашел точного виновника бага.
Сразу скажу, что я любитель находить баги, а баги любят находить меня!
И 13 число в моей жизни играет не последнюю роль.
История
Итак, сижу я вечером (на дворе как раз 13 декабря), тружусь над одним из своих любимых продуктов xUnitFor1C над значимым релизом 4.0
Тестирую работу тестов в режиме управляемого приложения при переходе с клиента на сервер и обратно.
Есть у нас один интересный и непростой сценарий поведения при использовании серверных тестов в режиме управляемого приложения на тонком клиенте.
В модуле контекста ядра тестирования (Упр.форма) созданы 2 похожих метода ВыполнитьТестовыйМетодНаКлиенте (признак &НаКлиенте) и ВыполнитьТестовыйМетодНаСервере (признак &НаСервере).
Назначение их понятно из названия.
Обычно в тесте я использовал метод УпрФорма.ВыполнитьТестовыйМетодНаКлиенте для проверки тестов УФ, т.е. через контекст управляемой формы.
Все штатно, проблем нет.
Но теперь мне понадобилось проверить переход с клиента на сервер.
Я решил, что хватит использовать ВыполнитьТестовыйМетодНаКлиенте, пора заняться более глубоким хакингом и вызвал метод ВыполнитьТестовыйМетодНаСервере.
Написал специальный тест, описал поведение согласно сценария и внутри теста вызываю ЭтаФорма.ВыполнитьТестовыйМетодНаСервере
Тест предсказуемо падает, ведь я работаю по методике TDD.
Начинаю разбираться, что нужно поправить в коде, чтобы тест заработал (ТДД работает именно так).
Проходит несколько минут, и я с огромным изумлением вижу, что вызываемой мной метод ВыполнитьТестовыйМетодНаСервере является приватным, т.е. у него нет признака Экспорт !!
При этом я его успешно вызываю, и он прекрасно отрабатывает.
Поиск и подтверждение бага в платформе 1С
Не верю своим глазам, ведь я много умных книжек читал, знаю много языков программирования, и понимаю, что приватный метод просто так вызвать нельзя.
Сначала я проверил, вызываю я правильный код из правильного места и т.д.
Еще через пару минут я убедился, что ошибки нет, действительно, я вызываю приватный метод и он успешно отрабатывает!
Также я проверил, что метод ВыполнитьТестовыйМетодНаКлиенте является публичным/экспортным методом.
Согласно методикам поиска багов я максимально упростил ситуацию и исключил сторонние факторы:
создал отдельную внешнюю обработку. Добавил к ней простую управляемую форму.
Добавил 2 команды ВызовПриватногоКлиентскогоМетода и ВызовПриватногоСерверногоМетода
Для этой формы добавил следующий код:
&НаСервере Процедура ПриватнаяНаСервере() Сообщить("ПриватнаяНаСервере"); Сообщить("После вызова ПриватнаяНаСервере"); КонецПроцедуры &НаКлиенте Процедура ВызовПриватногоСерверногоМетода(Команда) ЭтаФорма.ПриватнаяНаСервере(); // не выдает ошибку !! КонецПроцедуры &НаКлиенте Процедура ПриватнаяНаКлиенте() Сообщить("ПриватнаяНаКлиенте"); КонецПроцедуры &НаКлиенте Процедура ВызовПриватногоКлиентскогоМетода(Команда) ЭтаФорма.ПриватнаяНаКлиенте(); // как и положено, выдает исключение Сообщить("После вызова ПриватнаяНаКлиенте"); КонецПроцедуры
Первоначально я запускал подобный ручной тест на свежайшей версии 8.3.7.1805 (выпущена 10.12.2015, если я не ошибаюсь)
Получаю поведение:
- приватный серверный метод успешно вызывается, сообщения отрабатывают. Это ошибка.
- с приватным клиентским методом проще. Выдается правильное исключение, что метод не обнаружен.
{Форма.Форма.Форма(15)}: Метод объекта не обнаружен (ПриватнаяНаКлиенте)
ЭтаФорма.ПриватнаяНаКлиенте();
В итоге получаем явный баг в 8.3.7
Далее я согласно тем же методикам поиска багов проверяю поведение на другой платформе 1С 8.2.19
Поведение абсолютно такое же.
Проверил поведение на встроенной обработке, те же проблемы!
Собственно, формулировка бага — сторонний код может вызвать приватный серверный метод управляемой формы через контекст управляемой формы, а приватный клиентский код таким образом вызвать нельзя.
Риторические вопросы
- Получается, это не баг, это фича, потому что подобное «странное» поведение наблюдается очень давно, уже несколько лет?
- А как же приватность/публичность? это же базовые принципы!
- А как же инкапсуляция? получается, что кто угодно может вызвать скрытые серверные методы и нарушить поведение.
- А как же равноправие? почему клиент настолько ущемлен по сравнению с сервером 🙂 ?
В итоге этот баг сделал мой вечер!
Надеюсь, и вам понравилась указанная багофича.
Ух, как теперь можно развернуться кодерам на языке 1С, теперь можно экспорт не писать, все и без него работает.
Это же сколько кода можно наваять, если не тратить время на написание Экспорт! А в масштабах страны какая экономия времени?
А если более серьезно, то хочется обратиться к 1С для исправления данной ошибки.
Евангелист 1С PeterG, что скажешь? 🙂
Также предлагаю встроить в продукт АПК (Автоматизированная проверка конфигурации) проверку на подобный баг.
PS Если кому-то нужно, могу дать обработку для ручного тестирования.
PPS А если кому интересно, что же нового будет в версии 4.0 xUnitFor1C, ждите следующей статьи и новогоднего подарка!
ссылка на оригинал статьи http://habrahabr.ru/post/273155/
Добавить комментарий