Новое:Talanto осенью: поиск с цифрами, вакансия по шагам и каталог компаний

+1 973новые вакансии за сутки·85 834вакансии открыты сейчас·Новое:Talanto осенью: поиск с цифрами, вакансия по шагам и каталог компаний

Новые вакансии в TelegramРаботодателям
Talanto
Вакансии
Компании7 081
РезюмеAIПодготовкаСтатьи
BoostТарифыBoost
Войти

Не нашли подходящее?

Пусть нужная вакансия найдёт вас сама.

  1. Подборка в TelegramНовые вакансии по вашему фильтру — сразу в бота.Подключить
  2. Мэтчи по резюмеЗагрузите резюме — покажем, где вы подходите лучше всего.Загрузить
  3. Сохранить фильтрНастройте поиск один раз и возвращайтесь к новым вакансиям.Настроить
Что нового на TalantoTalanto осенью: поиск с цифрами, вакансия по шагам и каталог компаний

Для работодателей

Опубликуйте вакансию — отклики придут в ваш кабинет.

  1. Вакансиябесплатно
  2. Откликиконтакты бесплатно
  3. Наймэтапы и интервью

40 компаний публикуют вакансии напрямую · 4 400 кандидатов открыты к предложениям

Разместить вакансию

Популярные направления

Все подборки
  • Python15 655
  • Облачные технологии11 901
  • QA вакансии3 405
  • Backend вакансии1 917
  • Инженер данных1 435
  • Продакт-менеджер891

Разработка

  • Android1 772
  • iOS1 646
  • AI вакансии901
  • Fullstack вакансии801
  • Frontend вакансии678
  • Mobile вакансии33

По стеку

  • Go8 449
  • Java5 599
  • Node.js1 779
  • Kotlin1 475
  • Rust1 398
  • .NET1 370
  • PHP574
  • C#436
  • C++424

DevOps и инфраструктура

  • Kubernetes6 670
  • DevOps вакансии5 099
  • Linux-инфраструктура4 926
  • Terraform / IaC3 701
  • CI/CD1 889
  • Мониторинг и Observability1 699
  • SRE516
  • Кибербезопасность262

Аналитика и данные

  • Data Scientist797
  • Аналитик данных764
  • Бизнес-аналитик738
  • Системный аналитик96

Другие направления

  • Проджект-менеджер360
  • UI/UX дизайн110
  • Ручное тестирование14

По регионам

  • Вакансии в США41 869
  • Вакансии в Европе17 422
  • Вакансии в Канаде4 056
  • Работа в России3 874

По формату

  • Удалённые вакансии67 491
  • Релокация в США42 199
  • Гибридная работа9 848
  • Офисная работа6 812

По уровню

  • Senior вакансии38 497
  • Middle вакансии18 722
  • Junior вакансии6 245

Сейчас нанимают

Все компании
  • Wise193 вакансии
  • Rakuten189 вакансий
  • ASML164 вакансии
  • Grab134 вакансии
  • Celonis45 вакансий
  • Spotify37 вакансий
  • Adyen29 вакансий
  • Infobip28 вакансий
  • Monzo19 вакансий
  • Darktrace17 вакансий

Вакансии из 344 источников: карьерные страницы компаний и джоб-борды.

КомпанииО насНовостиПубличная офертаУсловия использованияПолитика конфиденциальностиПоддержка
←К теме Kotlin MultiplatformВсе вопросы
Kotlin MultiplatformMiddleКодинг

Как тестировать общий KMP-код?

В закладки
Сначала попробуйте ответить сами30 секунд
Сравнить с ответом ↓

Общий KMP-код тестируется через kotlin.test в commonTest. Тесты компилируются для всех таргетов. Для корутин используется kotlinx-coroutines-test с runTest, для моков — Mockative или ручные фейки.

Зависимости и конфигурация

// shared/build.gradle.kts:
kotlin {
    androidTarget()
    iosX64(); iosArm64(); iosSimulatorArm64()
    jvm()

    sourceSets {
        commonTest.dependencies {
            implementation(kotlin("test"))  // @Test, assertEquals, etc.
            implementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.8.1")
        }
    }
}

Инструменты тестирования в KMP

Kotlin Multiplatform поддерживает единый тестовый фреймворк kotlin.test, который предоставляет аннотации @Test, @BeforeTest, @AfterTest и assertions. Тесты в commonTest компилируются и выполняются на каждом таргете: JVM, Android Unit Test, iOS Simulator.

Базовые тесты в commonTest

// src/commonTest/kotlin/FormattersTest.kt
class SalaryFormatterTest {

    @Test
    fun formatSalaryWithBothBounds() {
        val salary = Salary(min = 100_000, max = 200_000, currency = "RUB")
        assertEquals("100000–200000 RUB", formatSalary(salary))
    }

    @Test
    fun formatSalaryMinOnly() {
        val salary = Salary(min = 100_000, max = null, currency = "USD")
        assertEquals("from 100000 USD", formatSalary(salary))
    }

    @Test
    fun emptyEmailFailsValidation() {
        assertFalse(validateEmail(""))
    }

    @Test
    fun validEmailPassesValidation() {
        assertTrue(validateEmail("user@example.com"))
    }
}

Тестирование suspend-функций

