IT-инфраструктура для бизнеса и творчества

Как мы поменяли этап тестирования в разработке приложений

Денис Гордиенко, руководитель Bright Mobile, о том, какие изменения внесли в тестирование мобильных приложений.

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

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

Чем больше итераций в формате «нашли ошибки — исправили — отправили снова проверять», тем больше накаляются эмоции. Со стороны заказчика это выглядит так: криворукие программисты не могут исправить свои же косяки, а со стороны программиста: заказчик не может сесть и сразу всё проверить, прислав единый баг-лист по проекту.

Можно зайти на Fl.ru и увидеть, как много объявлений в формате «проект сделан на 90%, надо допилить». Эти объявления — следствие того, что в какой-то момент разработчик и заказчик не смогли договорится и расстались с неприятным осадком.

По подписке не договорились

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

Как проходит тестирование в большинстве команд

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

Обычно разработка приложения выглядит так:

  1. Выполнение — непосредственно создание приложения.
  2. Самопроверка — программист проверяет за собой и исправляет баги, которые увидел, в студиях ему помогает менеджер проекта.
  3. Проверка клиентом — клиент при приёмке сам проверяет приложение и, если нашёл пропущенные баги или отклонения, сообщает об этом.

Клиент ставит себе приложение, находит еще ошибки, программист исправляет, и так в несколько итераций приложение доводится до итогового варианта. Задача менеджера проекта — максимально сократить количество этих итераций, в идеале сведя к приёмке без багов.

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

Но чем больше проект, чем он дороже, тем больше предъявляется требований к качеству проекта. Появляются ошибки, которые визуально не очевидны. Они влияют на качество работы или проявят себя позднее. Чуть ниже будет пример отчёта о проверке с описанием таких неочевидных ошибок. Пока давайте примем наличие таких багов, как убеждение:

ДМБ

Как решают проблему крупные проекты

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

Большие проекты вроде Авито, YouDo используют автотесты и внедряют стандарты качества.

Автотесты — это штука хорошая и правильная. Если дилетантски объяснять — создаётся подпрограмма, которая проверяет типичные и нетипичные варианты использования основного приложения.

Применима, когда один проект разрабатывается годами в agile-формате, то есть идёт постоянный поток задач и релизы выпускаются по календарному плану.

Однако большинство заказчиков видят работу над своим приложением проектно, то есть «начали, сделали, сдали, а нужно будет что-то дорабатывать или нет, это ещё вопрос». Позиция спорная, но аргументы в её защиту есть, поэтому принимать нужно как данность.

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

Второй вариант — переложить на тестировщиков. То есть вместо робота будет сидеть и проверять живой человек. Отчасти это похоже на проверку менеджером проекта, но тестировщик может сам поправить незначительные баги и отдать программисту только уж совсем сложные проблемы.

Соответственно, для тестировщиков пишутся регламенты — что проверять, как и что делать в той или иной ситуации.

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

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

С регламентами всё понятнее: так делай, так не делай. Но разработка имеет свою специфику. Можно написать код в формальном соответствии регламентам, но он будет ужасен и повлечёт много проблем в дальнейшем.

К чему пришли мы

Мы нашли интересное решение довольно случайно. Как всегда, оно пришло из суровой практики, а не из теории ведения проектов. Наш ведущий разработчик наткнулся на задние на Fl.ru, где нужно было сделать ревью приложения на Ionic.

Он посмотрел приложение, написал список багов (тот самый список, который я обещал в начале статьи):

  1. Необходимо исключить папку plugins из репозитория

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

  3. Скрипты в корне приложения подключены синхронно, это влияет на скорость загрузки приложения. Причём некоторые скрипты на первом экране не используются.

  4. Проект невозможно поднять из исходников: не хватает части библиотек
  5. Вынести обработку данных в компонентах или страницах в сервисы и провайдеры, чтобы при изменениях код корректировался в одном месте, а не в разных частях приложения.

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

