Pull to refresh

Comments 23

Определение товара по фото на ML построенно?
Да, основано на ML, определение работает на бэкенде. Модель постоянно совершенствуется, обучаясь на всех объявлениях, размещаемых на нашей платформе.
Не у всех есть регистрация на Хабре, но вопросы приходят и в наши соцсети/из чатиков. Буду их сюда копировать.

>Слышал, что вы разрабатываете свой фреймворк для UI тестов. Можете рассказать подробнее, да и вообще раскрыть тему, почему это лучше юнит-тестов?
В конце прошлого года начали заниматься End-to-end UI тестами. В ближайшее время выложим в Open Source.

Что же лучше, юнит тесты и UI тесты? Одно не лучше другого. Они дополняют друг друга.

Мы исповедуем прагматичный подход, мы занимаемся UI тестами, потому что они нам помогают минимизировать ручное тестирование. Фактически сейчас мы релизимся чаще раза в 2 недели, релизим две платформы, релизим приложение с огромным количеством сценариев использования. Перед релизом мы проводим регрессионное тестирование. У нас много сценариев в регрессионном тестировании, мы планируем закрыть их на 100%. То есть основная задача наших E2E тестов — минимизировать ручное тестирование. В основном UI тесты пишут тестировщики. Юнит тесты же пишут только разработчики для проверки своего кода.

По фреймворку. Мы написали фреймворк, удобный для написания тестов, мы используем XCUI, но абстрагировались от него, да и вообще от многого. Например, одни и те же тесты можно запускать с EarlGrey и c XCUI. Если чего-то в XCUI не хватает, мы свободны тестировать в обход XCUI. Чуть подробнее рассказывал на Cocoaheads: youtu.be/036qVHFtNxc
На Авито iOS был доклад про сбор метрик в мобильном приложении, какие технические или продуктовые решения получилось с помощью них сделать, принесли они какой-то профит?
Профит есть, и он состоит в поддержании качества приложения.

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

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

А можно подробнее про скорости компиляции. Как было, как стало? На каких машинах разработка ведется?
Все замеры проводятся на mac mini (2 физических + 2 логических ядра), а разработка ведется на MacBook Pro (4 логических + 4 логических), так что у разработчиков все собирается быстрее.

Время чистой сборки на mac mini сократилось с 600 секунд до 390. А вот инкрементальная сборка с изменением самого тяжелого модуля сократилось с 200 секунд до 25.

С недавнего времени стали собирать статистику по утилизации CPU — какой процент времени xcode собирает фреймворки параллельно на всех ядрах. Это позволяет понять, какие части приложения мешают компилироваться других частям.
Вопрос из чатика.
>Какая архитектура используется на презентейшн слое?
Мы используем VIPER. Presenter отвечает за связь модели (Interactor — фасад для модели) и отображения (View — фасад для UI). Стараемся делать стейтлесс. Обычно все события идут в одностороннем потоке. Например, View -> Presenter -> Interactor -> Presenter -> View.

View не знает про модели из Interactor, Interactor также изолирован от источника данных. Intractor — это фасад, он использует лишь абстракции.

Также Presenter умеет работать с Router — абстракцией над навигацией в приложении. Presenter изолирован от UIKit, нам в этом очень сильно помогает библиотека Marshroute (https://github.com/avito-tech/Marshroute). Видео по теме: выступление Тимура Юсипова, автора Marshroute, на РИТ++ по навигации в iOS: youtu.be/h6c4IkZxFZY
Касательно монорепо.
1) У вас один проект — Авито? Или есть другие приложения, лежащие в этом репо?
2) Если проектов несколько, какая у вас структура? Заведены ли воркспейсы для каждого из приложений, или в одном воркспейсе несколько таргетов для каждого приложения?
3) Вы же используете cocoapods development pods для внутренних модулей (фичи, кор слой)?
Как происходит процесс изменения чего-либо в кор слое? Или изменения медиатора? От них же зависит не только сам проект, но и почти все эти компоненты. А dependency в podspec можно выставлять только через версию, то есть path-ом не получится воспользоваться.
1.) В монорепозитории один продукт — Авито. Так же в нем есть другие приложения, которые используются в качестве демок для более быстрой работы над проектом, так как демки содержат меньше кода и собираются быстрее.

2.) Для демок заведены отдельные таргеты в том же воркспейсе, что дает быстрый доступ ко всем демкам.

