Memilih perpustakaan pernyataan untuk proyek Kotlin

Dalam salah satu proyek lama, pernyataan dari JUnit, kotlin.test dan AssertJ ditumpuk. Ini bukan satu-satunya masalah: umumnya ditulis sebagai surat dari Paman Fyodor, dan tidak ada waktu untuk berhenti dan membawanya ke satu bentuk. Dan sekarang saatnya telah tiba.



Artikel ini akan berisi penelitian mini tentang pernyataan mana yang lebih baik sesuai dengan kriteria subjektif. Pada awalnya saya ingin melakukan sesuatu yang sederhana: melempar serangkaian tes untuk memusatkan opsi dengan copy-paste dengan cepat. Lalu ia menyoroti data uji umum, mengotomatiskan beberapa cek, dan bagaimana semuanya berjalan ... Hasilnya adalah batu Rosetta kecil dan artikel ini mungkin berguna bagi Anda untuk memilih perpustakaan pernyataan yang sesuai dengan realitas Anda.



Saya akan membuat reservasi segera bahwa artikel tersebut tidak akan membandingkan kerangka pengujian, pendekatan pengujian, dan beberapa pendekatan rumit untuk validasi data. Kami akan berbicara tentang pernyataan sederhana.





Jika Anda terlalu malas untuk membaca alasan yang membosankan, sejarah cobaan saya dan detail lainnya, maka Anda dapat langsung menuju ke hasil perbandingan .



Sedikit latar belakang



Scala, β€” ScalaTest. , - , - .



Kotlin, - , , Kotest ( , ).





, , β€” . :



  1. Kotlin IntelliJ Idea. Scala- β€” . , ScalaTest , . IntelliJ <Click to see difference>, . , , IntelliJ Idea β€” Kotlin- - , ?

  2. . 1 != 2 , , "expected" "actual". " 100 , , ", , "… , , , ". , ? , β€” , , - .
  3. . assertEquals(expected, actual) β€” , . , β€” /, " , , " , contains, includes. β€” , .
  4. . - assertThat("Friendship").contains("end").
  5. . - JUnit4, , ExpectedException @Rule.
  6. () .
  7. .
  8. . β€” , . , : , , generic-, . -: assertThat(generic<Boolean>(input)).isEqualTo(true). <Boolean> . .
  9. , . . ? β€” , , . - , equals. - .


, , , , , . , β€” , . , -, QA-.





, 5 , , β€” .



:



  1. ScalaTest β€” .
  2. JUnit 5 β€” Java-.
  3. kotlin.test β€” multiplatform . β€” JUnit, .
  4. AssertJ β€” . FestAssert, - .
  5. Kotest β€” KotlinTest, kotlin.test. , ScalaTest. 1-22 β€” scala.
  6. Truth β€” . , AssertJ.
  7. Hamrest Β­β€” . valid4j.
  8. Strikt β€” AssertJ .
  9. Kluent β€” , JUnit ( β€” kotlin.test), Kotest. β€” , .
  10. Atrium β€” , AssertJ, . β€” ( maven/gradle).
  11. Expekt β€” Chai.js. : β€” 4 .
  12. AssertK β€” AssertJ, AssertK ( ).
  13. HamKrest β€” Hamrest, HamKrest ( Hamcrest ).


β€” , -.





80 , , , . - , .



, , 1 β€” 1 . , , - , " , " "".



, - , JUnit , , , , , . ScalaTest, : , , β€” . : ? , :). / , , .



: listOf(1,2,3)? β€” -, β€” . , , : , . , .



type erasure. Reified inline-, .



assertThrows<T>{...}


, reified :



assertThrows(expectedClass){...}


. , kotlin.test Asserter: , . , ?:)



GitHub. ScalaTest , .





: 0 β€” , 0.5 β€” , 1 β€” . β€” 9 .



-, , . . , . , - , " " , " " . .



Kotest Β± Β± + + + + + - 6.0
Kluent Β± Β± + + + + + - 6.0
AssertJ Β± + Β± + Β± + + Β± 6.0
Truth Β± + + + - + + - 5.5
Strikt Β± Β± Β± + + + + - 5.5
ScalaTest Β± Β± Β± + + + + - 5.5
HamKrest Β± - Β± + + Β± + - 5.5
AssertK Β± Β± Β± + Β± + + - 5.0
Atrium Β± Β± Β± + + Β± + - 5.0
Hamrest Β± Β± Β± + - Β± + - 5.0
JUnit + + - Β± + - Β± - 4.5
kotlin.test + Β± - - + - - - 3.5
Expekt Β± Β± - + - Β± + - 3.5


:



Kotest
  • , . .
  • , reified, : .
  • : . .
  • : <Click to see difference> .
  • : .
  • : , .


Kluent
  • "hello".shouldBeEqualTo("hello"), "hello" `should be equal to` "hello". DSL .
  • :

    invoking { block() } shouldThrow expectedClass.kotlin withMessage expectedMessage
  • , , . Expected Iterable to contain none of "[1, 3]" β€” , Iterable .
  • : <Click to see difference> .
  • : .


AssertJ
  • β€” … , containsExactly, β€” hasSameElementsAs, β€” .usingRecursiveComparison().isEqualTo.



  • : <Click to see difference> .



  • : - , . , , .



  • : .usingRecursiveComparison(), . : , , . , , ,



    assertThat(actual)
        .usingRecursiveComparison()
        .isNotEqualTo(unexpected)


    : .



  • : . , DSL.





