Тестування роботи мобільного додатку в офлайн-режимі

TRUETECH займається розробкою, підтримкою та обслуговуванням мобільних додатків iOS, Android, PWA. Маємо великий досвід та експертизу для публікації мобільних додатків до популярних маркетів Google Play, App Store, Amazon, AppGallery та інші.

Розробка та підтримка будь-яких видів мобільних додатків:

Інформаційні та розважальні мобільні програми
Новинки, ігри, довідники, онлайн-каталоги, погодні, фітнес та здоров'я, туристичні, освітні, соціальні мережі та месенджери, квіз, блоги та подкасти, форуми, агрегатори
Мобільні програми електронної комерції
Інтернет-магазини, B2B-додатки, маркетплейси, онлайн-обмінники, кешбек-сервіси, біржі, дропшиппінг-платформи, програми лояльності, доставка їжі та товарів, платіжні системи
Мобільні програми для управління бізнес-процесами
CRM-системи, ERP-системи, управління проектами, інструменти для команди продажів, облік фінансів, управління виробництвом, логістика та доставка, управління персоналом, системи моніторингу даних
Мобільні програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, платформи надання електронних послуг, платформи кешбеку, відеохостинги, тематичні портали, платформи онлайн-бронювання та запису, платформи онлайн-торгівлі

Це лише деякі з типів мобільних додатків, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 1735 послуг
Тестування роботи мобільного додатку в офлайн-режимі
Середній
~2-3 дні
Часті запитання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_mobile-applications_feedme_467_0.webp
    Розробка мобільного додатка для компанії FEEDME
    792
  • image_mobile-applications_xoomer_471_0.webp
    Розробка мобільного додатку для компанії XOOMER
    671
  • image_mobile-applications_rhl_428_0.webp
    Розробка мобільного додатку для компанії RHL
    1097
  • image_mobile-applications_zippy_411_0.webp
    Розробка мобільного додатку для компанії ZIPPY
    969
  • image_mobile-applications_affhome_429_0.webp
    Розробка мобільного додатку для компанії Affhome
    914
  • image_mobile-applications_flavors_409_0.webp
    Розробка мобільного додатку для компанії FLAVORS
    495

Тестування роботи мобільного додатку у офлайн-режимі

Офлайн-режим — одна з тих функцій, яку заявляють у вимогах та тестують поверхово. «Без інтернету не працює» — та окей. Але для додатків, якими користуються у метро, у поїздках, у зонах слабого покриття, це критично. Гірше «не працює» — працює неправильно: показує застарілі дані без мітки часу, втрачає введені дані, мовчки ошибається.

Що перевіряємо

Три основні сценарії:

Запуск без мережі. Що видит користувач, відкриваючи додаток без інтернету? Правильно: останні кешовані дані з міткою часу («оновлено 2 години тому»). Неправильно: білий екран або повідомлення «немає з'єднання» без жодного контенту.

Втрата з'єднання під час використання. Користувач переглядав ленту, з'єднання зникло. Уже завантажений контент повинен залишатися доступним. Незавершені дії — збережені як чорновики або поставлені у чергу.

Відновлення з'єднання. Дані синхронізуються, чергу відкладених дій виконується, конфлікти розв'язуються. Користувач видит актуальні дані без ручного оновлення.

Локальне кешування: що та як

На iOS — NSURLCache для HTTP-ответов (якщо сервер повертає правильні Cache-Control заголовки), Core Data або Realm для структурованих даних, UserDefaults для невеликих налаштувань. Для медіа — FileManager з власним каталогом кешу.

Core Data з NSPersistentCloudKitContainer дає синхронізацію через CloudKit «з коробки», але конфлікти розв'язує примітивно — last-write-wins. Для складної логіки конфліктів реалізуємо кастомний merge policy.

На Android — Room для структурованих даних, DataStore для налаштувань, Cache-Control через OkHttp для HTTP-кешу:

val cacheSize = 10 * 1024 * 1024L // 10 MB
val cache = Cache(context.cacheDir, cacheSize)

val okHttpClient = OkHttpClient.Builder()
  .cache(cache)
  .addNetworkInterceptor { chain ->
    val response = chain.proceed(chain.request())
    response.newBuilder()
      .header("Cache-Control", "public, max-age=300") // 5 хвилин
      .build()
  }
  .addInterceptor { chain ->
    val request = if (isNetworkAvailable()) {
      chain.request()
    } else {
      chain.request().newBuilder()
        .header("Cache-Control", "public, only-if-cached, max-stale=${60 * 60 * 24}") // 24 години з кешу
        .build()
    }
    chain.proceed(request)
  }
  .build()

only-if-cached + max-stale — читаємо з кешу, навіть якщо дані застарілі, поки офлайн.

Чергу відкладених дій

Дії користувача у офлайні повинні виконатися при відновленні мережі. Не «втеруть з помилкою», а збережуться та виконаються.

Android — WorkManager з setRequiredNetworkType(NetworkType.CONNECTED):

fun scheduleOfflineAction(action: UserAction) {
  val data = workDataOf("action_json" to action.toJson())
  val request = OneTimeWorkRequestBuilder<SyncWorker>()
    .setConstraints(Constraints.Builder()
      .setRequiredNetworkType(NetworkType.CONNECTED)
      .build())
    .setInputData(data)
    .build()
  WorkManager.getInstance(context).enqueue(request)
}

Дія зберігається у базу WorkManager, виконується як тільки появиться мережа, переживе перезавантаження пристрою.

iOS — BackgroundTasks framework (BGProcessingTask) або простіший варіант: локальна черга у Core Data, спроба виконання при applicationDidBecomeActive та при зміні мережі через NWPathMonitor.

Тестові сценарії та інструменти

Відключення мережі у тесті:

iOS симулятор: Hardware → Network Link Conditioner → 100% Loss або xcrun simctl status_bar + емуляція через Network Link Conditioner profile.

Android емулятор: adb shell svc wifi disable && adb shell svc data disable. Відновлення: enable.

У автотестах (Detox):

it('shows cached data when offline', async () => {
  // Завантажуємо дані при наявності мережі
  await element(by.id('feed_list')).waitForVisible();

  // Відключаємо мережу (тільки на Android через adb)
  await device.setNetworkConditions({ offline: true });

  // Перезапускаємо та перевіряємо кеш
  await device.reloadReactNative();
  await expect(element(by.id('cached_banner'))).toBeVisible();
  await expect(element(by.id('feed_list'))).toBeVisible(); // кеш працює
});

Конфлікти при синхронізації

Користувач відредагував запис офлайн. Інший користувач змінив цю саму запис онлайн. При відновленні з'єднання — конфлікт.

Стратегії: last-write-wins (простіше, але втрачає дані), server-wins (передбачуваного, але ігнорує офлайн-правки), merge (правильно, але складно). Для більшості додатків достатньо показати користувачу діалог вибору версії.

Строки

2–3 дні — тестування по чеклисту офлайн-сценаріїв, оцінка корректності кешування та черги дій, звіт. Вартість розраховується індивідуально.