Fixtures for Kotlin providing generated values for unit testing

Overview

KotlinFixture

Maven Central CI status Coverage status License

A tool to generate well-defined, but essentially random, input following the idea of constrained non-determinism.

Getting started

Include the following dependency in your build.gradle.kts file:

build.gradle.kts
")">
testImplementation("com.appmattus.fixture:fixture:
       
        "
       )

Simply create a fixture and invoke it with the type to be generated:

() // Abstract classes will pick a sub-class at random // This could be a Byte, Double, Long, Float, Int or Short val anyNumber = fixture () // Pick randomly from a list val randomStringFromTheList = fixture(listOf("Cat", "Dog", "Horse")) val anotherRandomIntFromAList = fixture(1..5)">
val fixture = kotlinFixture()

// Generate a list of strings
val aListOfStrings = fixture<List<String>>()

// Nulls are supported
val sometimesNull = fixture<Int?>()

// Create instances of classes
// Optional parameters will be randomly used or overridden
data class ADataClass(val value: String = "default")
val aClass = fixture<ADataClass>()

// Abstract classes will pick a sub-class at random
// This could be a Byte, Double, Long, Float, Int or Short
val anyNumber = fixture<Number>()

// Pick randomly from a list
val randomStringFromTheList = fixture(listOf("Cat", "Dog", "Horse"))
val anotherRandomIntFromAList = fixture(1..5)

You can also generate an infinite sequence of a type, which you can then filter:

val fixture = kotlinFixture()

val intSequence = fixture.asSequence<Int>()

// Standard Kotlin sequence functions can then be applied before using
// the sequence through an iterator for access to the next() function.

// For example, you can filter values
val oddIterator = intSequence.filter { it.absoluteValue.rem(2) == 1 }.iterator()
val oddNumber = oddIterator.next()
val anotherOddNumber = oddIterator.next()

// Or, ensure it returns only distinct values
enum class XYZ { X, Y, Z }
val enumIterator = fixture.asSequence<XYZ>().distinct().iterator()
val aDistinctValue = enumIterator.next()
val anotherDistinctValue = enumIterator.next()
⚠️

The sequence can hang indefinitely if the applied operators prevent the generation of new values. For example:

  • distinct will hang if we exhaust all available values. A good practice is to add a take(count) which will throw a NoSuchElementException if we try to generate more values.

  • filter that can never be fulfilled e.g. filter { false }

Configuration options

Everything can be customised, see configuration options for more details.

Advanced engine customisation is also possible if the above options are not enough.

Kotest integration: property based testing

The library provides KotlinFixture powered property based testing for Kotest.

See Kotest integration for more details.

Java Faker integration: pretty data

Generate values with a closer match to real data using Java Faker.

See Java Faker integration for more details.

Generex integration: regex to random string

To generate a random string from a regular expression, look no further than the Generex integration.

See Generex integration for more details.

Please take a look at the feature comparison with related projects.

Contributing

Please fork this repository and contribute back using pull requests.

All contributions, large or small, major features, bug fixes, additional language translations, unit/integration tests are welcome.

License

License