Truth
  • , .
  • : , , assertThrows JUnit5. , JUnit , ?
  • : , , : containsAtLeastElementsIn. , assertThat(actual).isEqualTo(expected).
  • : <Click to see difference> .
  • : .
  • : , .
  • " ":

    expected: 1
    but was : 2
    at asserts.truth.TruthAsserts.simpleAssert(TruthAsserts.kt:10)
    at common.FailedAssertsTestBase.simple assert should have descriptive message(FailedAssertsTestBase.kt:20)
    at [[Reflective call: 4 frames collapsed (https://goo.gl/aH3UyP)]].(:0)
    at [[Testing framework: 27 frames collapsed (https://goo.gl/aH3UyP)]].(:0)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
    at [[Testing framework: 9 frames collapsed (https://goo.gl/aH3UyP)]].(:0)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
    at [[Testing framework: 9 frames collapsed (https://goo.gl/aH3UyP)]].(:0)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
    at [[Testing framework: 17 frames collapsed (https://goo.gl/aH3UyP)]].(:0)
    at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:99)
    ...


Strikt
  • , reified, : .



  • : expectThat(haystack).not().contains(needle), expectThat(collection).doesNotContain(items).



  • : contentEquals. : expectThat(actual).not().contentEquals(unexpected). , , Array<T> Strikt - . β€” containsExactly, β€” containsExactlyInAnyOrder.



  • : . , . :



    val actual: Array<String> = arrayOf("1")
    val expected: Array<String> = arrayOf("2")
    expectThat(actual).contentEquals(expected)


    , contentEquals. , contentEquals :



    infix fun <T> Assertion.Builder<Array<out T>>.contentEquals(other: Array<out T>)


    -



    val actual: Array<out String> = arrayOf("1")
    val expected: Array<String> = arrayOf("2")
    expectThat(actual).contentEquals(expected)


  • : <Click to see difference>.



  • : , .



  • : .





ScalaTest
  • : .
  • : , . .
  • : DSL contains, contains include, theSameElementsAs.
  • : , .
  • : , .


HamKrest
  • , , . β€” , .
  • , Hamcrest, - : -.
  • β€” :

    assertThat( {
        block()
    }, throws(has(RuntimeException::message, equalTo(expectedMessage))))
  • : . - 3,5 . : assertThat(collection, allOf(items.map { hasElement(it) })).
  • .
  • : .
  • : <Click to see difference>.
  • β€” - :

    expected: a value that not contains 1 or contains 3
    but contains 1 or contains 3


AssertK
  • β€” AssertJ. ( , -).



  • : AssertJ assertThat(collection).containsAll(items), AssertK , containsAll vararg. , containsAll(1,2,3), . , , β€” . β€” . , containsOnly containsExactly.



  • : <Click to see difference>.



  • : - , , .



  • : .usingRecursiveComparison() .



  • β€” ( ), :



    expected to contain exactly:<[3, 4, 5]> but was:<[1, 2, 3]>
    at index:0 unexpected:<1>
    at index:1 unexpected:<2>
    at index:1 expected:<4>
    at index:2 expected:<5>


    ?



  • : .





Atrium
  • : fluent infix. assertThat(x).isEqualTo(y) x shouldBe y, , expect(x).toBe(y) expect(x) toBe y. , , "". - o: expect(x) contains o atLeast 1 butAtMost 2 value "hello". , , . infix- ( - ), Atrium fluent-.
  • : : notToBe, containsNot. . , : contains vararg, containsElementsOf , . , contains(1,2,3), . expect(collection).containsNot.elementsOf(items).
  • , toList.
  • , reified, : .
  • : .
  • : <Click to see difference>.
  • : ( , ), :

    expected that subject: [4, 2, 1]        (java.util.Arrays.ArrayList <938196491>)
    ◆ does not contain:
    ⚬ an entry which is: 1        (kotlin.Int <211381230>)
      βœ˜β€„β€„number of such entries: 1
           is: 0        (kotlin.Int <1934798916>)
        has at least one element: true
           is: true
  • : .


Hamcrest
  • : (



    assertThat(actual, `is`(not(unexpected)))




    assertThat(actual, not(unexpected))


    containsString vs contains vs hasItem vs hasItems. , : hasItems vararg, Set<T> T . , hasItems(1,2,3), .



    assertThat(collection, allOf(items.map { hasItem(it) }))


    :



    assertThat(collection, not(anyOf(items.map { hasItem(it) })))


  • hasItems, Β± "", , .



  • : .



  • : <Click to see difference>.



  • : .



  • : .





JUnit
  • : - assertEquals(expected, actual), : assertArrayEquals, assertIterableEquals ..
  • : , JUnit - , .
  • : assertLinesMatch(listOf(".*$needle.*"), listOf(haystack)) , .
  • : assertLinesMatch, , assertIterableEquals.
  • : , assertIterableEquals Map Set , .
  • : .


kotlin.test
  • . JUnit, . , .
  • , JUnit, :
  • .
  • assertIterableEquals, .
  • : JUnit' assertEquals, kotlin.test , .
  • : .


Expekt
  • expect(x).equal(y) x.should.equal(y), . , .
  • : contains(item) should.have.elements(items) should.contain.elements(items). containsAll. , : should.have.elements vararg. , should.have.elements(1,2,3), . any: .should.not.contain.any.elements.
  • : , .
  • .
  • .
  • : .
  • : .
  • : <Click to see difference>.




Kotest, Kluent AssertJ. , Kotlin , AssertJ ( ). , .



β€” , , AssertJ. , , .




All Articles