Slide 1

Slide 1 text

::class.fixture() QBUUFSO Š ֦ுؔ਺Λੜ͔ͨ͠ɺ5FTU'JYUVSF؅ཧͷ঺հ !,PUMJO'FTU

Slide 2

Slide 2 text

セッション概要 ¡ l5FTU'JYUVSFzͱ͸ɺ 6OJU5FTU౳ʢҎԼ୯ʹ 5FTUʣͰଟ༻͞ΕΔલఏ৚݅΍Πϯελϯεͷू߹ମ Λ۩ମతͳ 5FTU$BTFͱ͸ผ͚ͯ؅ཧͨ͠΋ͷͰ͢ ¡ 5FTUΛ໌ྎͰಡΈ΍͘͢͢Δʢͦͯ͠ॻ͖΍͘͢͢ΔʣޮՌ͕͋Γ·͢ɻ ¡ 'JYUVSF͸࠶ར༻͢Δࣄ͕ՄೳͰɺఆ਺ͱͯ͠ఆٛͯ͠ࢀর͢Δ౳ͷํ๏͕͋Γ·͢ɻ ఆٛՕॴ΍ํ๏ʹΑͬͯݟ͚ͭΔͷ͕೉͔ͬͨ͠Γɺ࠶ར༻Օॴ͕ݶΒΕΔͱ͍ͬͨ໰୊͕͋Γ·ͨ͠ɻ ¡ ͦ͜ͰɺΫϥεʢ,$MBTTʣʹର͢Δ֦ுؔ਺ͱͯ͠ 'JYUVSFΛఆٛ͢ΔࣄͰɺ1SPEVDUJPOίʔυͷ ԚછΛආ͚ͨ··Ͱɺ*%&ʹΑΔิ׬ͷԸܙΛड͚ΒΕΔ؅ཧ͕Ͱ͖ΔΑ͏ʹͳΓ·ͨ͠ɻ ¡ ͜Εʹ͍ͭͯɺهड़ํ๏Λݩʹ DMBTTGJYUVSF QBUUFSOͱݺΜͰ͍·͢ɻ ¡ ຊηογϣϯͰ͸ɺ'JYUVSF ͷ֓ཁ͔Β࢝·ͬͯɺDMBTTGJYUVSF QBUUFSOͷ۩ମతͳهड़ํ๏΍ɺ *%&Ͱิ׬͞ΕΔ৔߹ͷମݧΛɺσϞΛަ͑ͳ͕Β঺հͤͯ͞௖͜͏ͱࢥ͍ͬͯ·͢ɻ

Slide 3

Slide 3 text