Выделять в студии ведущего программиста на то, чтобы он проверял правильность кода, дорого. Мы нашли альтернативное решение.

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

Получается, что это как бы такой автотест, но без привязки к конкретному проекту. То есть некая постоянно пополняемая база «как делать нельзя», не увеличивающая стоимость приложения, но серьёзно помогающая снизить количество багов.

(function () { let cdnUrl = `https://specialsf378ef5-a.akamaihd.net/SelectelBranding/images/` let previousArticleNumber = null let currentArticleNumber = 0 let platform = 'Desktop' let articles = [ { name: 'camera', url: `${cdnUrl}CameraCat`, text: 'умную камеру для\u00A0наблюдения за\u00A0котиками', link: 'https://vc.ru/selectel/306690', num: 3 }, { name: 'chill', url: `${cdnUrl}ChillCat`, text: 'трекер, который подскажет, когда пора отдохнуть', link: 'https://vc.ru/promo/288561-eye-tracker', num: 1 }, { name: 'cloud', url: `${cdnUrl}CloudCat`, text: 'котика: даёшь ему «пять», а\u00A0он делает бэкап в облако', link: 'https://vc.ru/dev/294799-maneki-neko', num: 2 } ] let buttonCycle = document.querySelector('.button--cycle') let buttonChoose = document.querySelector('.button--choose') let buttonMobile = document.querySelector('.button--mobile') let textField = document.querySelector('.selectel-footer-subtitle') let imageAgent = document.querySelector('.image--agent') let banner = document.querySelector('.selectel-footer') buttonCycle.addEventListener('click', cycleClick) buttonChoose.addEventListener('click', () => sendEvent(`Promo ${articles[currentArticleNumber].num} Left`, 'Click')) buttonMobile.addEventListener('click', () => sendEvent(`Promo ${articles[currentArticleNumber].num} Left`, 'Click')) let media = window.matchMedia("(max-width: 570px)") media.addEventListener('change', matchMedia) function matchMedia() { if (media.matches) { platform = 'Mobile' } else { platform = 'Desktop' } update() } matchMedia() function cycleClick(event) { sendEvent(`Promo ${articles[currentArticleNumber].num} Right`, 'Click') if (event) { event.preventDefault() event.stopPropagation() } window.open('https://vc.ru/tag/selectelDIY', '_blank') //cycle(event) } function cycle(event) { // incrementArticleNumber() textField.innerHTML = generatedText() imageAgent.src = articles[currentArticleNumber].url + platform + '.svg?3' imageAgent.setAttribute("class", "") imageAgent.classList.add('image--agent', articles[currentArticleNumber].name) banner.href = articles[currentArticleNumber].link } function update() { banner.href = articles[currentArticleNumber].link imageAgent.src = articles[currentArticleNumber].url + platform + '.svg' textField.innerHTML = generatedText() } function incrementArticleNumber() { previousArticleNumber = currentArticleNumber if (currentArticleNumber >= articles.length - 1) { currentArticleNumber = 0 } else { currentArticleNumber++ } } const sendEvent = (label, action = 'Click') => { const value = `SelectelDIY — loc: Footer — ${label} — ${action}`; if (window.dataLayer !== undefined) { window.dataLayer.push({ event: 'data_event', data_description: value, }); } }; function generatedText() { let defaultText if (platform === 'Desktop') { defaultText = `Мы тут собрали %text%. Хотите научим?` } else { defaultText = `Мы тут собрали %text%.` } return defaultText.replace('%text%', articles[currentArticleNumber].text) } function getRandom(min, max) { min = Math.ceil(min) max = Math.floor(max) return Math.floor(Math.random() * (max - min + 1)) + min } (function create() { currentArticleNumber = getRandom(0, articles.length - 1) cycle() let page = document.querySelector('.page--entry') if (page) { function insertAfter() { let parents = page.querySelectorAll('[data-id="7"]') let referenceNode = parents[0] referenceNode.parentNode.insertBefore(banner, referenceNode.nextSibling); loaded() } setTimeout(() => insertAfter(), 0) } }()) function loaded() { banner.classList.add('loaded') } loadImages([ `${cdnUrl}CameraCatDesktop.svg`, `${cdnUrl}ChillCatDesktop.svg`, `${cdnUrl}CloudCatDesktop.svg`, `${cdnUrl}CameraCatMobile.svg`, `${cdnUrl}ChillCatMobile.svg`, `${cdnUrl}CloudCatMobile.svg?3`, ]) function loadImages(urls) { return Promise.all(urls.map(function (url) { return new Promise(function (resolve) { var img = document.createElement('img'); img.onload = resolve; img.onerror = resolve; img.src = url; }); })); } }())
0
4 комментария
Популярные
По порядку
Андрей Браиловский

Автотесты увеличивают стоимость проекта на 30% - серьезно?
Мне просто интересно, как вы это посчитали.

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

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

Ответить
3
Развернуть ветку
Денис Гордиенко

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

И какой видите объективный подход к тестированию приложения с бюджетом до 500 т.р.?

Ответить
1
Развернуть ветку
Андрей Браиловский

С бюджетом в 500 тысяч рублей за все приложение - тестить самому или нанять асессора на удаленку/фриланс, написав ему чек-лист. Автотесты это все же энтерпрайзное решение для больших проектов, в такой бюджет никак не вписать. Не думаю что они в таком случае экономически оправданы

Если брать классический случай, когда автотестами занимается 1-2 QA в команде из нескольких десятков человек + время от времени 1 девопс, выходит довольно небольшая сумма

Ответить
1
Развернуть ветку
Денис Гордиенко

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

Ответить
1
Развернуть ветку
Читать все 4 комментария
Сооснователь Endel Владислав Пинский запустил в Германии сервис распознавания документов ABC Doc и привлёк €500 тысяч Статьи редакции

Сервис помогает понять смысл документов и решить, что с ними нужно делать.

Пример работы ABC Doc
Эвакуатор для своих: бармен из Санкт-Петербурга придумал как заработать, когда закрыли общепит Статьи редакции

Он сам переоборудовал грузовик Toyota Dyna и принимает заказы от владельцев автосервисов и знакомых автомобилистов.

Платформу для эвакуатора варили из металла вручную
Почему начинающим предпринимателям стоит выходить на маркетплейсы

Торговые онлайн-площадки готовы сотрудничать с бизнесом любого размера.

Дольше всех на рынке: почему компаниям с большим опытом сложнее работать с клиентами?
В OTUS стартует первый онлайн-буткемп «Java developer»
Пользователи Авито спасли от вырубки леса равные по площади территории Карелии и сэкономили электроэнергию близкую годов

Как деятельность Авито влияет на сокращение загрязнения окружающей среды? Перепродажа наиболее вредных с точки зрения производства товаров помогла пользователям Авито за 2020 год совместно сэкономить более 1,3 миллиарда кг различных материалов, 267 млн ГДж энергии и 123 млн м3 воды.

OZON заблокировал аккаунт и отказывается объяснять причину

Ничего не предвещало беды. Как это обычно и бывает, я пришел в ПВЗ, чтобы забрать свой заказ, достал телефон, чтобы назвать сотруднику номер заказа, и столкнулся с проблемой: меня выкинуло из аккаунта. При попытке авторизоваться по номеру телефона или по почте я получил ошибку:

Благодарность команде vc.ru

Эти ребята делают наш мир лучше.

Как поднять продажи фармы в диджитале? Рассказываем про стратегию продвижения бренда «Ультра-Д» и показываем результаты

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

Голова не варит: 10+ советов, как предотвратить умственное переутомление

Наш мозг потребляет уйму энергии, но мы почему-то часто игнорируем, продолжая нагружать его новыми задачами. Как следствие — возникает умственное переутомление, и мы печально и бессильно глядим в пустоту в конце дня. Разбираемся, почему такое состояние возникает и как с ним бороться.

null