https://kotlinlang.org logo
Join Slack
Powered by
# test
  • 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
  • m

    Maiko Trindade

    05/20/2025, 8:12 PM
    Does anybody know when we can start using

    Journeys▾

    for Android testing?
    ➕ 1
    • 1
    • 1
  • j

    Jonathan

    06/09/2025, 3:39 PM
    I’m having drop testing a function that uses a withTimeoutOrNull(). Is there a recommended way of testing such code?
    c
    c
    • 3
    • 11
  • s

    Sergey Dmitriev

    06/27/2025, 12:49 PM
    Hello 👋 Is there any good replacement for JUnit
    ParameterizedTest
    ?
    c
    • 2
    • 2
  • l

    Luv Kumar

    07/11/2025, 12:08 PM
    hi, is there a way to do deep comparison of two objects(of non data classes) in commonTest (something equivalent of
    assertReflectionEquals
    in java), i found
    shouldBeEqualToComparingFields
    in kotest assertions module but that is also jvm only.
    c
    e
    • 3
    • 4
  • u

    ursus

    07/16/2025, 10:27 PM
    Copy code
    kotlin-powerAssert = { id = "org.jetbrains.kotlin.plugin.power-assert", version.ref = "kotlin" }
    
    plugins {
        ...
        alias(libs.plugins.kotlin.powerAssert)
    }
    Copy code
    import kotlin.test.Test
    
    
    class ExampleUnitTest {
        @Test
        fun testFunction() {
            val hello = "Hello"
            val world = "world!"
            assert(hello.length == world.length)
        }
    }
    ... No matter what I do, I'm getting just the basic
    Copy code
    Assertion failed
    java.lang.AssertionError: Assertion failed
    	at foo.bar.ExampleUnitTest.testFunction(ExampleUnitTest.kt:11)
    	at java.base/java.lang.reflect.Method.invoke(Method.java:569)
    	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
    	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
    and not the right messages what am I doing wrong?
    e
    • 2
    • 1
  • a

    Alex Kuznetsov

    07/23/2025, 5:21 PM
    Maintainer of kotest here. Can you share anecdotes about flaky tests, what causes your tests to be flaky, how you resolve that, etc.. This will help us improve kotest. TIA!
    c
    • 2
    • 2
  • m

    mbonnin

    07/26/2025, 1:17 PM
    For JS browser tests, is there a way to hook into the test infrastructure to start/stop a JVM server during the tests? Is anything like this possible?
    l
    o
    • 3
    • 11
  • m

    maarten ha

    08/09/2025, 1:20 PM
    Are there tools for mutation testing that are compatible with kotlin native? Like for when writing KMP libraries I can not just use Pitest if I got it correct since it’s a JVM thing
    c
    • 2
    • 3
  • e

    Eugen Martynov

    08/11/2025, 6:17 AM
    Have you found a way for jacoco ignoring compose previews except the annotation with
    Generated
    word inside?
    • 1
    • 1
  • j

    joseph_ivie

    08/15/2025, 4:35 PM
    Could we get the standard testing library to support
    assume()
    ? Granted I'd prefer different naming, but that's less important than having it supported.
    o
    • 2
    • 8
  • e

    edwinRNDR

    08/17/2025, 8:18 AM
    on JVM targets (but also in general) why do assertEquals with NaN arguments pass? I'd expect
    Copy code
    kotlin.test.assertEquals(Double.NaN, Double.NaN, 1e-6)
    to fail because
    Double.NaN != Double.NaN
    e
    • 2
    • 4
  • u

    ursus

    08/21/2025, 7:24 PM
    Copy code
    class FooTest {
    	private val myDependency = Dependency(StandardTestDispatcher(testScheduler)) <----
    
    	@Test fun foo() = runTest {
    		// val dispatcher = StandardTestDispatcher(testScheduler)
    		...
    	}
    }
    I like to construct dependencies to the sut in properties, but
    testScheduler
    is only available from inside the
    runTest
    lambda, which is "too late" for me. How do I access
    testScheduler
    from a property?
    o
    • 2
    • 49
  • j

    jessewilson

    09/04/2025, 9:03 PM
    this goes out to all the test enjoyers https://code.cash.app/burst-test-interceptors
    👏 2
    👏🏻 1
    👏🏼 1
    z
    c
    o
    • 4
    • 17
  • j

    jessewilson

    09/09/2025, 3:40 PM
    FYI, we’re doing HTML snapshot testing in Redwood. I would love to get this into a standalone library but I haven’t done the work for that yet. Here’s what it looks like!
    Copy code
    @Test
      fun happyPath() = runTest {
        val helloWorld = document.createElement("div").apply {
          appendElement("h1") {
            appendText("hello world")
          }
        }
        snapshotter.snapshot(helloWorld, "happyPath", Frame.None)
      }
    nice spin 1
  • o

    Oliver.O

    09/11/2025, 1:15 PM
    ℹ️: testballoon TestBalloon 0.6.0-K2.2.0 has been successfully tested to work with Kotlin 2.2.20. With its variants, the latest TestBalloon release 0.6.0 continues to support all Kotlin versions since 2.0.0.
    🚀 4
  • d

    dave08

    09/11/2025, 1:54 PM
    A little point... how could one use Robolectric with test balloon? https://robolectric.org/androidx_test/ seems to have it's own runner...
    o
    • 2
    • 1