Copyright 2020 Appmattus Limited

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.apache.org/licenses/LICENSE-2.0.

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Comments
  • How to apply NeverNullStrategy on list Items

    How to apply NeverNullStrategy on list Items

    The documentation here specifies that you can ensure all generated values are non null. I tried using this when generating a list of Trail objects to ensure that none of the trail element properties would be null. Also, I'm referencing this library in an Android instrumentation test.

    Here is what my fixture configuration looks like:

    private val fixture = kotlinFixture {
        nullabilityStrategy(NeverNullStrategy)
    }
    private val trails = fixture<List<Trail>>()
    

    Here is the Trail class:

    data class Trail(
        val name: String? = null,
        var username: String? = null,
        val startLatitude: Double? = null,
        val startLongitude: Double? = null,
        val endLatitude: Double? = null,
        val endLongitude: Double? = null,
        val description: String? = null,
        val city: String? = null,
        val state: String? = null,
        val distance: Double? = null
    )
    

    Here's a screenshot showing that some values are null: Screen Shot 2020-11-20 at 9 43 39 AM

    Am I missing something in the configuration to make this work properly? Thanks!

    This library is great by the way :)

    opened by Alton09 3
  • Could not resolve com.appmattus.fixture:fixture-generex:0.9.6 from jcenter repository

    Could not resolve com.appmattus.fixture:fixture-generex:0.9.6 from jcenter repository

    When I tried to get the fixture-generex dependency from jcenter I couldn't resolve it. However, if I uncomment the dl.bintray.com repo commented out below, the dependencies are resolved properly. It seems like a jcenter problem, but I think it needs to be checked

    ./gradlew test --info | grep fixture-generex
    Resource missing. [HTTP HEAD: https://repo.jfrog.org/artifactory/libs-release-bintray/com/appmattus/fixture/fixture-generex/0.9.6/fixture-generex-0.9.6.pom?referrer]
    Resource missing. [HTTP HEAD: https://repo.maven.apache.org/maven2/com/appmattus/fixture/fixture-generex/0.9.6/fixture-generex-0.9.6.pom]
    
    FAILURE: Build failed with an exception.
    
    * What went wrong:
    Execution failed for task ':extractIncludeProto'.
    > Could not resolve all files for configuration ':compileProtoPath'.
       > Could not resolve com.appmattus.fixture:fixture-generex:0.9.6.
         Required by:
             project :
    
    // build.gradke.kts
    
    repositories {
        jcenter()
        mavenCentral()
        // maven("https://dl.bintray.com/appmattus/maven")
    }
    
    
    dependencies {
        testImplementation("com.appmattus.fixture:fixture:0.9.6")
        testImplementation("com.appmattus.fixture:fixture-generex:0.9.6")
        testImplementation("com.appmattus.fixture:fixture-javafaker:0.9.6")
    }
    
    opened by wickedev 3
  • Make PopulateInstance interface public to make creating new resolvers easier

    Make PopulateInstance interface public to make creating new resolvers easier

    Hi,

    First of all, thanks for this nice and promising library :slightly_smiling_face:

    I'd like to create a variant of ClassResolver in order to apply the default constructor strategy that is used in this library's honorable .NET cousin, AutoFixture. Unlike the random approach you chose in your ClassResolver, it will use the constructor with the fewest parameters as explained here.

    I was about to simply duplicate the ClassResolver class, but unfortunately PopulateInstance interface is internal, making it impossible to use it directly. Is there a reason for that ? Wouldn't it be useful to make it public in order to allow this kind of customizations ?

    Or is there another way to achieve that that I missed ?

    Thanks

    opened by DeafLight 3
  • How to configure a factory that would generate suspend functions ?

    How to configure a factory that would generate suspend functions ?

    Hi,

    Running kotlinfixture 1.0, I'm trying to configure a fixture to generate suspend functions, for instance :

    class test : StringSpec({
        "test1" {
            val fixture = kotlinFixture() {
                factory<suspend (String) -> String> {
                    {
                        delay(1)
                        ""
                    }
                }
            }
        }
    })
    

    But I keep getting the following error :

    Class declares 3 type parameters, but 2 were provided.
    java.lang.IllegalArgumentException: Class declares 3 type parameters, but 2 were provided.
    	at kotlin.reflect.full.KClassifiers.createType(KClassifiers.kt:53)
    	at kotlin.reflect.jvm.internal.ReflectionFactoryImpl.typeOf(ReflectionFactoryImpl.java:123)
    	at kotlin.jvm.internal.Reflection.typeOf(Reflection.java:137)
    	at com.dummy.fixturetest.test$1$1$fixture$1.invoke(KotlinFixtureSuspendTest.kt:117)
    	at com.dummy.fixturetest.test$1$1$fixture$1.invoke(KotlinFixtureSuspendTest.kt:9)
    	at com.appmattus.kotlinfixture.KotlinFixtureKt.kotlinFixture(KotlinFixture.kt:102)
    	at com.dummy.fixturetest.test$1$1.invokeSuspend(KotlinFixtureSuspendTest.kt:11)
    	at com.dummy.fixturetest.test$1$1.invoke(KotlinFixtureSuspendTest.kt)
    	at io.kotest.core.internal.ExecutionsKt$executeWithBehaviours$2$1.invokeSuspend(executions.kt:13)
    	at io.kotest.core.internal.ExecutionsKt$executeWithBehaviours$2$1.invoke(executions.kt)
    	at io.kotest.core.internal.ExecutionsKt.wrapTestWithGlobalAssert(executions.kt:39)
    	at io.kotest.core.internal.ExecutionsKt$executeWithBehaviours$2.invokeSuspend(executions.kt:12)
    	at io.kotest.core.internal.ExecutionsKt$executeWithBehaviours$2.invoke(executions.kt)
    	at io.kotest.core.internal.ExecutionsKt$wrapTestWithAssertionModeCheck$2.invokeSuspend(executions.kt:25)
    	at io.kotest.core.internal.ExecutionsKt$wrapTestWithAssertionModeCheck$2.invoke(executions.kt)
    	at io.kotest.core.internal.AssertionsCheckKt.executeWithAssertionsCheck(assertionsCheck.kt:25)
    	at io.kotest.core.internal.ExecutionsKt.wrapTestWithAssertionModeCheck(executions.kt:24)
    	at io.kotest.core.internal.ExecutionsKt.executeWithBehaviours(executions.kt:11)
    	at io.kotest.core.internal.TestCaseExecutor$executeInScope$2.invokeSuspend(TestCaseExecutor.kt:258)
    	at io.kotest.core.internal.TestCaseExecutor$executeInScope$2.invoke(TestCaseExecutor.kt)
    	at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:91)
    	at kotlinx.coroutines.CoroutineScopeKt.coroutineScope(CoroutineScope.kt:194)
    	at io.kotest.core.internal.TestCaseExecutor.executeInScope(TestCaseExecutor.kt:252)
    	at io.kotest.core.internal.TestCaseExecutor$executeAndWait$2$1$3$1$1.invokeSuspend(TestCaseExecutor.kt:227)
    	at io.kotest.core.internal.TestCaseExecutor$executeAndWait$2$1$3$1$1.invoke(TestCaseExecutor.kt)
    	at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturnIgnoreTimeout(Undispatched.kt:102)
    	at kotlinx.coroutines.TimeoutKt.setupTimeout(Timeout.kt:148)
    	at kotlinx.coroutines.TimeoutKt.withTimeout(Timeout.kt:44)
    	at io.kotest.core.internal.TestCaseExecutor$executeAndWait$2$1$3$1.invokeSuspend(TestCaseExecutor.kt:226)
    	at io.kotest.core.internal.TestCaseExecutor$executeAndWait$2$1$3$1.invoke(TestCaseExecutor.kt)
    	at io.kotest.engine.ExecutorExecutionContext$executeWithTimeoutInterruption$$inlined$suspendCoroutine$lambda$2.invokeSuspend(ExecutorExecutionContext.kt:56)
    	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
    	at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:274)
    	at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:86)
    	at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:61)
    	at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)
    	at io.kotest.engine.ExecutorExecutionContext.executeWithTimeoutInterruption(ExecutorExecutionContext.kt:55)
    	at io.kotest.core.internal.TestCaseExecutor$executeAndWait$2$1$3.invokeSuspend(TestCaseExecutor.kt:225)
    	at io.kotest.core.internal.TestCaseExecutor$executeAndWait$2$1$3.invoke(TestCaseExecutor.kt)
    	at io.kotest.mpp.ReplayKt.replay(replay.kt:18)
    	at io.kotest.core.internal.TestCaseExecutor$executeAndWait$2$1.invokeSuspend(TestCaseExecutor.kt:220)
    	at io.kotest.core.internal.TestCaseExecutor$executeAndWait$2$1.invoke(TestCaseExecutor.kt)
    	at io.kotest.engine.ExecutorExecutionContext$executeWithTimeoutInterruption$$inlined$suspendCoroutine$lambda$2.invokeSuspend(ExecutorExecutionContext.kt:56)
    	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
    	at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:274)
    	at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:86)
    	at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:61)
    	at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)
    	at io.kotest.engine.ExecutorExecutionContext.executeWithTimeoutInterruption(ExecutorExecutionContext.kt:55)
    	at io.kotest.core.internal.TestCaseExecutor$executeAndWait$2.invokeSuspend(TestCaseExecutor.kt:213)
    	at io.kotest.core.internal.TestCaseExecutor$executeAndWait$2.invoke(TestCaseExecutor.kt)
    	at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturnIgnoreTimeout(Undispatched.kt:102)
    	at kotlinx.coroutines.TimeoutKt.setupTimeout(Timeout.kt:148)
    	at kotlinx.coroutines.TimeoutKt.withTimeout(Timeout.kt:44)
    	at io.kotest.core.internal.TestCaseExecutor.executeAndWait(TestCaseExecutor.kt:212)
    	at io.kotest.core.internal.TestCaseExecutor.invokeTestCase(TestCaseExecutor.kt:180)
    	at io.kotest.core.internal.TestCaseExecutor.executeActiveTest(TestCaseExecutor.kt:149)
    	at io.kotest.core.internal.TestCaseExecutor$intercept$innerExecute$1$1.invokeSuspend(TestCaseExecutor.kt:87)
    	at io.kotest.core.internal.TestCaseExecutor$intercept$innerExecute$1$1.invoke(TestCaseExecutor.kt)
    	at io.kotest.core.internal.TestCaseExecutor.executeIfActive(TestCaseExecutor.kt:113)
    	at io.kotest.core.internal.TestCaseExecutor$intercept$innerExecute$1.invokeSuspend(TestCaseExecutor.kt:87)
    	at io.kotest.core.internal.TestCaseExecutor$intercept$innerExecute$1.invoke(TestCaseExecutor.kt)
    	at io.kotest.core.internal.TestCaseExecutor.intercept(TestCaseExecutor.kt:101)
    	at io.kotest.core.internal.TestCaseExecutor.execute(TestCaseExecutor.kt:67)
    	at io.kotest.engine.runners.InstancePerLeafSpecRunner$run$2.invokeSuspend(InstancePerLeafSpecRunner.kt:155)
    	at io.kotest.engine.runners.InstancePerLeafSpecRunner$run$2.invoke(InstancePerLeafSpecRunner.kt)
    	at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:91)
    	at kotlinx.coroutines.CoroutineScopeKt.coroutineScope(CoroutineScope.kt:194)
    	at io.kotest.engine.runners.InstancePerLeafSpecRunner.run(InstancePerLeafSpecRunner.kt:95)
    	at io.kotest.engine.runners.InstancePerLeafSpecRunner.interceptAndRun(InstancePerLeafSpecRunner.kt:90)
    	at io.kotest.engine.runners.InstancePerLeafSpecRunner.executeInCleanSpec(InstancePerLeafSpecRunner.kt:81)
    	at io.kotest.engine.runners.InstancePerLeafSpecRunner.execute(InstancePerLeafSpecRunner.kt:73)
    	at io.kotest.engine.spec.SpecExecutor$runTests$run$1.invokeSuspend(SpecExecutor.kt:130)
    	at io.kotest.engine.spec.SpecExecutor$runTests$run$1.invoke(SpecExecutor.kt)
    	at io.kotest.engine.spec.SpecExecutor.interceptSpec(SpecExecutor.kt:144)
    	at io.kotest.engine.spec.SpecExecutor.runTests(SpecExecutor.kt:135)
    	at io.kotest.engine.spec.SpecExecutor.runTestsIfAtLeastOneActive(SpecExecutor.kt:115)
    	at io.kotest.engine.spec.SpecExecutor.execute(SpecExecutor.kt:44)
    	at io.kotest.engine.KotestEngine$submitBatch$$inlined$forEach$lambda$1$1.invokeSuspend(KotestEngine.kt:139)
    	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
    	at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:274)
    	at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:86)
    	at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:61)
    	at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)
    	at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt)
    	at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source)
    	at io.kotest.engine.KotestEngine$submitBatch$$inlined$forEach$lambda$1.run(KotestEngine.kt:138)
    	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    	at java.lang.Thread.run(Thread.java:748)
    

    Of course, everything runs fine if I try and get a regular function.

    Am I missing something ?

    Thanks!

    opened by DeafLight 2
  • Suggestions on using fixtures for ktorm database objects

    Suggestions on using fixtures for ktorm database objects

    I realize that this is a bit of a long shot question, because it's not directly related to this code.

    I'm trying to figure out how I can use these fixtures to test ktorm (https://github.com/kotlin-orm/ktorm). The ktorm objects are fairly complex, consisting of a singleton object that connects to the database, fronted by an abstract interface for interacting with the singleton that instantiates a proxy whenever it itself is instantiated.

    Needless to say, the reflection based auto-fixture didn't work.

    I tried created a class that reifies the interface, but the companion object is making that hard.

    I was just wondering if anyone here has any experience or can point me in the direction of something I can read to figure this out. Or if someone here's experience says "this is probably not the right approach, don't bother".

    (I asked a similar question at ktorm and it was not a question that intrigued them, so that got closed and I understand if that happens here as well)

    Thank you!

    opened by sean-abbott 2
  • Generating customised objects

    Generating customised objects

    This is not an issue, it's more of a question.

    I'm trying to generate Strings with a specific length but I couldn't understand how's the easiest way to do it using this library. This is just one example and the necessity makes sense IMHO. It's a trivial use case but I don't see any similar examples in the docs nor in the tests. Can anyone show me how?

    opened by juliabirkett 1
  • How to return generic type for a fixture to return a fixture with configuration builder properties ?

    How to return generic type for a fixture to return a fixture with configuration builder properties ?

    Hello, I tried to return a kotlinFixture in a function with ConfigurationBuilder, but I discovered that I have no idea what type it will return.

    Is there any way to return the correct type for

    private fun myReusableFixture(): Sometype = kotlinFixture { property(X::y) { y } }

    It will complain when used as fun fixture() = myReusableFixture() and then fixture() in the every mockk.

    I want to return the same fake values in multiple tests, now it generates a new fake value that I have no reference to.

    opened by istvandesign 1
  • Error while created complex nested class

    Error while created complex nested class

    I run into an issue while using fixture for created a complicated and nested class. Unfortunately i cannot provide a lot of information apart the attached error log. Since I'm not really able to tear down the problem the title is an assumption and the main might be something else

    Until i got some information back what i can do, or maybe if a fix is necessary i have to avoid using fixture

    errorlog

    opened by jo8558 1
  • Injecting nulls for non-nullable property

    Injecting nulls for non-nullable property

    I have the following data class:

    @Serializable
    data class ErrorCodeDto(
        val ErrorCode: String,
        val ErrorDetail: String,
        val ErrorDescription: String
    )
    

    When I run the following unit test:

    fun `serializing and deserializing ErrorCodeDto should result in original instance`() {
        repeat(100000) {
            val original = fixture<ErrorCodeDto>()
            if(runCatching {
                verifySerialization(original)
            }.isFailure){
                println(original)
                throw IllegalArgumentException()
            }
        }
    }
    

    I get an exception because nulls are injected:

    ErrorCodeDto(ErrorCode=null, ErrorDetail=null, ErrorDescription=null)
    
    java.lang.IllegalArgumentException
    	at com.vayapay.cardregistration.model.CommonDtoTest.serializing and deserializing ErrorCodeDto should result in original instance(CommonDtoTest.kt:26)
    
    opened by msche 0
  • Classcast exception when creating fixture for array of integers

    Classcast exception when creating fixture for array of integers

    When I try to create a fixture for a array of integers I get the following exception:

    class [I cannot be cast to class [Ljava.lang.Integer; ([I and [Ljava.lang.Integer; are in module java.base of loader 'bootstrap')
    java.lang.ClassCastException: class [I cannot be cast to class [Ljava.lang.Integer; ([I and [Ljava.lang.Integer; are in module java.base of loader 'bootstrap')
    

    An array of String is working okay.

    Tested it with the following code:

        @Test
        fun test() {
            val array = fixture<Array<String>>()
            val arrayOfInt = fixture<Array<Int>>()
        }
    
    opened by msche 0
  • Unresolved reference: appmattus

    Unresolved reference: appmattus

    Hello,

    First, thank you for the great library.

    Cannot import import com.appmattus.kotlinfixture.kotlinFixture error Unresolved reference: appmattus\

    build.gradle(My Application) file: // Top-level build file where you can add configuration options common to all sub-projects/modules.

    plugins {
        id 'com.android.application' version '7.1.3' apply false
        id 'com.android.library' version '7.1.3' apply false
        id 'org.jetbrains.kotlin.android' version '1.6.21' apply false
    }
    
    task clean(type: Delete) {
        delete rootProject.buildDir
    }
    

    build.gradle(app module) file:

    plugins {
        id 'com.android.application'
        id 'org.jetbrains.kotlin.android'
    }
    
    android {
        compileSdk 32
    
        defaultConfig {
            applicationId "com.example.myapplication"
            minSdk 21
            targetSdk 32
            versionCode 1
            versionName "1.0"
    
            testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        }
    
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            }
        }
        compileOptions {
            sourceCompatibility JavaVersion.VERSION_1_8
            targetCompatibility JavaVersion.VERSION_1_8
        }
        kotlinOptions {
            jvmTarget = '1.8'
        }
        buildFeatures {
            viewBinding true
        }
    }
    
    dependencies {
    
        implementation 'androidx.core:core-ktx:1.7.0'
        implementation 'androidx.appcompat:appcompat:1.4.1'
        implementation 'com.google.android.material:material:1.5.0'
        implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
        implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.4.1'
        implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.1'
        implementation 'androidx.navigation:navigation-fragment-ktx:2.4.2'
        implementation 'androidx.navigation:navigation-ui-ktx:2.4.2'
        testImplementation 'junit:junit:4.13.2'
        androidTestImplementation 'androidx.test.ext:junit:1.1.3'
        androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
        testImplementation 'com.appmattus.fixture:fixture:1.5.31'
    }
    

    settings.gradle file:

    pluginManagement {
        repositories {
            gradlePluginPortal()
            google()
            mavenCentral()
        }
    }
    dependencyResolutionManagement {
        repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
        repositories {
            google()
            mavenCentral()
        }
    }
    rootProject.name = "My Application"
    include ':app'
    

    ExampleUnitTest file:

    package com.example.myapplication
    
    import org.junit.Test
    
    import org.junit.Assert.*
    import com.appmattus.kotlinfixture.kotlinFixture // Unresolved reference: appmattus
    
    /**
     * Example local unit test, which will execute on the development machine (host).
     *
     * See [testing documentation](http://d.android.com/tools/testing).
     */
    class ExampleUnitTest {
    
        private val fixture = kotlinFixture()
    
        @Test
        fun addition_isCorrect() {
            assertEquals(4, 2 + 2)
        }
    }
    

    Should I use kts to get it to work?

    opened by IDisouki2021 2
  • How can I ignore `lateinit var` field?

    How can I ignore `lateinit var` field?

    I have below classes. I want to create fixtures without lateinit var field , how can I achieve this? Thank you for your awesome project

    @Table("post")
    data class Post(
        @Id override val id: ID,
        val title: String,
        val content: String,
        @Relation(User::class) val userId: ID,
    ) : Node {
    
        @Autowired lateinit var userRepository: UserRepository
    
        fun author(env: DataFetchingEnvironment): CompletableFuture<User> {
            return userRepository.findById(userId, env)
        }
    }
    
    opened by wickedev 0
  • Override nullability strategy

    Override nullability strategy

    Hi there,

    According to your document about overriding nullability strategy, I have an issue with it in nullable properties.

    By default, when the library comes across a nullable type, such as String? it will randomly return a value or null. This can be overridden by setting a nullability strategy.

    I have a data class like:

    data class Order(val id: String? = null, /*with some other fields*/ )
    

    And I'm using KotlinFixture to write tests like that:

    val order = kotlinFixture {
          nullabilityStrategy(NeverNullStrategy)
          //Other configuration
        } <Order>()
    

    I expected the id attribute to always have a value. But this is not the case and sometimes it is null and the test is not deterministic and sometimes it is passed and sometimes it is not.

    My fixture version: 1.2.0

    opened by mahdibohloul 2
Releases(1.2.0)
Owner
Appmattus Limited
Appmattus Limited
Powerful, elegant and flexible test framework for Kotlin with additional assertions, property testing and data driven testing

Kotest is a flexible and comprehensive testing tool for Kotlin with multiplatform support. To learn more about Kotest, visit kotest.io or see our quic

Kotest 3.8k Jan 3, 2023
Selenium locators for Java/Kotlin that resemble the Testing Library (testing-library.com).

Selenium Testing Library Testing Library selectors available as Selenium locators for Kotlin/Java. Why? When I use Selenium, I don't want to depend on

Luís Soares 5 Dec 15, 2022
Kotlin wrapper for React Test Renderer, which can be used to unit test React components in a Kotlin/JS project.

Kotlin API for React Test Renderer Kotlin wrapper for React Test Renderer, which can be used to unit test React components in a Kotlin/JS project. How

Xavier Cho 7 Jun 8, 2022
PowerMock is a Java framework that allows you to unit test code normally regarded as untestable.

Writing unit tests can be hard and sometimes good design has to be sacrificed for the sole purpose of testability. Often testability corresponds to go

PowerMock 3.9k Jan 5, 2023
PowerMock is a Java framework that allows you to unit test code normally regarded as untestable.

Writing unit tests can be hard and sometimes good design has to be sacrificed for the sole purpose of testability. Often testability corresponds to go

PowerMock 3.9k Jan 2, 2023
3 types of Tests in Android (Unit - instrumentation - UI)

UnitTestingPractice 3 types of Tests in Android Unit instrumentation (Integration) UI Unit Testing benefits confirm code work like a charm simulate Ap

Ahmed Tawfiq 8 Mar 23, 2022
Most popular Mocking framework for unit tests written in Java

Most popular mocking framework for Java Current version is 3.x Still on Mockito 1.x? See what's new in Mockito 2! Mockito 3 does not introduce any bre

mockito 13.6k Jan 4, 2023
A simple project to help developers in writing their unit tests in Android Platform.

AndroidUnitTesting A simple project to help developers in writing their unit tests in Android Platform. This is not a multi-module project, but has th

Bruno Gabriel dos Santos 4 Nov 10, 2021
Snapshot Testing framework for Kotlin.

KotlinSnapshot Snapshot Testing framework for Kotlin. What is this? Snapshot testing is an assertion strategy based on the comparision of the instance

Pedro Gómez 157 Nov 13, 2022
Android UI Testing

User scenario testing for Android Robotium is an Android test automation framework that has full support for native and hybrid applications. Robotium

null 2.8k Dec 14, 2022
A set of AssertJ helpers geared toward testing Android.

AssertJ Android A set of AssertJ assertions geared toward testing Android. Deprecated The support libraries and play services are developing at a rate

Square 1.6k Jan 3, 2023
A programmer-oriented testing framework for Java.

JUnit 4 JUnit is a simple framework to write repeatable tests. It is an instance of the xUnit architecture for unit testing frameworks. For more infor

JUnit 8.4k Jan 9, 2023
Android UI Testing

User scenario testing for Android Robotium is an Android test automation framework that has full support for native and hybrid applications. Robotium

null 2.7k Apr 8, 2021
A programmer-oriented testing framework for Java.

JUnit 4 JUnit is a simple framework to write repeatable tests. It is an instance of the xUnit architecture for unit testing frameworks. For more infor

JUnit 8.4k Dec 28, 2022
A sample repo describing best practices for snapshot testing on Android

Road to effective snapshot testing A sample repo describing best practices for snapshot testing on Android. This includes for now: Parameterized Tests

Sergio Sastre Flórez 86 Jan 1, 2023
Turbine is a small testing library for kotlinx.coroutines Flow.

A small testing library for kotlinx.coroutines Flow

Cash App 1.8k Jan 5, 2023
Morsa: Jetpack Compose UI Testing Framework

Morsa: Jetpack Compose UI Testing Framework Test library to ease UI testing with Jetpack Compose Purpose This library aims to add some useful wrappers

HyperDevs 10 Dec 3, 2022
Lovely Systems Database Testing

Lovely DB Testing This repository provides opinionated testing helpers for database testing used at Lovely Systems. License This plugin is made availa

Lovely Systems GmbH 1 Feb 23, 2022
Project for testing intern candidate simple level

RickAndMorty-TestTask Тестовый проект 'Гайд по мультфильму Рик и Морти' для практикантов начального и продвинутого уровня. Структура проекта Структура

null 0 Nov 18, 2021