TruthとAssertJを比較してみた / Try to compared Truth and AsserJ

F0bc859dd1f5725158d04e63289c6634?s=47 Dais-33
August 27, 2019

TruthとAssertJを比較してみた / Try to compared Truth and AsserJ

今年の7月に正式リリースされたGoogle製のアサーションライブラリであるTruthですが、調べてみると今後のAndroidではTruthを正式に使っていく流れになりそうでした(あくまで個人の予想ですが)。
なので、既存のアサーションライブラリと比較して、置き換えをしても問題ないかを検証しました。

F0bc859dd1f5725158d04e63289c6634?s=128

Dais-33

August 27, 2019
Tweet

Transcript

  1. 株式会社 ヤプリ XXXX 株式会社 ヤプリ TruthとAssertJを⽐較してみた / Dais-33

  2. 株式会社 ヤプリ 株式会社 ヤプリ • Name Ø 佐々⽊ ⼤輔 •

    Twitter Ø @DaisSasa • Company Ø 株式会社ヤプリ • Job Ø Androidエンジニア ⾃⼰紹介 Copyright © 2019 Yappli, Inc. All rights reserved. 1
  3. 株式会社 ヤプリ 株式会社 ヤプリ • サービス名 Ø yappli • サービス内容

    Ø ⾮エンジニアがアプリ開発・運⽤できるようになるプラットフォーム Ø ⼀部機能を除きほぼネイティブで提供 • エンジニアの役割 Ø yappliで製作するアプリで使われる機能の原型の実装、改修を⾏います Androidに限らずアプリエンジニア募集中です 興味がある⽅は、良ければ懇親会にてお声掛け下さい https://yapp.li/ サービス紹介 Copyright © 2019 Yappli, Inc. All rights reserved. 2
  4. 株式会社 ヤプリ 株式会社 ヤプリ Truthを試してみた背景 Copyright © 2019 Yappli, Inc.

    All rights reserved. 3 • TruthはGoogleが提供しているアサーションライブラリ Ø 2019年7⽉8⽇にバージョン1.0が正式にリリースされたばかり • Google社内ではこのTruthを使って開発を⾏っている Ø Truthの公式ページにて記載されている • AndroidX Test LibraryにてTruth向けの拡張が⽤意されてある 今後TruthがAndroidの正式なアサーションライブラリになるかも︖ また、Android向けの開発も継続的に⾏われると予想 (あくまで個⼈の予想です)
  5. 株式会社 ヤプリ 株式会社 ヤプリ Truthを試してみた背景 Copyright © 2019 Yappli, Inc.

    All rights reserved. 4 とはいえ、まだまだ正式リリースされたばかり、 既存のライブラリから置き換えても⼤丈夫か︖ ↓ という訳で、アサーションライブラリでよく使われている AssertJと使える機能の⽐較を⾏いました
  6. 株式会社 ヤプリ 株式会社 ヤプリ ⽂字列のアサーション Copyright © 2019 Yappli, Inc.

    All rights reserved. 5 AssertJ Assertions.assertThat("TOKYO") .`as`("TEXT CHECK TOKYO") .isEqualTo("TOKYO") .isEqualToIgnoringCase("tokyo") .isNotEqualTo("KYOTO") .isNotBlank() .startsWith("TO") .endsWith("YO") .contains("OKY") .matches("[A-Z]{5}") .isInstanceOf(String::class.java)
  7. 株式会社 ヤプリ 株式会社 ヤプリ ⽂字列のアサーション Copyright © 2019 Yappli, Inc.

    All rights reserved. 6 Truth Truth.assertWithMessage("TEXT CHECK TOKYO") .that("TOKYO").apply { isEqualTo("TOKYO") // isEqualToIgnoringCase("tokyo") isNotEqualTo("KYOTO") isNotEmpty() startsWith("TO") endsWith("YO") contains("OKY") matches("[A-Z]{5}") isInstanceOf(String::class.java) }
  8. 株式会社 ヤプリ 株式会社 ヤプリ 数値のアサーション Copyright © 2019 Yappli, Inc.

    All rights reserved. 7 AssertJ Assertions.assertThat(3.14159) .isNotZero() .isNotNegative() .isGreaterThan(3.0) .isLessThanOrEqualTo(4.0) .isBetween(3.0, 3.2) .isCloseTo(Math.PI, within(0.001))
  9. 株式会社 ヤプリ 株式会社 ヤプリ 数値のアサーション Copyright © 2019 Yappli, Inc.

    All rights reserved. 8 Truth Truth.assertThat(3.14159).apply { isNonZero() isAtLeast(0.0) isGreaterThan(3.0) isAtMost(4.0) // isBetween(3.0, 3.2) // isCloseTo(Math.PI, within(0.001)) }
  10. 株式会社 ヤプリ 株式会社 ヤプリ コレクションのアサーション Copyright © 2019 Yappli, Inc.

    All rights reserved. 9 AssertJ val target = listOf("Giants", "Dodgers", "Athletics") Assertions.assertThat(target) .hasSize(3) .contains("Dodgers") .containsOnly("Athletics", "Dodgers", "Giants") .containsExactly("Giants", "Dodgers", "Athletics") .doesNotContain("Padres")
  11. 株式会社 ヤプリ 株式会社 ヤプリ コレクションのアサーション Copyright © 2019 Yappli, Inc.

    All rights reserved. 10 Truth val target = listOf("Giants", "Dodgers", "Athletics") Truth.assertThat(target).apply { hasSize(3) contains("Dodgers") containsAtLeast("Athletics", "Dodgers", "Giants") containsExactly("Giants", "Dodgers", "Athletics").inOrder() doesNotContain("Padres") }
  12. 株式会社 ヤプリ 株式会社 ヤプリ フィルタリング Copyright © 2019 Yappli, Inc.

    All rights reserved. 11 AssertJ val target = listOf( BallTeam("Giants", "San Francisco", "AT&T Park"), BallTeam("Dodgers", "Los Angels", "Dodger Stadium"), BallTeam("Angels", "Los Angels", "Angel Stadium"), BallTeam("Athletics", "Oakland", "Oakland Coliseum"), BallTeam("Padres", "San Diego", "Petco Park") ) Assertions.assertThat(target) .filteredOn { team -> team.city.startsWith("San") } .filteredOn { team -> team.city.endsWith("Francisco") } .extracting("name", String::class.java) .containsExactly("Giants") Assertions.assertThat(target) .filteredOn { team -> team.city == "Los Angels" } .extracting("name", "stadium") .containsExactly( tuple("Dodgers", "Dodger Stadium"), tuple("Angels", "Angel Stadium") )
  13. 株式会社 ヤプリ 株式会社 ヤプリ フィルタリング Copyright © 2019 Yappli, Inc.

    All rights reserved. 12 Truth val target = listOf( BallTeam("Giants", "San Francisco", "AT&T Park"), BallTeam("Dodgers", "Los Angels", "Dodger Stadium"), BallTeam("Angels", "Los Angels", "Angel Stadium"), BallTeam("Athletics", "Oakland", "Oakland Coliseum"), BallTeam("Padres", "San Diego", "Petco Park") ) // Truthにfilter機能がない?ので自分でfilterする // 一部の要素のみをみて比較する場合、Correspondenceを定義して行う // 比較する要素ごとにCorrespondenceの定義が必要になる val filterTarget = target.filter { team -> team.city.startsWith("San") } .filter { team -> team.city.endsWith("Francisco") } Truth.assertThat(filterTarget) .comparingElementsUsing(HAS_NAME) .containsExactly("Giants") val filterTarget2 = target.filter { team -> team.city == "Los Angels" } Truth.assertThat(filterTarget2) .comparingElementsUsing(BALLTEAM_NAME_PARSES_TO_TUPLE) .containsExactly( tuple("Dodgers", "Dodger Stadium"), tuple("Angels", "Angel Stadium") )
  14. 株式会社 ヤプリ 株式会社 ヤプリ フィルタリング_truthの補⾜ Copyright © 2019 Yappli, Inc.

    All rights reserved. 13 Truth private val HAS_NAME = Correspondence.transforming<BallTeam, String>({ it?.name }, "Has an Name of") private val BALLTEAM_NAME_PARSES_TO_TUPLE = Correspondence.from(::ballteamParsesToTuple, "parses to") // Ballteamのnameとstadiumの⽐較 private fun ballteamParsesToTuple(actual: BallTeam?, expected: Tuple?): Boolean { if (actual == null) { return expected == null } return expected?.toList()?.let { list -> if (list.isEmpty() || list.size != 2) return false actual.name == list[0] && actual.stadium == list[1] } ?: false }
  15. 株式会社 ヤプリ 株式会社 ヤプリ 例外の検証 Copyright © 2019 Yappli, Inc.

    All rights reserved. 14 AssertJ Assertions.assertThatExceptionOfType(RuntimeException::class.java) .isThrownBy { functionMayThrow() } .withMessage("Aborted!") .withNoCause()
  16. 株式会社 ヤプリ 株式会社 ヤプリ 例外の検証 Copyright © 2019 Yappli, Inc.

    All rights reserved. 15 Truth try { functionMayThrow() } catch (e: Throwable) { Truth.assertThat(e).apply { isInstanceOf(RuntimeException::class.java) hasMessageThat().contains("Aborted!") // withNoCause() } }
  17. 株式会社 ヤプリ 株式会社 ヤプリ 実際に動くテストコード Copyright © 2019 Yappli, Inc.

    All rights reserved. 16 スライドに記載したテストコードは発表⽤にガリガリ削ってます 実際に動くものはGithubにて公開してます https://github.com/dais-33/android-truth
  18. 株式会社 ヤプリ 株式会社 ヤプリ ⽐較してみた感想・結論 Copyright © 2019 Yappli, Inc.

    All rights reserved. 17 • 流⽯にAssertJができることを全て網羅している訳ではない • ただし、必要最低限は網羅していそう Ø それはテストする必要があるのか︖という機能を削った印象 ↓ すでにAssertJ等を使ってバリバリテストを書いてるアプリでは Truthに切り替える理由は薄い これからアサーションライブラリを導⼊しようと考えている場合は Truthも選択として⼗分有り
  19. 株式会社 ヤプリ 株式会社 ヤプリ 発表は以上になります。 ご静聴ありがとうございました。 Copyright © 2019 Yappli,

    Inc. All rights reserved. 18