͜ͷηογϣϯͷ (PBMɾ ಛʹ͓ಧ͚͍ͨ͠ํ ͜͜Ͱ͸࿩͞ͳ͍͜ͱɾ஫ҙ఺ ¡ Goal ¡ Fixture 管理重要かも、と思って頂く ¡ Fixture を管理するのに良い方法 ¡ Gradle module 内 → ::class:fixture pattern() ¡ Gradle Multimodule → java-test-fixture plugin ¡ 特にお届けしたい方 ¡ 『Test を書く時間が足りない。。。』 『Test がなんかごちゃごちゃしてる?』 『読み返したら読みにくい・更新しにくい』 ¡ という現場あるあるを持ってらっしゃる方。 改善策の元ネタの1つに使って頂ければ幸いです ¡ ここでは話さない・話せない事 ¡ 良い Test とは ¡ 良い(Testable な)設計 ¡ 注意点 ¡ 『特定のパターンを紹介する』という形の発表には なってしまいますが、同時に現場での Fixture の扱い、 というものをまとめる事に注力しました。 ⚠ 拡張関数のご利用は計画的に! ⚠

Slide 4

Slide 4 text

本セッションの流れ ¡ ࣗݾ঺հɾഎܠͷ૝ఆ ¡ 5FTUͱ l'JYUVSFz ¡ 'JYUVSF؅ཧͷॏཁੑ ¡ 'JYUVSF؅ཧ͋Ε͜Ε ¡ $"1*5"-@$"4&GJYUVSF ¡ 'JYUVSFJOEFGBVMUWBMVF ¡ 'JYUVSFJODPNQPOFOU ¡ 3BOEPN'JYUVSFFUDʜ ¡ DMBTTGJYUVSF QBUUFSOͷ঺հ ¡ (SBEMF`TKBWBUFTUGJYUVSFT QMVHJO ¡ $MPTJOH

Slide 5

Slide 5 text

自己紹介:松田一樹 (@kazuki_matsuda) ¡ Senior Software Engineer (Server Side) in LINE Digital Frontier 株式会社 ¡ = 『LINE マンガ』. ¡ 興味の1つ = 分断を避けた Scalability で、開発効率を上げること ¡ git-lfs scalability. ¡ e.g.) Implement “git-lfs dedup”. https://swet.dena.com/entry/2021/07/12/120000#:~:text=git%20lfs%20dedup ¡ 課題・動機: ¡ 当時開発していたプロジェクトのリポジトリサイズが ~ 100GB。(Asset 含む) / 複数 Checkout をしたい。hardlink / symlink では対応出来ない。 ¡ spring-gradle-plugins: Multimodule gradle project performance improvement. ¡ e.g.) Fix: “High CPU usage when identifying local projects in large multi-project builds” https://github.com/spring-gradle-plugins/dependency-management-plugin/pull/289 ¡ Motivation: Large multimodule Gradle project (~ 数百) needs long time to IntelliJ reload. ¡ Feature branch model to trunk based development transformation. ¡ https://linedevday.linecorp.com/2020/ja/sessions/6992/

Slide 6

Slide 6 text

Kotlin & Testing in my work (LINE Manga) ¡ -*/&ϚϯΨ ೥໨ͷεϚʔτϑΥϯ޲͚ΞϓϦέʔγϣϯʢ8FCʣ ¡ 1FSM4FSWFS4JEF,PUMJO΁ͷ .JHSBUJPOத ೥໨ ¡ ,PUMJOͷ 4FSWFS4JEFͰͷ࢖ΘΕํ ¡ 4QSJOH#PPU.7$ 3FTU+40/"1* ¡ .POPSFQPTJUPSZ (SBEMFNVMUJNPEVMFQSPKFDU "1* #BUDIFUDʜͷ .PEVMBSNPOPMJUI˞ ¡ 5FTUFECZ+6OJU,PUFTU GVMM$*GPSFWFSZ13 ¡ ˞͍͔ͭ͘ͷίϯϙʔωϯτ͸ଞνʔϜʹΑΓطʹ .JDSP 4FSWJDFT ͱͯ͠ఏڙ͞Ε͍ͯΔ ¡ -*/&"VUI #MMMJOH *NBHF#MPC #JH%BUB "QQ1VTI ¡ ˞ .PEVMBS NPOPMJUI .POPSFQP GVMM$*ͳͷͰ෦඼ͷ࠶ར༻ɺ͕໰୊ແ͘͠΍͍͢ɻ

Slide 7

Slide 7 text

本セッションの流れ ¡ ࣗݾ঺հɾഎܠͷ૝ఆ ¡ 5FTUͱ l'JYUVSFz ͷؔ܎ ¡ 'JYUVSF؅ཧͷॏཁੑ ¡ 'JYUVSF؅ཧ͋Ε͜Ε ¡ $"1*5"-@$"4&GJYUVSF ¡ 'JYUVSFJOEFGBVMUWBMVF ¡ 'JYUVSFJODPNQPOFOU ¡ 3BOEPN'JYUVSFFUDʜ ¡ DMBTTGJYUVSF QBUUFSOͷ঺հ ¡ (SBEMF`TKBWBUFTUGJYUVSFT QMVHJO ¡ $MPTJOH

Slide 8

Slide 8 text

4PGUXBSF5FTUJOHʹ͓͚Δ l'JYUVSFzͱ͸ ¡ 'JYUVSF KJH KB࣏۩ʢ͙͡ʣ ¡ ݩͷҙຯʣ࡞ۀΛ͢Δࡍʹɺ ର৅ҐஔͷݻఆͳͲͰ࡞ۀΛิॿ͢Δ ¡ ޻࡞ػցͦͷ΋ͷͰ͸ͳ͍͕ɺ޻࡞͢ΔࣄΛॿ͚ͯ͘ΕΔ ¡ ޻࡞Λ҆શʹɾਖ਼֬ʹɾૣ͘Ͱ͖Δ ¡ 4PGUXBSF 5FTUJOHͷจ຺ʢࠓ೔ͷ࿩ʣͰ͸ ¡ 5FTUͷͨΊͷɾ5FTU ΛηοτΞοϓ͢Δ ςετσʔλ΍ϝιου ¡ .PDL)FMQFS౳ͱݺ͹Ε͍ͯͨΓ΋͢Δʁ ¡ 4FSWJDFDMBTT౳ͷ NPLDJOHͱ΍΍͍͜͠Ͱ͢Ͷɻ -VJHJ;BOBTJ ౤ߘऀࣗ਎ʹΑΔஶ࡞෺ $$#:4"DB IUUQTDPNNPOTXJLJNFEJBPSHXJOEFYQIQ DVSJEʹΑΔ

Slide 9

Slide 9 text

Fixture の説明 in Wikipedia, JUnit4’s Cookbook. ςετΛ࣮ߦɺ੒ޭͤ͞ΔͨΊʹඞཁͳঢ়ଶ΍લఏ৚݅ ͷू߹ΛɺϑΟΫενϟͱݺͿɻ 'SPN8JLJQFEJBʰY6OJUʱ IUUQTKBXJLJQFEJBPSHXJLJ96OJU 'SPNIUUQTKVOJUPSHKVOJUDPPLCPPLIUNM 5FTUTOFFEUPSVOBHBJOTUUIFCBDLHSPVOEPGBLOPXOTFUPGPCKFDUT5IJTTFU PGPCKFDUTJTDBMMFEBUFTUGJYUVSF8IFOZPVBSFXSJUJOHUFTUTZPVXJMMPGUFOGJOE UIBUZPVTQFOENPSFUJNFXSJUJOHUIFDPEFUPTFUVQUIFGJYUVSFUIBOZPVEPJO BDUVBMMZUFTUJOHWBMVFT 5PTPNFFYUFOU ZPVDBONBLFXSJUJOHUIFGJYUVSFDPEFFBTJFSCZQBZJOHDBSFGVM BUUFOUJPOUPUIFDPOTUSVDUPSTZPVXSJUF)PXFWFS BNVDICJHHFSTBWJOHTDPNFT GSPNTIBSJOHGJYUVSFDPEF0GUFO ZPVXJMMCFBCMFUPVTFUIFTBNFGJYUVSFGPS TFWFSBMEJGGFSFOUUFTUT&BDIDBTFXJMMTFOETMJHIUMZEJGGFSFOUNFTTBHFTPS QBSBNFUFSTUPUIFGJYUVSFBOEXJMMDIFDLGPSEJGGFSFOUSFTVMUT 'SPNIUUQTKVOJUPSHKVOJUDPPLCPPLIUNM ʰςετΛॻ͍͍ͯΔͱɺ࣮ࡍʹ஋Λݕূ͢ΔΑΓ΋ 'JYUVSF ΛηοτΞοϓ͢ΔͨΊ ͷίʔυΛॻ͘΄͏ʹ͕͔͔࣌ؒͬͯ͠·͏͜ͱ͕Α͋͘Γ·͢ɻʱ ʰ$POTUSVDUPS ͷॻ͖ํΛ޻෉͢Ε͹ 'JYUVSF ͷηοτΞοϓ࣌ؒ͸࡟ݮͰ͖Δ͔΋͠ Εͳ͍ɻͰ΋΋ͬͱՁ஋͕͋Δͷ͸ 'JYUVSF ؔ܎ͷίʔυΛڞ༗͢Δ͜ͱͩʱ

Slide 10

Slide 10 text

Started HERE: First Example Test Fixture

Slide 11

Slide 11 text

ຊ೔ͷൃදͷ͖͔͚ͬ Կނ 'JYUVSF ؅ཧʹ 'PDVT ͢Δͷ͔ʁ ¡ ࣗ෼ͷதͰͷ՝୊ҙࣝ ¡ पΓͷϝιουʹ͋ΘͤͨΒςετίετ͕͕͋ͬͯ͠·͏ɺͱ͍͏ܦݧɻ ¡ 3FRVFTU$POUFYU ͷΑ͏ͳܗͰܕʹ͸ΊΔͷ͸ྑ͍͚Ͳɺςετ͕ॻ͖ʹ͍͘ࣄ͕͋Δɻ ¡ ͦͷΠϯελϯεͲ͏࡞Δͷʁ ¡ ෆཁͳϑΟʔϧυʹ͸ԿΛೖΕΔ΂͖ʁ ¡ ྫʣΠϯελϯε͕࡞Γʹ͍͘ͱɺ࠷খݶͷҾ਺ͷ .FUIPE Λఆٛͨ͘͠ͳͬͯ͠·͏ ¡ GVOCVJME)FMMP.FTTBHF DUY3FRVFTU$POUFYU มߋʹରͯ͠ด͍ͯ͡Δ ¡ 'VOCVJME)FMMP.FTTBHF OBNF4USJOH OPX*OTUBOU ݴޠͰϝοηʔδΛม͍͑ͨͱࢥͬͨΒʁ ¡ ςετΛॻ͘ͷ͕΋ͬͱ؆୯ʹͳΒͳ͍͔ʁ ¡ ςετ͕ͳΜͱͳ͘ಡΈʹ͍͘ɾͪ͝Ό͍͍ͭͯΔ ¡ ΋ͪΖΜςετର৅͕ͦ΋ͦ΋ෳࡶɾద੾ʹઃܭ͞Ε͍ͯͳ͍Մೳੑ΋͋Δɻ ¡ ςετΛಡΉͷ͕΋ͬͱ؆୯ʹͳΒͳ͍͔ʁ

Slide 12

Slide 12 text

適切な Fixture 管理がもたらすメリット ¡ 5FTU3FBEBCJMJUZ ¡ ద੾ʹ؅ཧ͞Εͨ 'JYUVSF͸ʰ5FTUͷՄಡੑʱΛ޲্ͤ͞·͢ ¡ 5FTU8SJUBCJMJUZ ¡ ؆୯ʹॻ͚Ε͹ɺ΋ͬͱଟ͘ͷ 5FTUΛɺద੾ͳλΠϛϯάͰɺ଎͘ॻ͚ΔΑ͏ʹͳΓ·͢ɻ ¡ 4DBMF.FSJU$PEFVOJGJDBUJPO ¡ ద੾ʹ 'JYUVSF Λ؅ཧ͢Ε͹ʢཁίετʣɺ ଞͷ։ൃऀʹ΋࢖ΘΕΔࣄͰ։ൃޮ཰্͕͕Γ·͢ʢʴʴʣ ¡ 4IBSFE -JCSBSZ6UJMJUZ ࣮૷ͱڞʹɺ'JYUVSF΋ఏڙ͢ΔࣄͰɺ 5FTUઃܭ͔Βࣗવʹ 1SPEVDUJPO $PEF ͷઃܭͷڞ௨Խ͕ੜ·ΕΔ͜ͱ͕ظ଴Ͱ͖Δ

Slide 13

Slide 13 text

5FTU 'JYUVSF ར༻ͷࣦഊྫʢ%BSL 4JEFʣ ¡ ࣗ෼͸ʰ؆୯ʹॻ͚Δʱ͕ ଞͷਓ͕ʰԿΛςετ͍ͯ͠Δͷ͔ʱ͕ղΓʹ͍͘ίʔυ ¡ ςετίʔυ͸ɺ׬શʹ%3:ʢ܁Γฦ͠ΛࣙΊΔʣʹͳΔͷͰ͸ͳ͘ɺ%".1 Λ໨ࢦ͢΂͖Ͱ͋Δࣄ ͕ଟ͍ɻͭ·Γɺʮઆ໌త͔ͭҙຯ͕෼͔Γ΍͍͢ݴ͍ճ͠ʢ%FTDSJQUJWF "OE .FBOJOHGVM 1ISBTF ʯΛਪ঑͢Δͱ͍͏͜ͱͩɻগʑͷॏෳ͸ɺͦΕ͕ςετΛ୯७͔ͭ໌֬ͳ΋ͷʹ͢ΔݶΓɺ ໰୊ແ͍ɻ ¡ 'SPNʰ(PPHMF ͷιϑτ΢ΣΞΤϯδχΞϦϯάʱ 4FD QQॳ൛ FOIUUQTBCTFJMJPSFTPVSDFTTXF CPPLIUNMDIIUNMUFTUT@BOE@DPEF@TIBSJOH@EBNQDPNNB@OPU@ES ¡ ςετίʔυͰ͸ɺ%3:ʹ͢Δ͜ͱʹ༂ىʹͳΒͳ͍Ͱ͍ͩ͘͞ɻ ಉ͡ίʔυΛ܁Γฦͯ͠΋͔·͍ ·ͤΜɻ ૉ௚ʹɺ۪௚ʹɺ୯७ʹɻ·ͯ͠Կ͔Λந৅Խ͢ΔϝϦοτ͸΄΅ͳ͍Ͱ͠ΐ͏ɻ ¡ 'SPNIUUQTHJUIVCDPNVCJFPTTLPUMJODPEJOHTUZMF

Slide 14

Slide 14 text

DRY を目指してわかりにくくなってしまうテスト ¡ その値はどこから来た?

Slide 15

Slide 15 text

Fixture の利用時したときは、特に前提条件を明確に ¡ Fixture を使う時も事前条件 (Given) を常にチェックするとよい。 ¡ 常に 『即値で書くのとどちらがで見やすい?』 と悩むのは良いこと。

Slide 16

Slide 16 text

好みっぽい話になってしまう(?) ¡ 好みっぽい話になってしまう ¡ そもそも check する必要がない Fixture の生成方法、 というのは大きなテーマ Fixture をどう定義するかを考えると どうチェックするのか、 の話は省略できる (同じタイミングでできる)

Slide 17

Slide 17 text

本セッションの流れ ¡ ࣗݾ঺հɾഎܠͷ૝ఆ ¡ 5FTUͱ l'JYUVSFz ͷؔ܎ ¡ 'JYUVSF؅ཧͷॏཁੑ ¡ 'JYUVSF؅ཧ͋Ε͜Ε ¡ $"1*5"-@$"4&pYUVSF ¡ 'JYUVSFJOEFGBVMUWBMVF ¡ 'JYUVSFJODPNQPOFOU ¡ 3BOEPN'JYUVSFFUDʜ ¡ DMBTTpYUVSF QBUUFSOͷ঺հ ¡ (SBEMF`TKBWBUFTUpYUVSFT QMVHJO ¡ $MPTJOH

Slide 18

Slide 18 text

Test Fixture あれこれ ¡ 今まで試した・見てきた方法 ¡ (private) fun / val fixture ¡ STATIC_FINAL_FIXTURE ¡ fun mockTargetClass() fixture ¡ Fixture as default value? ¡ Fixture in component. ¡ Random

Slide 19

Slide 19 text

(private) fun / val fixture ¡ ઌ΄Ͳͷྫɾશͯͷجຊ ¡ ςετΫϥεʹ෇ਵ͢Δ GJYUVSFΛɺ ಉҰ $MBTT಺ͷෳ਺ςετͰ࢖͍ճ͢ɻ ¡ 1SPT ¡ ڽॖ౓͸ߴ͍ ¡ ͕ɺ݁ہεΫϩʔϧൣғ֎ͩͱ໌ࣔతͱ͸ݴ͍͕͍ͨ ¡ 'JYUVSF มߋͷӨڹൣғΛݶఆͰ͖Δ ¡ $POT ¡ ΫϥεΛލ͍Ͱ࠶ར༻͞Εͳ͍ɻ ¡ ςετʹΑͬͯಉ໊͡લͷ GJYUVSFͷఆ͕ٛ ҟͳΔࣄ΋

Slide 20

Slide 20 text

STATIC_FINAL fixture ¡ 他のクラスでも再利用できるように val (static final) や fun に切り出して共有 ¡ Pros ¡ Class を越えた共有ができるようになる。 ¡ Mutable な値を val 定義して問題になる事も。。。 ¡ なのでたまに fun で ¡ Cons ¡ 巨大クラスになりがち(許容できることも) ¡ 見つかりにくいので再利用されにくい ¡ 特にクラス分割してしまったりすると

Slide 21

Slide 21 text

Fixture in default value? ¡ MoSvaSon: ¡ もう Produc:on code に default value すれば楽なのでは無いか? ¡ Produc'on code も変更したいところだけ変更すれば変更行数が少ない? ¡ フィールドを追加してもテストを更新しなくてよい? ¡ Pros ¡ 別のコンパイル単位での利用も簡単 ¡ Cons ¡ 影響範囲を限定できるのではなく、実際は隠してしまう。 ¡ などなど

Slide 22

Slide 22 text

Fixture in companion ¡ Companion object の中に(≒ static object として;Java)定義 ¡ Pros ¡ 比較的見つけやすい(?) ¡ コンパイル単位を越えて簡単に使える ¡ Cons ¡ Production code への混入(が default value 程ではない) ¡ などなど

Slide 23

Slide 23 text

Fixture in companion

Slide 24

Slide 24 text

Random ¡ 乱数でインスタンスを初期化してテスト ¡ Motivation ¡ いちいち new するのはめんどうだ(引数が) ¡ かといって default 値を入れるのは production code を汚す ¡ Fixture 管理もしたくない ¡ Pros ¡ 手間が無く簡単 ¡ 共有しないので、共有ルールを覚える必要は無い ¡ Cons ¡ テストに新たな不確定要素が増える ¡ 意味のある値はいれられない・にくい(例:User Agent ¡ Not DAMP. 純粋に Random を利用すると、 『つまりどうなる?』 が解りにくい(DAMP)

Slide 25

Slide 25 text

Fixture by mock ¡ 4FSWJDF౳ͷ .PDLJOHʹ͔ͭ͏ MJCSBSZΛ pYUVSFʹ΋ར༻͢Δ ¡ 1SPT ¡ 4FSWJDF ౳ͷ NPDLJOHͱಉ͡΍Γ͔ͨɻ ¡ *OUFSBDUJPOΛશͯ໌Β͔ʹͰ͖Δ ¡ ྫʣಛఆͷ 'JFME͔͠৮͍ͬͯͳ͍ࣄΛ͔֬ʹ͍ͨ͠ ¡ $POT ¡ ʰσʔλɾঢ়ଶʱͰ͸ͳ͘ʰ࣮૷ʱ ͷςετʹͳͬͯ͠·͏

Slide 26

Slide 26 text

状態では無く実装をテストしてしまう、とは? ¡ ྫʣ ¡ ϑΟʔϧυΛ௚઀ࢀর͢Δͷ͔ɺNFUIPEܦ༝Ͱࢀর͢Δͷ͔ɺͩͱ͢Ε͹ͲͷϝιουΛࢀর͍ͯ͠Δͷ͔ʁ Λҙࣝͯ͠ .PDL͢Δඞཁ͕͋Δ

Slide 27

Slide 27 text

一覧 ࠶ར༻Մೳੑ ຊ൪ίʔυԚછ ݟ͔ͭΓ΍͍͔͢ %".1 QSJWBUFWBM ❌ in class only 🟢 ❌ 🟢 45"5*$@'*/"- 🟢 🟢 ⚠ ⚠ EFGBVMUWBMVF 🟢 ❌ 🟢 ⚠ DPNQBOJPOPCKFDU 🟢 ❌ 🟢 ⚠ SBOEPN 'JYUVSF ❌ 🟢 ❌ ❌ NPDL'JYUVSF ❌ 🟢 ❌ 🟢 (実装をテスト) ˞ ຊ౰͸ɺʰͲͷΑ͏ʹΠϯελϯεΛ࡞Δ͔ʱʰͲͷΑ͏ʹڞ༗͢Δ͔ʱͷೋ͕࣠͋Δ

Slide 28

Slide 28 text

Fixture 管理あれこれ / まとめ ¡ มߋʹڧ͍ɺͱݺ͹ΕΔύλʔϯ͸࣮ࡍ͸ʰมߋΛӅ͢ʱํ๏Ͱ͋Δࣄ΋͋ΔɻʢEFGBVMUGJYUVSF ¡ Ӆ͞ͳ͚Ε͹ίϯύΠϧ࣌ʹؾ͚ͮΔɻ ¡ Ӆͨ͠Βɿ࣮ߦ࣌͠ͳ͍ͱؾ͚ͮͳ͍ɻ ¡ ݱ࣮ͷݱ৔ ¡ ʰઌ݄ 6TFSΫϥεʹϑΟʔϧυ͕૿͚͑ͨͲɺͦͷͱ͖͸Ұ෦ͷ .FUIPE ͔͠ରԠͯ͠ͳ͍Έ͍ͨɻ ඇରԠͷ .FUIPE ͔Βऔಘͨ͠৔߹͸ຊདྷͷঢ়ଶͱ͸ؔ܎ແ͘ɺϑΟʔϧυ͕ৗʹ GBMTFʹͳͬͪΌ͏ΜͩΑͶɻɻɻɻʱ ¡ 1SPEVDUJPODPEFʢTSDNBJOʣʹॻ͚͹ɺ࠶ར༻ՄೳʹͳΔɻɻɻʁ ¡ ΋΍ͬͱ͢Δɻʢʣ ¡ ֎෦ -JCSBSZ ͷ 'JYUVSF ͸Կॲʹॻ͘ʁ ໰୊͕ൃੜɻ ¡ Ϋϥεͷۙ͘ʢ 1SPEVDUJPODPEFʣʹॻ͚͹ݟ͚ͭ΍͍͢ɺԕ͘ʹॻ͍ͯݟ͚ͭ΍͘͢͢ΔͨΊʹ͸ɻɻɻɻʁ ˠඞཁͳͷ͸ɺ1SPEVDUJPODPEFʹӨڹΛ͓΅Αͣ͞ɺ֎෦ϥΠϒϥϦΫϥεʢ+BWBؚΉʣʹ΋࢖͑ͯɺ ॻ͖ํΛεέʔϧͨ͠ͱ͖ʹʢ෼ࢄͯ͠ॻ͍ͨͱ͖ʹʣݟ͚ͭ΍͍͢ 'JYUVSF ͷॻ͖ํɻ

Slide 29

Slide 29 text

本セッションの流れ ¡ ࣗݾ঺հɾഎܠͷ૝ఆ ¡ 5FTUͱ l'JYUVSFz ͷؔ܎ ¡ 'JYUVSF؅ཧͷॏཁੑ ¡ 'JYUVSF؅ཧ͋Ε͜Ε ¡ $"1*5"-@$"4&pYUVSF ¡ 'JYUVSFJOEFGBVMUWBMVF ¡ 'JYUVSFJODPNQPOFOU ¡ 3BOEPN'JYUVSFFUDʜ ¡ DMBTTpYUVSF QBUUFSOͷ঺հ ¡ (SBEMF`TKBWBUFTUpYUVSFT QMVHJO ¡ $MPTJOH

Slide 30

Slide 30 text

::class.fixture() pattern ¡ Fixture を対象クラス(KClass)の拡張関数として定義 ¡ 拡張関数なので、コードを汚染しない。

Slide 31

Slide 31 text

Example) 基本的な使い方

Slide 32

Slide 32 text

::class.fixture() pattern ¡ 'JYUVSFΛର৅Ϋϥεʢ,$MBTTʣͷ֦ுؔ਺ͱͯ͠ఆٛ ¡ ֦ுؔ਺ͳͷͰɺ1SPEVDUJPO DPEFΛԚછ͠ͳ͍ɻ ¡ 1SPT ¡ ֦ுؔ਺ͱͯ͠࠶ར༻Λલఏ ¡ -JCSBSZ ͷίʔυʹ΋ར༻Մೳ ¡ +BWBͰॻ͔Ε͍ͯͯ΋ 0, ¡ $POT ¡ ֦ுؔ਺Ͱ͢ʂ ར༻͸ܭըతʹ ¡ 1SPEVDUJPODPEFͱ෼཭͞ΕΔͷͰɺ $PNQJMFڥքΛӽ͑Δҝʹ 1MVHJO ͕ඞཁ

Slide 33

Slide 33 text

Why KClass? companion object に対して拡張関数を定義できるが、、 ¡ DPNQBOJPOPCKFDU ʹର֦ͯ͠ுؔ਺Λఆٛ͢Ε ͹΋ͬͱγϯϓϧʹ $MBTTGJYUVSF Ͱݺͼग़ͤΔ ¡ ͕ɺۭͷ DPNQBOJPOPCKFDU͕ඞཁ ¡ एׯ QSPEVDUJPODPEFʹӨڹ ¡ ֎෦ͷɾ+BWB ͷΫϥεʹద༻Ͱ͖ͳ͍ ¡ ,$MBTT JOTUBODF͸ +BWB ͷΫϥεʹରͯ͠΋औಘ Մೳ

Slide 34

Slide 34 text

&YBNQMF +BWB Ͱॻ͔ΕͨΫϥε΋ର৅ʹ ¡ +BWBͰॻ͔ΕͨΫϥε΋ ,$MBTT͸͋Δ ¡ ,$MBTT Λܦ༝ͯ͠ܕʹٖࣅతͳ֦ுؔ਺Λ࡞੒ ¡ 1SPEVDUJPO DPEFଆͰ EFGBVMU஋͕ແ͍ɾ DPQZNFUIPE͕ແ͍৔߹Ͱ΋ GJYUVSF͕໌ࣔ తʹ࡞ΕΔɻ

Slide 35

Slide 35 text

Example) 外部クラスに対しても利用可能

Slide 36

Slide 36 text

No content

Slide 37

Slide 37 text

Example) Mock / Helper へのヒントとして ¡ mockk ¡ 自分で mock してしまいがちだが、、、 ¡ spring-boot-starter-test に MockHttpServletRequest がある ¡ 知らないとなかなか見つからない ¡ fixture にヒントを書く

Slide 38

Slide 38 text

No content

Slide 39

Slide 39 text

実際はこれで十分 ¡ 先の例では rich な @Deprecated を書きましたが実際はこれで十分

Slide 40

Slide 40 text

DMBTTGJYUVSF QBUUFSO·ͱΊ ¡ ,$MBTTΠϯελϯεʹର͢Δ֦ுؔ਺ͱͯ͠ 'JYUVSF Λఆٛ ¡ ,$MBTT5Πϯελϯεʹର͢Δ֦ுؔ਺Λॻ͍ͯ 5ܕ΁ͷ֦ுؔ਺ͱݟͳ͢ ¡ ୳͠΍͍͢ʢ*%& 'SJFOEMZʣ ¡ ֎෦ίʔυɾ+BWB ʹ΋ద༻Մೳ ¡ ͦΕͧΕ͕ಠཱͨ͠৔ॴʹॻ͚Δ ¡ ֦ுؔ਺ͷ͝ར༻͸ܭըతʹ ¡ #VU౓ʰDMBTTpYUVSF Ͱ୳ͤΔʱ͕νʔϜʹड͚ೖΕΒΕΕ͹ָɻ