// src/commonTest/kotlin/UserRepositoryTest.kt
class UserRepositoryTest {

    private lateinit var repo: UserRepository
    private lateinit var fakeApi: FakeUserApi

    @BeforeTest
    fun setup() {
        fakeApi = FakeUserApi()
        repo = UserRepository(fakeApi)
    }

    @Test
    fun loadUsersReturnsSortedList() = runTest {
        fakeApi.users = listOf(
            User("2", "Bob"),
            User("1", "Alice")
        )
        val result = repo.getUsers()
        assertEquals("Alice", result.first().name)
    }

    @Test
    fun loadUsersThrowsOnNetworkError() = runTest {
        fakeApi.shouldThrow = true
        assertFailsWith<NetworkException> {
            repo.getUsers()
        }
    }

    // Тест с контролем времени:
    @Test
    fun cacheExpiresAfter5Minutes() = runTest {
        repo.getUsers()  // первый запрос — кэшируется
        advanceTimeBy(4 * 60 * 1000)  // 4 минуты
        repo.getUsers()  // второй запрос — из кэша
        assertEquals(1, fakeApi.callCount)

        advanceTimeBy(2 * 60 * 1000)  // ещё 2 минуты
        repo.getUsers()  // кэш истёк — новый запрос
        assertEquals(2, fakeApi.callCount)
    }
}

Фейковые реализации вместо моков

// src/commonTest/kotlin/fakes/FakeUserApi.kt
class FakeUserApi : UserApi {
    var users: List<User> = emptyList()
    var shouldThrow: Boolean = false
    var callCount: Int = 0

    override suspend fun fetchUsers(): List<User> {
        callCount++
        if (shouldThrow) throw NetworkException("Network error")
        return users
    }

    override suspend fun getUser(id: String): User =
        users.find { it.id == id } ?: throw NotFoundException(id)
}

Mockative для автогенерации моков

// build.gradle.kts:
commonTest.dependencies {
    implementation("io.mockative:mockative:2.2.2")
}
// plugins:
id("com.google.devtools.ksp")

// Тест:
@Mock
val userApi = mock(classOf<UserApi>())

@Test
fun callsApiOnce() = runTest {
    given(userApi).coroutine { fetchUsers() }.thenReturn(listOf(User("1", "Alice")))

    val repo = UserRepository(userApi)
    repo.getUsers()

    verify(userApi).coroutine { fetchUsers() }.wasCalled()
}

Запуск тестов

// JVM (самый быстрый, без эмулятора):
./gradlew jvmTest

// Android Unit Tests:
./gradlew testDebugUnitTest

// iOS Simulator (требует macOS):
./gradlew iosSimulatorArm64Test

// Все таргеты:
./gradlew allTests

Подводные камни

  • Использование runBlocking вместо runTest в commonTest — на Kotlin/Native runBlocking на Main-потоке может дедлочить; runTest — правильная замена;
  • Реальный delay() в тестируемом коде без advanceTimeBy() — тесты выполняются в реальном времени и замедляют CI в десятки раз;
  • Использование @BeforeClass (JUnit4) в commonTest — аннотация отсутствует в kotlin.test; используйте @BeforeTest;
  • Прямое использование мока Mockito или MockK в commonTest — они работают только на JVM; для KMP нужны Mockative или ручные фейки;
  • Тестирование конкретных actual-реализаций из commonTest — тест получает JVM-реализацию, а не iOS; тесты actual пишите в платформенных test source sets;
  • Пропуск @AfterTest для закрытия БД/клиента — на Kotlin/Native утечки между тестами могут вызвать IncorrectDereferenceException;
  • Зависимость kotlinx-coroutines-test добавлена только в jvmTest вместо commonTest — тесты корутин не компилируются на iOS-таргете.

Частые вопросы на собеседовании

  • Что такое структура source set: commonMain, androidMain, iosMain?
  • Какой код можно разделять между платформами, а какой должен оставаться платформо-зависимым?
  • Как структурировать KMP-проект (shared module, платформо-зависимые модули)?
  • Что такое Kotlin Multiplatform (KMP) и какие платформы он поддерживает?

Типичные ошибки

  • Объяснять «тестирование common KMP-кода» только как синтаксис и не описывать поведение runtime/compiler.
  • Игнорировать важный риск: Если тестировать только Android, iOS actual-код может не компилироваться или вести себя иначе.
  • Давать пример без edge case: отмены, null, recomposition, platform boundary или ошибки.

Что проверяет интервьюер

  • Формулирует суть темы «тестирование common KMP-кода» своими словами и связывает ее с кодом.
  • Называет механизм: kotlin.test дает общий API, но окружение, dispatcher, database driver и file system нужно подбирать по target.
  • Видит production-последствие: Если тестировать только Android, iOS actual-код может не компилироваться или вести себя иначе.

Как вы знаете этот вопрос?

Проверить себя по теме Kotlin Multiplatform →

Источники

  • https://kotlinlang.org/docs/multiplatform/multiplatform-run-tests.html
←Предыдущий вопросКак KMP взаимодействует со Swift/Objective-C на iOS?Следующий вопрос→Как разделять сетевой код между платформами в KMP (например, с помощью Ktor)?

Связанные темы

Kotlin Multiplatformplatform-boundariestesting-common-code-reasoning