Skip to content

saksmt/ktest

Repository files navigation

kTest

CircleCI Maven metadata URI

kTest is integration / acceptance / system / any other non-unit test oriented modular test framework in Kotlin. Inspired by kotlintest, specs2 and martians.

Usage

object MyTestSpecification : BehaviorSpec({
    given("some service") {
        `when`("executing it's API") {
            then("it should work correctly") {
                // test body...
            }
        }
    }
})
fun makeMyHttp(): List<Account> {
    return rest["my-backend"] {
        using(url) {
            agreements / param("id") / accounts 
        } execute {
            GET(pathParam(123), header("Accept", "application/json"))
        }
    }
}
fun loadAccounts(resourcePath: String) =
    resourcePath.loadAsJson { list(map<String, Any>()) }.also {
        println(it.dump()) // pretty-printing pseudo-logging
    }
fun compareMyJsons(expected: JsonNode, actual: JsonNode) {
    with(JsonNodeMatchers) {
        assertThat(actual, isIdenticalTo(expected).bySubtree {
            // comparing only meaningful nodes
            "accounts[*]" {
                + "id"
                + "accountNumber"
                
                "owner" {
                    + "id"
                    + "name"
                }
            }
        })
    }
}

Powered by JSONPath

fun allIdsNearAccountNumbers(jp: DocumentContext) =
    jp select "id" where {
        "accountNumber".exists()
    } castTo { list<Long>() }
fun getAccounts(activeOn: Date) =
    "my-database".db {
        select<Account>("""
           | SELECT * FROM accounts 
           | WHERE 
           |   close_date is NULL 
           |   OR close_date < :activeOn
        """.trimMargin()) {
            parameter("activeOn", activeOn)
        }.asList()
    }
object MyTest : SimpleSpec({
    suite("my service suite") {
        restTest(name = { "${it.method} accounts" }) {
            url { agreements / accounts }
        
            GET(queryParam("name", "%"))
            POST(body("name", "%")) { it / search }
            
            expect { response: DocumentContext ->
                // do some check
            }
        }
    }
})

Reporting powered by excellent Allure

object MyTest : AllureSpec({
    feature("some feature", metaInfo = {
        blocker()
    }) {
        story("true story", metaInfo = {
            issue("PROJ-111")
        }) {
            case("my case", metaInfo = {
                description("my description")
            }) {
                // test body...
            }
        }
    }
})

Putting it all together

object AccountByCustomerRestApiSpec : AllureSpec({
    beforeAll {
        rest["backend"] {
            using(url) {
                `internal` / caches
            } execute {
                DELETE(queryParam("force", "true"))
            }
        }
    }

    epic("Search") {
        feature("Account by customer search") {
            story("Single criteria search") {
                val testTable = table(
                    header("criteriaName", "criteriaValue", "expectedJsonName"),
                    row("billing", ">100", "richAccounts.json"),
                    row("region", "Central", "centralRegionAccounts.json"),
                    row("validTill", ">${LocalDate.now().format(DateTimeFormatter.ISO_DATE)}", "activeAccounts.json")
                )
                // should be generated right before test
                val myGeneratedCustomer: Customer = testData["customer.json"]
                
                forAll(testTable) { criteriaName, criteriaValue, expectedJsonName ->
                    val criteria = mapOf<String, String>(
                        criteriaName, criteriaValue
                    )
                    
                    restTest(name = { "Search account by \"$criteriaName\": ${it.method}" }, metaData = {
                        category<Complex>()
                        flaky()
                    }) {
                        url { customers / param("customerId") / accounts }
                        
                        GET(queryParams(criteria), pathParam("customerId", myGeneratedCustomer.id))
                        POST(body(criteria), pathParam("customerId", myGeneratedCustomer.id))
                        
                        expect { response: DocumentContext ->
                            with(DocumentContextMatchers) {
                                assertThat(response, matches(expectedJsonName.loadAsJsonPath()).afterRemovalOfSubtree {
                                    "account[].metaData" {
                                        + "date"
                                        + "IP"
                                    }
                                })
                            }
                        }
                    }
                }
            }
        }
    }
})

For more see docs and samples

Download

You can use dependency management

Gradle

compile 'run.smt.ktest:ktest-api'
compile 'run.smt.ktest:ktest-config'
compile 'run.smt.ktest:ktest-util'
compile 'run.smt.ktest:ktest-runner-junit4'
compile 'run.smt.ktest:ktest-allure'
compile 'run.smt.ktest:ktest-jackson'
compile 'run.smt.ktest:ktest-json-matchers'
compile 'run.smt.ktest:ktest-jsonpath'
compile 'run.smt.ktest:ktest-db'
compile 'run.smt.ktest:ktest-rest'
compile 'run.smt.ktest:ktest-resttest'

Maven

<dependency>
    <groupId>run.smt.ktest</groupId>
    <artifactId>ktest-api</artifactId>
</dependency>

<dependency>
    <groupId>run.smt.ktest</groupId>
    <artifactId>ktest-config</artifactId>
</dependency>

<dependency>
    <groupId>run.smt.ktest</groupId>
    <artifactId>ktest-util</artifactId>
</dependency>

<dependency>
    <groupId>run.smt.ktest</groupId>
    <artifactId>ktest-runner-junit4</artifactId>
</dependency>

<dependency>
    <groupId>run.smt.ktest</groupId>
    <artifactId>ktest-allure</artifactId>
</dependency>

<dependency>
    <groupId>run.smt.ktest</groupId>
    <artifactId>ktest-jackson</artifactId>
</dependency>

<dependency>
    <groupId>run.smt.ktest</groupId>
    <artifactId>ktest-json-matchers</artifactId>
</dependency>

<dependency>
    <groupId>run.smt.ktest</groupId>
    <artifactId>ktest-jsonpath</artifactId>
</dependency>

<dependency>
    <groupId>run.smt.ktest</groupId>
    <artifactId>ktest-db</artifactId>
</dependency>

<dependency>
    <groupId>run.smt.ktest</groupId>
    <artifactId>ktest-rest</artifactId>
</dependency>

<dependency>
    <groupId>run.smt.ktest</groupId>
    <artifactId>ktest-resttest</artifactId>
</dependency>

License

All source code is licensed under MIT license

About

kTest - integration/acceptance/system/whatever test oriented modular test framework in Kotlin

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy