Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

株式会社 ヤプリ 株式会社 ヤプリ • Name Ø 佐々⽊ ⼤輔 • Twitter Ø @DaisSasa • Company Ø 株式会社ヤプリ • Job Ø Androidエンジニア ⾃⼰紹介 Copyright © 2019 Yappli, Inc. All rights reserved. 1

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

株式会社 ヤプリ 株式会社 ヤプリ 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向けの開発も継続的に⾏われると予想 (あくまで個⼈の予想です)

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

株式会社 ヤプリ 株式会社 ヤプリ ⽂字列のアサーション 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)

Slide 7

Slide 7 text

株式会社 ヤプリ 株式会社 ヤプリ ⽂字列のアサーション 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) }

Slide 8

Slide 8 text

株式会社 ヤプリ 株式会社 ヤプリ 数値のアサーション 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))

Slide 9

Slide 9 text

株式会社 ヤプリ 株式会社 ヤプリ 数値のアサーション 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)) }

Slide 10

Slide 10 text

株式会社 ヤプリ 株式会社 ヤプリ コレクションのアサーション 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")

Slide 11

Slide 11 text

株式会社 ヤプリ 株式会社 ヤプリ コレクションのアサーション 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") }

Slide 12

Slide 12 text

株式会社 ヤプリ 株式会社 ヤプリ フィルタリング 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") )

Slide 13

Slide 13 text

株式会社 ヤプリ 株式会社 ヤプリ フィルタリング 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") )

Slide 14

Slide 14 text

株式会社 ヤプリ 株式会社 ヤプリ フィルタリング_truthの補⾜ Copyright © 2019 Yappli, Inc. All rights reserved. 13 Truth private val HAS_NAME = Correspondence.transforming({ 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 }

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

株式会社 ヤプリ 株式会社 ヤプリ 例外の検証 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() } }

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

株式会社 ヤプリ 株式会社 ヤプリ 発表は以上になります。 ご静聴ありがとうございました。 Copyright © 2019 Yappli, Inc. All rights reserved. 18