Slide 41

Slide 41 text

本セッションの流れ ¡ ࣗݾ঺հɾഎܠͷ૝ఆ ¡ 5FTUͱ l'JYUVSFz ͷؔ܎ ¡ 'JYUVSF؅ཧͷॏཁੑ ¡ 'JYUVSF؅ཧ͋Ε͜Ε ¡ $"1*5"-@$"4&GJYUVSF ¡ 'JYUVSFJOEFGBVMUWBMVF ¡ 'JYUVSFJODPNQPOFOU ¡ 3BOEPN'JYUVSFFUDʜ ¡ DMBTTGJYUVSF QBUUFSOͷ঺հ ¡ (SBEMF`T+BWB5FTU'JYUVSF1MVHJO ¡ $MPTJOH

Slide 42

Slide 42 text

+BWB5FTU'JYUVSFT1MVHJO ͷ঺հ ¡ +BWB5FTU'JYUVSFT1MVHJO ¡ (SBEMF ެࣜͷ 'JYUVSF ڞ༗༻ 1MVHJO ¡ (SBEMF6TFS(VJEF +BWB5FTUJOH 6TJOHUFTUpYUVSFT ¡ IUUQTEPDTHSBEMFPSHDVSSFOUVTFSHVJEFKBWB@UFTUJOHIUNMTFDKBWB@UFTU@pYUVSFT ¡ Ͱ͖Δ͜ͱʣNPEVMFڥքΛӽ͑ͯ 'JYUVSFΛ࠶ར༻Ͱ͖ΔΑ͏ʹͳΔ SFQPTJUPSZTFSWFS ¡ TSDNBJOʹॻ͍ͨΒ QSPEVDUJPODPEFࠞೖ ❌ ¡ TSDUFTUʹॻ͍ͯ΋ڞ༗Ͱ͖ͳ͍ ❌

Slide 43

Slide 43 text

+BWB5FTU'JYUVSFT1MVHJO ͷ࢖͍ํʢηοτΞοϓʣ ¡ NBJO UFTUͷଞʹ lUFTU'JYUVSFTzTPVSDFTFU͕Ͱ ͖Δ ¡ Ϟδϡʔϧ୯ମʹ͓͍ͯ ¡ UFTU'JYUVSFT͸ NBJOͷ $MBTT͕ݟ͑Δ ¡ UFTU͸ UFTU'JYUVSFTͷ $MBTT͕ݟ͑Δ NBJO UFTU'JYUVSFT UFTU

Slide 44

Slide 44 text

QSPKFDU TUPSBHFVTFS +BWB5FTU'JYUVSFT1MVHJO ͷԿ͕خ͍͠ͷ͔ ¡ Ϟδϡʔϧ୯ମͰ͸Կ΋خ͘͠ͳ͍ ¡ 'JYUVSF ͸ଞͷϞδϡʔϧͰ΋࠶ར༻Ͱ͖Δɺͱ͍͏ͱ͜Ζʹخ͕͋͠͞Δ ¡ ྫɿTFSWFSNPEVMFͰɺTUPSBHFNPEVMFͷ 'JYUVSF Λ࢖͍ճ͍ͨ͠ QSPKFDU BQJTFSWFS EFQFOEFODZ\ JNQMFNFOUBUJPO QSPKFDU lTUPSBHFVTFSz ^ QSPKFDU CBUDITVTFS EFQFOEFODZ\ JNQMFNFOUBUJPO QSPKFDU lTUPSBHFVTFSz ^

Slide 45

Slide 45 text

QSPKFDU TUPSBHFVTFS +BWB5FTU'JYUVSFT1MVHJO ͷ࢖͍ํʢར༻ʣ NBJO UFTU'JYUVSFT UFTU QSPKFDU BQJTFSWFS EFQFOEFODZ\ GPSNBJO JNQMFNFOUBUJPO QSPKFDU lTUPSBHFVTFSz GPS5FTUJOH UFTU*NQMFNFOUBUJPO UFTU'JYUVSFT QSPKFDU lTUPSBHFVTFSz ^ QSPKFDU CBUDITVTFS

Slide 46

Slide 46 text

+BWB5FTU'JYUVSFT1MVHJO 'JYUVSF ఏڙଆ

Slide 47

Slide 47 text

+BWB5FTU'JYUVSFT1MVHJO 'JYUVSF ར༻ଆ

Slide 48

Slide 48 text

+BWB5FTU'JYUVSFT1MVHJO ·ͱΊ Gradle 公式の Fixture 管理用 Plugin Fixture を個別 source set として管理 Module を越えた、 Fixture 再利用を可能にする Fixture のコピー&ペーストしなくてよくなる

Slide 49

Slide 49 text

本セッションの流れ ¡ ࣗݾ঺հɾഎܠͷ૝ఆ ¡ 5FTUͱ l'JYUVSFz ͷؔ܎ ¡ 'JYUVSF؅ཧͷॏཁੑ ¡ 'JYUVSF؅ཧ͋Ε͜Ε ¡ $"1*5"-@$"4&GJYUVSF ¡ 'JYUVSFJOEFGBVMUWBMVF ¡ 'JYUVSFJODPNQPOFOU ¡ 3BOEPN'JYUVSFFUDʜ ¡ DMBTTGJYUVSF QBUUFSOͷ঺հ ¡ (SBEMF`TKBWBUFTUGJYUVSFT QMVHJO ¡ $MPTJOH

Slide 50

Slide 50 text

まとめ ¡ 5FTU'JYUVSF؅ཧ͸ॏཁʢˍ໘ന͍ʣ ¡ ໌֬ͰಡΈ΍͍͢ςετͷͨΊɻ݁Ռͱͯ͠ςετͷॻ͖΍͢͞ͷͨΊɻ ¡ ʰͳΜͱͳ͘ΊΜͲ͍͘͞ςετʱΛ୤٫͢Δͷʹඞཁͳͭ ¡ 'JYUVSFΛ੔ཧͨ͠Βɺઃܭ΍ࣄલ४උͷվળ఺͕໨ཱͭΑ͏ʹͳΔ͔΋ ¡ ͨͩ͠ɺ'JYUVSF ؅ཧͱڞʹ໌ࣔతͳ DIFDLɺ΋େࣄɻʢ%".1આ໌త͔ͭҙຯ͕෼͔Γ΍͍͢ݴ͍ճ͠ʣ ¡ DMBTTGJYUVSF QBUUFSO,$MBTT ֦ுؔ਺ͱͯ͠ॻ͘͜ͱͰɺ*%& ͷԸܙ΋ड͚ΒΕͯڞ༗ʹศར ¡ ͦ͜ʹͳ͍ ଟ෼ଞʹ΋ॻ͔Ε͍ͯͳ͍ νʔϜͱͯ͠௥Ճ͢Δɺͷ൑அ ¡ 5FTU'JYUVSFҎ֎ʹ΋࢖͑Δʢ+BWB`T#VJMEFSSFQMBDFNFOU౳ʣ ¡ (SBEMFެࣜ +BWB5FTU'JYUVSFT1MVHJOศར ¡ lKBWBzͱ͍͍ͭͯ·͕͢ɺ౰વ ,PUMJOͰ΋ศརʹ࢖͑Δ

Slide 51

Slide 51 text

::class.fixture() QBUUFSO Š ֦ுؔ਺Λੜ͔ͨ͠ɺ5FTU'JYUVSF؅ཧͷ঺հ !,PUMJO'FTU 5IBOLZPV,PUMJO ,PUMJO'FTU 5IBOL ZPVGPSZPVSMJTUFOJOH