AuswĂ€hlen einer Assertionsbibliothek fĂŒr ein Kotlin-Projekt

In einem der alten Projekte wurden Behauptungen von JUnit, kotlin.test und AssertJ angehÀuft. Dies war nicht sein einziges Problem: Es wurde im Allgemeinen als Brief von Onkel Fjodor geschrieben, und es blieb keine Zeit, anzuhalten und es in eine einzige Form zu bringen. Und jetzt ist es soweit.



Der Artikel enthĂ€lt eine Mini-Recherche darĂŒber, welche Behauptungen nach subjektiven Kriterien besser sind. Zuerst wollte ich etwas Einfaches tun: eine Reihe von Tests durchfĂŒhren, um Optionen schnell mit Copy-Paste zu vernieten. Dann hob er die allgemeinen Testdaten hervor, automatisierte einige der ÜberprĂŒfungen und wie alles lief ... Das Ergebnis war ein kleiner Rosetta-Stein, und dieser Artikel kann fĂŒr Sie nĂŒtzlich sein, um eine Bibliothek von Asserts auszuwĂ€hlen, die Ihren RealitĂ€ten entspricht.



Ich werde sofort reservieren, dass der Artikel keine Test-Frameworks, Test-AnsĂ€tze und einige knifflige AnsĂ€tze zur Datenvalidierung vergleicht. Wir werden ĂŒber einfache Behauptungen sprechen.





Wenn Sie zu faul sind, um langweilige Argumente, die Geschichte meiner PrĂŒfungen und andere Details zu lesen, können Sie direkt zu den Vergleichsergebnissen gehen .



Ein bisschen Hintergrund



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