https://kotlinlang.org logo
Join SlackCommunities
Powered by
# test
  • t

    tylerwilson

    07/31/2024, 2:51 PM
    What is the current preferred method to test functions in commonMain that can take some time, like API calls? On the Android side I fund the CountDownLatch/.await works well. Is there a similar approach using coroutines test that I can use in commonTest? Thank you!
    c
    • 2
    • 6
  • t

    tylerwilson

    08/02/2024, 12:59 PM
    Related question to the above: thank you to Ivan, using suspendCoroutine works well from commonTest running against Android or JVM, but when I try to run against iosSimulator64Test, it never finishes. See thread:
    e
    • 2
    • 3
  • c

    CLOVIS

    08/12/2024, 7:00 AM
    I wrote about time control in tests using KotlinX.Coroutines.Test: https://opensavvy.gitlab.io/groundwork/prepared/docs/features/time.html The article uses the Prepared helpers (which provide
    Clock
    s or allow setting a specific time using an Instant directly) but most things mentioned also works if you're using any other testing library.
  • s

    Sergio Pro

    08/12/2024, 4:32 PM
    Hi all! 👋 Just wanted to share my testing lib for generating fake data - kotlin-faker. Unfortunately only JVM is supported for now, but hopefully multiplatform will come soon 😏 (well... as soon as I get some extra time to learn it, or someone contributes 😄 ) And as a side bonus, it also includes property-testing extension for my favorite kotlin testing lib - kotest. Hope someone finds it useful; and if not - that's also OK 🙂 Cheers 🤜 🤛
    c
    • 2
    • 23
  • m

    Marcus Randevik

    09/09/2024, 1:03 PM
    Hi everyone, during our migration to java 21 I noticed some changed behavior that I cannot track down as to why it happens. We have a category of tests that are classified by using a custom tag as follows:
    Copy code
    @Tag(TestCategory.DatabaseTest)
    annotation class DatabaseTest {
        companion object {
            init {
                sharedDependency = TestImplementationOfDependency()
            }
        }
    }
    The shared dependency is declared as follow in order to be switched out in tests:
    Copy code
    var sharedDependency: SharedDependency? = null
    val SHARED_DEPENDENCY: SharedDependency
        get() {
            if (sharedDependency == null) {
                sharedDependency = ProductionImplementationOfDependency()
            }
            return sharedDependency ?: throw RuntimeException("SharedDependency set to null by another thread")
        }
    When running on java 11, the shared dependency is correctly set to the TestImplementation, this can clearly be seen by placing a breakpoint in the init block. However, when running on java 21 the init block of the tag is not executed. Does anyone have a clue as to why that could be?
  • g

    Guyaume Tremblay

    09/13/2024, 1:33 PM
    Hi everyone! Is it possible to override an
    actual
    in
    *unitTest
    ? My situation is that I have an
    expect/actual
    in an
    object
    which return the user language and I have a test which look for a date (like
    January 1st
    ) My date formater is using this
    object
    and, mokkery can't mock an object. Now, if my computer is not in english but my CI is, my test will fail... I tried to put an actual in
    androidUnitTest
    but it complain that there is no expect in
    commonTest
    ... Do you think of something else please ?
    e
    • 2
    • 4
  • x

    Xavier F. Gouchet

    09/20/2024, 11:52 AM
    Hello everyone. Has anyone been able to setup mutation testing on an Android/Kotlin project. I heard about Arcmutate but couldn't find if it was compatible with android modules
    👀 1
    e
    c
    • 3
    • 5
  • o

    Ousc

    09/30/2024, 9:47 AM
    Hello everyone, Help! The
    kotlin.test
    dependency in my local maven repository seems to get lost when I switch between projects (some of them use
    maven
    builds, some use
    gradle
    builds). the project prompts that
    kotlin.test
    is not found, and refresh gradle dependencies doesn't fix it, the only way I can fix it is by deleting the
    ~/.m2/org/jetbrains /kotlin/kotlin-test
    folder and reloading the gradle project to fix it. Both my partner and I are experiencing the same issue when running a few specific projects. Has anyone else encountered this or have any ideas on how to resolve it, it's been bugging me for a long time 😞.
    👀 1
    c
    • 2
    • 14
  • o

    Olivier Patry

    10/03/2024, 7:01 PM
    Using
    AndroidComposeTestRule
    , I'm trying a basic E2E scenario on my app. The main content stays blank (I get top app bar, bottom nav etc.) until the test finishes, despite using the
    waitUntil*
    helpers. I have 2 steps in the start sequence to load content:
    null
    (loading), then
    List<T>
    (empty or not), the first step remains until test end but never change before that. The state relies on a Room database
    Flow
    from a
    Dao
    . What could prevent the Room flow mechanism to operate in the context of Compose UI tests?
    ✅ 1
    c
    • 2
    • 6
  • s

    SimonT

    10/10/2024, 7:21 PM
    Hello, I wanted to ask about something I haven't tried in a while, I used to do the initial call inside viewmodels in the init block and then for testing use pause dispatcher and resume dispatcher to connect the flow to turbine before my init call started while creating the viewmodel. From what I see the pause and resume dispatcher are deprecated, so I wanted to ask what's recommend to do right now. My intention is to see that we get the loading state and then success state with specific data and then nothing else. Thank you in advance.
    s
    • 2
    • 2
  • d

    Daniel Weidensdörfer

    10/11/2024, 7:27 PM
    Hello, are parameterized tests supported in kotlin-test? And if not, are there plans to support it?
    c
    • 2
    • 2
  • e

    enighma

    11/02/2024, 3:15 AM
    Java test broke once I converted a file under test to Kotlin. I'm using MockedStatic for what was a static function. Now it's a companion function that is marked @JvmStatic. But it returns
    null
    when used instead of the what I've passed to
    thenReturn
    c
    • 2
    • 1
  • m

    Manuel Lorenzo

    11/07/2024, 9:04 PM
    How can I test a flow that uses .stateIn in an Android ViewModel?
    s
    • 2
    • 27
  • k

    Krishna Prasad

    11/14/2024, 12:27 AM
    Hi, anyone faces issues while adding espresso dependencies as
    androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.6.1'
    while testing navigation fragments
    • 1
    • 2
  • k

    kgurgul

    11/14/2024, 8:44 AM
    Hi, do you know a good alternative to the
    verify
    method for KMP without using mocking libraries?
    d
    j
    • 3
    • 41
  • g

    Guilherme Delgado

    11/20/2024, 12:29 PM
    Hello! I’m getting the following output and
    java.lang.AssertionError
    when using Asserts with kotlin
    2.1.0-RC
    or
    2.1.0-RC2
    . If I downgrade to
    2.0.21
    it works:
    Copy code
    e: .gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/2.1.0-RC2/a2fc741252a95c0b35b2f6803cc4593751adc78f/kotlin-stdlib-2.1.0-RC2.jar!/META-INF/kotlin-stdlib-jdk7.kotlin_moduleModule was compiled with an incompatible version of Kotlin. The binary version of its metadata is 2.1.0, expected version is 1.9.0.
    e: .gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/2.1.0-RC2/a2fc741252a95c0b35b2f6803cc4593751adc78f/kotlin-stdlib-2.1.0-RC2.jar!/META-INF/kotlin-stdlib-jdk8.kotlin_moduleModule was compiled with an incompatible version of Kotlin. The binary version of its metadata is 2.1.0, expected version is 1.9.0.
    e: .gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/2.1.0-RC2/a2fc741252a95c0b35b2f6803cc4593751adc78f/kotlin-stdlib-2.1.0-RC2.jar!/META-INF/kotlin-stdlib.kotlin_moduleModule was compiled with an incompatible version of Kotlin. The binary version of its metadata is 2.1.0, expected version is 1.9.0.
    e: .gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-test-junit/2.1.0-RC2/b93d3ae5bf5d6705f0a7e996ae76625be9aab838/kotlin-test-junit-2.1.0-RC2.jar!/META-INF/kotlin-test_JUnit.kotlin_moduleModule was compiled with an incompatible version of Kotlin. The binary version of its metadata is 2.1.0, expected version is 1.9.0.
    e: .gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-test/2.1.0-RC2/589f4d86f57a00236e6af14e85e84f043ca7e41f/kotlin-test-2.1.0-RC2.jar!/META-INF/kotlin-test.kotlin_moduleModule was compiled with an incompatible version of Kotlin. The binary version of its metadata is 2.1.0, expected version is 1.9.0.
    Can someone elucidate me? Thanks!
    m
    • 2
    • 12
  • d

    David Kubecka

    11/22/2024, 3:42 PM
    A little bit of brainstorming here. In testing, specifically when comparing expected and actual values, I would like to ignore certain fields located deep in a nested data class structure. I know I can do that with assertj using
    Copy code
    assertThat(actual).usingRecursiveComparison().ignoringFields("my.nested.field", MyClass::otherField.name).isEqualTo(expected)
    but that is unsatisfactory for two reasons: • The ignore list is either not type-safe (plain strings) or is too verbose (property references) • The ignore list needs to be specified on the call site instead of on the declaration side. The latter point is important in the case of test fixtures which are shared among many tests and which contain some dynamic or computed data, such as dates or hashes. In such cases it would be much more convenient for me if I could ignore the field "on the declaration side, e.g. like this:
    Copy code
    my TEST_DATA = MyClass(fixedField = TEST_VALUE, dynamicField = any())
    and then use some special assertion function that understands that
    any()
    . For that to work, I imagine that the return type of
    any()
    should be both a subclass of the
    dynamicField
    type as well some marker type for the assertion function. E.g. in pseudo code
    Copy code
    interface AnyMarker
    
    inline fun <reified T> any() = object : T, AnyMarker {}
    This looks very similar to how Spring creates proxy classes. That relies on the all-open compiler plugin. But I can't use a similar trick here because • It would be quite impractical to mark a class with some annotation for the plugin only for the testing use case • I'm not even sure I can "open" classes such as
    String
    which would be needed for the important ignore-hash use case. My questions are: • Does this idea make sense? • Is it feasible? If yes, how to effectively implement
    any()
    (or something similar)?
    e
    s
    c
    • 4
    • 9
  • m

    mbonnin

    11/29/2024, 2:42 PM
    Trying to understand why the JS vs JVM behaviour is different when async coroutines are launched:
    Copy code
    @Test
      fun test() = runTest {
        CoroutineScope(Dispatchers.Default).launch {
          delay(10.seconds)
          println("done")
        }
      }
    JVM: completes immediately, without printing "done". JS: takes 10s and prints done. Is there a fundamental reason this is like this? Could JS just ignore the launched coroutine? (Or if it's a problem because it has side effects for other tests, shouldn't the bahaviour be the same for JVM?)
    👀 1
    o
    c
    • 3
    • 18
  • r

    Romain

    12/06/2024, 1:50 AM
    Hi there! Out of curiosity, has anyone found a framework for "web application testing" that they are happy with? Looking for something with a nice DSL to say like "click here", "submit this form with those values" etc.. I haven't found anything active enough, but I'm probably gonna keep looking
    c
    • 2
    • 2
  • d

    David Kubecka

    12/09/2024, 3:52 PM
    I would like to write a generic type-safe TestData class for JUnit parametrized tests. I imagine something like this:
    Copy code
    import org.junit.jupiter.params.provider.Arguments
    
    data class TestData<G, E>(val testName: String, val given: G, val expected: E) {
        override fun toString() = testName
    }
    
    fun <G, E> List<TestData<G, E>>.asArguments() = map { Arguments.of(it) }
    
    fun myTestMethodTestData() = listOf(
      TestData("test case 1", 1, "1"),
      TestData("test case 2", 2, "2"),
    ).asArguments()
    This works fine but isn't type-safe, i.e. nothing prevents me from writing
    Copy code
    fun myTestMethodTestData() = listOf(
      TestData("test case 1", 1, "1"),
      TestData("test case 2", "2", 2),
    ).asArguments()
    Is there any way how that can be achieved? At first I thought I could utilize
    @NoInfer
    to force the user to specify the type arguments explicitly, e.g.
    asArguments<Int, String>()
    , but of course that doesn't enforce anything about the types in the
    TestData
    class instance...
    s
    • 2
    • 3
  • m

    martmists

    12/14/2024, 3:35 PM
    How can I assert that two double arrays are the same within some tolerance? There doesn't seem to be a parameter to specify this in kotlin.test, so it's failing due to float/double precision.
  • p

    Piotr Krzemiński

    01/15/2025, 6:30 AM
    what's the fate of https://github.com/Kotlin/kotlinx-knit? I'd like to use it, but I see the latest release is from 2.5 years ago kodee sad
    l
    • 2
    • 1
  • k

    Krishna Prasad

    01/16/2025, 11:07 PM
    Hi everyone, Does anyone successfully implement https://github.com/Xray-App/xray-junit-extensions/ in android project for customizing test reports ?
  • a

    aherbel

    02/07/2025, 1:34 AM
    hello, I have a problem with a UI test I want to write... I have a simple app: just a MainActivity that displays a list in a LazyColumn. The data is pulled from the MainViewModel which, in turns, ask it to a repository. I want to make a test for it, but the problem I am having is that I am not being able to configure the FakeRepository before the activity starts and call the viewmodel to fetch the data. I am using Hilt as a DI framework and "createAndroidComposeRule<MainActivity>()" in my test Is there a way to configure the fake before the activity start? or maybe delay the start of the activity until the fake is configured and after that make assertions with a composeRule other than the AndroidComposeTestRule?
  • j

    jean

    03/04/2025, 11:03 PM
    I’m running in a weird error while testing android view models from junit tests. If I manually set
    Dispatchers.setMain(UnconfinedTestDispatcher(testScheduler))
    in my test function, it works. But if I use a Rule instead to do it, it fails. I do create the viewmodel from withing the test function and I do have the
    @get:Rule
    as the first thing in the test class. I really don’t understand what I’m doing wrong here. Any idea on what I am missing?
    • 1
    • 1
  • p

    Piero Silvestri

    03/06/2025, 9:41 AM
    Hello! ✋ I would like to share my new tutorial, in which I implemented the Screenshot Testing inside a Compose Multiplatform App. If this is not the best channel to share it, I will delete this. Please, fell free to write me if you find some errors! 🙂 Any kind of feedback is welcome! https://medium.com/@munsra/using-screenshot-tests-in-a-compose-multiplatform-app-8fa171a3975d
    kodee happy 1
  • m

    Meika

    03/07/2025, 4:22 AM
    hi all, is using the KSP or all-open plugin the only way to mock classes in Multiplatform project tests? currently, we are trying to migrate away from MockK since it doesn't support Multiplatform. we found that most mocking libraries either use KSP or all-open plugins, which require annotating the classes that need to be mocked. we’re not entirely comfortable with this approach, as it introduces test-related annotations/code into
    commonMain
    . right now, we’re leaning towards using Mokkery since it makes migration easier syntax-wise. however, it still requires us to annotate the classes for mocking. crossposting from #C3PQML5NU since it also make sense to ask here
    j
    • 2
    • 2
  • e

    Ed Holloway-George

    03/26/2025, 12:02 PM
    kodee greetings Hey, I have a very simple question that's been driving me a little potty when using Kotlin Test because I have seen some conflicting opinions
    ```class FakeRepo: Repo {
    private val users = mutableSetOf<String>()
    fun addUser(name: String) {
    users.add(name)
    }
    fun getUserCount(): Int {
    return users.size
    }
    }
    class SomeService(val repo: Repo) {
    fun addUser(name: String) {
    userRepository.addUser(name)
    }
    fun getUserCount(): Int {
    return userRepository.getUserCount()
    }
    }```
    If you write tests in this form:
    ```class SomeServiceTest {
    private val repo = FakeRepo()
    private val sut = SomeService(repo)
    @Test
    fun test1() {
    service.registerUser("Alice")
    val result = sut.getUserCount()
    assertEquals(1, result)
    }
    @Test
    fun test2() {
    service.registerUser("Bob")
    service.registerUser("Charlie")
    val result = sut.getUserCount()
    assertEquals(2, result)
    }
    }```
    Each individual test will pass if it executes first, but wont pass if it's executed after the other. As the order tests are run isn't guaranteed, this is a common cause of issues with fakes that hold state.
    Am I right here? The correct approach would be to init
    sut
    in a
    @BeforeTest
    method right? One of my colleagues mentioned
    FakeRepo
    would be recreated every time without
    @BeforeTest
    d
    • 2
    • 7
  • m

    Maiko Trindade

    04/16/2025, 4:37 PM
    Anybody knows anything about Journeys with Gemini for Android UI Testing? Firebase AI Agent was released recently but I was wondering when Journeys would be released as well.
  • n

    Nino

    04/18/2025, 12:24 PM
    Hello, I'm looking for an assertion library or any tips to allow me to assert that a data class has all its fields equals to another data class, except for the possible lambdas. I don't care about the lambdas since they can't be tested anyway, a UI test will actually take care of that. But the fields like
    label
    and other stuff has great value to test. I would like to avoid overriding the equal function of the data class for obvious reasons. Any ideas ?
    Copy code
    // Source code
    data class Foo(
        val label: String,
        val onClicked: () -> Unit,
        val onValueChanged: (Int) -> Unit,
    )
    
    object FooMapper {
        fun map(
            label: String,
            viewModel: FooViewModel,
        ) = Foo(
            label = label,
            onClicked = { viewModel.onFooClicked() },
            onValueChanged = { viewModel.onValueChanged(it.toLong()) },
        )
    }
    
    class FooViewModel {
        fun onFooClicked() { /* whatever */ }
        fun onValueChanged(value: Long) { /* whatever */ }
    }
    
    // Unit tests
    class FooMapperTest {
        @Test
        fun `foo map`() {
            // Given
            val label = "label"
            val fooViewModel = mockk<FooViewModel>()
    
            // When
            val result = FooMapper.map(label = label, viewModel = fooViewModel)
    
            // Then
            // !! What should I use there?
            assertEquals(
                Foo(label = label, onClicked = {}, onValueChanged = {}),
                result
            )
        }
    }
    e
    • 2
    • 12