3.) Так как все наши зависимости живут в монорепозитории, то они объявлены как “development pod” и прописаны в “podfile” статическими путями. Они не версионируются, опять же потому, что все живет в одном репозитории и вся кодовая база проекта синхронизирована сама по себе. Изменения core-слоя происходят достаточно редко и они минимальны, так как мы стараемся делать простые интерфейсы, а на случай больших изменений у нас всегда есть фича тоглы)

Почему мы используем такую схему работы с проектом? Около года назад у нас были репозитории для каждого отдельного модуля/слоя, но это замедляло разработку, так как при изменении зависимости тебе нужно было сделать минимум 2 пулл реквеста и, скорее всего, порешать конфликты. Было долго и мучительно. Так как проект у нас один и он не шарит код с другими аппами, то схема с монорепой убрала всю боль и не принесла новой. В общем, нам это хорошо зашло)
По какому принципу выделяли модули из монолита? Есть модули без презентейшен слоя?
Без презентационного слоя у нас только утилитки (Core слой), и так случилось, что все они были вынесены наружу из монолита задолго до того, как он начал требовать распила. Можно сказать, что когда такие утилитки появлялись (на замену легаси коду), они сразу оформлялись в виде отдельных модулей (а до перезда в монореп и в виде отдельных репозиториев)

В монолите же лежали только модули экранов, то есть модули с презентационным слоем (хотя модулями их было трудно назвать, монолит же =)).

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

Например, все экраны платных услуг выделили в отдельный cocoapod. За эти экраны ответственна определенная группа разработчиков

Другие примеры фич — главная страница + экраны поисковой выдачи, экраны выбора локации, экраны поисковых фильтров, экраны публичного профиля пользователя, экраны приватного профиля пользователя, экраны по работе с картой, экраны по работе с веб-контентом

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

  1. Какого порядка число таргетов? Демка — это тоже самое приложение с реализацией фичи/фикса или только сама фича?


  2. Как вы собираете, версионируете и распространяете (внутри команды) демки и фичи? Расскажите подробнее про используемые CI/CD.
Про CI/CD. Демки — это отдельные маленькие приложения, связанные, как правило, с фичами конкретного юнита и используются внутри юнита и поэтому их распространять на всех не нужно.
Что касается распространения приложения Авито внутри компании — мы используем Testflight (заливаем туда сборки с помощью fastlane), куда добавлены как internal users(тестировщики) так и external testers(все заинтересованные в компании). Также вместе с Авито у нас распространяется отдельное приложение с фича-таггламм, которое позволяет включать фичи в приложении Авито для различных конфигураций(напр: debug, adhoc, release).
Мы собираем сборки для тестирования каждые 2 часа из develop, также есть возможность у разработчика собрать сборку для тестирования на своей ветке.
Подробнее про флоу CI/CD у нас — youtu.be/r3rUedCbe7Q
Так же могу дополнить, что демок больше десятка. Демо — это приложение с подключенными к нему необходимыми модулями и необходимой для них частью core-слоя. Ничего лишнего, только нужный юниту функционал.
пулл реквесты, легаси, feature-toggle…
а сайт тяжелый — крутится много всего совершенно не нужного для пользователей
Добрый день, чем пользуетесь при кодогенерации?
Sourcery используем для генерации Swift кода на основе Swift кода.
github.com/krzysztofzablocki/Sourcery

У нас довольно много кода им генерируется, поэтому у нас есть обвязки, оптимизирующие это. Кодогенерация запускается в Pre-Action при билде, занимает на горячую порядка секунды. Очень мощный инструмент, довольно стабилен. Случаются казусы, но оно у нас работает почти без нареканий, это даже удивительно.

Кодогенерацией делаем конструкторы, функции сравнения, генерируем тесты на DI, генерируем различные списки, типа списка поддерживаемых методов API. Всего сейчас использется 26 Stencil шаблонов.

SwiftGen используем для генерации Swift кода на основе ассетов.
github.com/SwiftGen/SwiftGen

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

Jinja2. Есть код на Python3 для генерации скелета тестов UI тестов на основе описания тесткейсов ручного регресса. Также Jinja2 используется для генерации отчетов на CI.
А если не секрет, что используете для проверки уязвимости кода? Используете ли статические анализаторы?
Only those users with full accounts are able to leave comments. Log in, please.