Slide 1

Slide 1 text

$MPKVSFͷςετ ʹ͍ͭͯ $MPKVSF੒෼ೱ͍Ί ୈճौ୩KBWB !BZBUP@Q$ZCP[V4UBSUVQT *OD

Slide 2

Slide 2 text

BZBUP@Q ͋΍ͽʔͰ͢ &NBDTͱ$MPKVSF͕޷͖Ͱ͢ $MPKVSFྺ೥ͷ$MPKVSFΤϯδχΞͰ͢ ݄͔Βฐࣾ$MPKVSJBOਓʹͳΓ·͢

Slide 3

Slide 3 text

ຖճ$MPKVSFͷ࿩Λͯ͠ΔํͰ͢

Slide 4

Slide 4 text

໨࣍ ͦ΋ͦ΋$MPKVSFͬͯͳΜͩ $MPKVSFͰͷςετʹ͍ͭͯ DMPKVSFUFTUΛ࢖ͬͨجຊతͳςετͷॻ͖ํ ΑΓ࣮ફతͳॻ͖ํ ଞͷςετϑϨʔϜϫʔΫʹ͍ͭͯ

Slide 5

Slide 5 text

ͦ΋ͦ΋$MPKVSF ͬͯͳΜͩ

Slide 6

Slide 6 text

ͦ΋ͦ΋$MPKVSFͬͯͳΜͩ -JTQ ಈత։ൃ ؔ਺ܕϓϩάϥϛϯά ࣮ߦ࣌ϙϦϞʔϑΟζϜ ฒߦϓϩάϥϛϯά +7.ϗετ PS+BWB4DSJQU /&5

Slide 7

Slide 7 text

$MPKVSFͰͷ ςετʹ͍ͭͯ

Slide 8

Slide 8 text

3&1-ฤ 3&1-%SJWFO%FWFMPQNFOU ୯७ͳಈ࡞֬ೝͰ͸ςετέʔεॻ͘ΑΓ
 3&1-Ͱ֬ೝͨ͠ํ͕ૣ͍

Slide 9

Slide 9 text

ςετίʔυฤ ࠓ೔ͷຊฤ 3%%Λओு͢Δ͜ͱ͸ଟ͍͚ͲςετΛશ͘
 ॻ͔ͳ͍Θ͚Ͱ͸ͳ͍ ଞͷݴޠʹൺ΂Δͱςετ͕ॻ͖΍͍͢ͱ
 ײ͡Δͱ͜Ζ͸ଟ͍

Slide 10

Slide 10 text

DMPKVSFUFTUΛ࢖ͬͨ جຊతͳ ςετͷॻ͖ํ

Slide 11

Slide 11 text

(require '[clojure.test :refer :all]) (is (= 4 (+ 2 2))) (is (instance? Long 256)) (is (.startsWith "abcde" "ab")) Ξαʔγϣϯ DMPKVSFUFTUωʔϜεϖʔεΛ࢖͏ JTϚΫϩ͚֮ͩ͑Ε͹؆୯ʹςετ͕ग़དྷΔ

Slide 12

Slide 12 text

user> (is (= 5 (+ 2 2))) FAIL in () (form-init305064439250635979.clj:3) expected: (= 5 (+ 2 2)) actual: (not (= 5 4)) false Ξαʔγϣϯ 3&1-Ͱ΋࣮ߦՄೳ

Slide 13

Slide 13 text

(is (thrown? ArithmeticException (/ 1 0))) (is (thrown-with-msg? ArithmeticException #"Divide by zero" (/ 1 0))) Ξαʔγϣϯ ྫ֎ͷ৔߹͸ಛघͳUISPXO ͳͲΛ࢖͏

Slide 14

Slide 14 text

(is (= 5 (+ 2 2)) "Arithmetic") ςετͷυΩϡϝϯτԽ JTϚΫϩ͸ୈೋҾ਺ʹΞαʔγϣϯͷ
 આ໌Λ௥Ճग़དྷΔ

Slide 15

Slide 15 text

(testing "Arithmetic" (testing "with positive integers" (is (= 4 (+ 2 2))) (is (= 7 (+ 3 4)))) (testing "with negative integers" (is (= -4 (+ -2 -2))) (is (= -1 (+ 3 -4))))) ςετͷυΩϡϝϯτԽ UFTUJOHϚΫϩͰςετͷάϧʔϓԽ͕ग़དྷΔ จࣈྻ͸GBJMVSFSFQPSUTʹؚ·ΕΔ Ϩϙʔτ͸34QFD෩

Slide 16

Slide 16 text

(with-test (defn my-function [x y] (+ x y)) (is (= 4 (my-function 2 2))) (is (= 7 (my-function 3 4)))) ςετͷఆٛ XJUIUFTUΛ࢖͏ͱؔ਺ͷఆٛͱಉ࣌ʹ
 ςετΛهड़ग़དྷΔ ௨ৗ࢖͏͜ͱ͸ͳ͍ ίʔυશମͷݟ௨͕͠ѱ͘ͳΔ

Slide 17

Slide 17 text

(deftest addition (is (= 4 (+ 2 2))) (is (= 7 (+ 3 4)))) (deftest subtraction (is (= 1 (- 4 3))) (is (= 3 (- 7 4)))) ςετͷఆٛ EFGUFTUϚΫϩΛ࢖͏ ςετର৅ͱςετΛ෼͚ͯهड़ग़དྷΔ ௨ৗͪ͜ΒΛ࢖͏ͷ͕Ұൠత

Slide 18

Slide 18 text

(defn my-fixture [f] ;; 前処理 (f) ;; テストの実行 ;; 後処理 ) (use-fixtures :each my-fixture) ςετϑΟΫενϟ ϑΟΫενϟࣗମ͸ؔ਺Λͻͱͭड͚औΔ
 ؔ਺ͱͯ͠ఆٛͰ͖Δ ωʔϜεϖʔεʹରͯ͠Ξλον͢Δ

Slide 19

Slide 19 text

ΑΓ࣮ફతͳॻ͖ํ

Slide 20

Slide 20 text

!U@XBEB͞Μͷ໰୊Λղ͘ ໰Լهͷ࢓༷ΛςεςΟϯάϑϨʔϜϫʔΫΛ࢖ͬͯςετίʔυΛ ॻ͖ͳ͕Β࣮૷͍ͯͩ͘͠͞ɻ ʲ࢓༷ʳʮݱࡏ࣌ࠁʯʹԠͯ͡ɺѫࡰͷ಺༰ΛԼهͷΑ͏ʹͦΕͧΕฦ ͢ػೳΛ࡞੒͍ͨ͠ɻ λΠϜκʔϯ͸"TJB5PLZPͱ͢Δ ே Ҏ্ະຬ ͷ৔߹ɺʮ͓͸Α͏͍͟͝·͢ʯͱฦ͢ ன Ҏ্ະຬ ͷ৔߹ɺʮ͜Μʹͪ͸ʯͱฦ͢ ໷ Ҏ্ະຬ ͷ৔߹ɺʮ͜Μ͹Μ͸ʯͱฦ͢ ྫ࣌ʹHSFFUFSHSFFU ΛݺͿͱ͜Μʹͪ͸ͱฦ͢ IUUQTDPEFJRKQNBHB[JOF

Slide 21

Slide 21 text

(ns demoapp.greeter) (defn current-date-time [] (java.time.LocalDateTime/now)) (defn greet [] (let [current-hour (.getHour (current-date-time))] (cond (<= 5 current-hour 11) "おはようございます" (<= 12 current-hour 17) "こんにちは" :else "こんばんは"))) ςετର৅ͷίʔυ

Slide 22

Slide 22 text

(ns demoapp.greeter-test (:require [clojure.test :refer :all] [demoapp.greeter :as g :refer :all]) (:import [java.time LocalDateTime])) (deftest greet-test (are [dt-str expect] (with-redefs [g/current-date-time (constantly (LocalDateTime/parse dt-str))] (= (greet) expect)) "2016-04-22T00:00" "こんばんは" "2016-04-22T04:59" "こんばんは" "2016-04-22T05:00" "おはようございます" "2016-04-22T11:59" "おはようございます" "2016-04-22T12:00" "こんにちは" "2016-04-22T17:59" "こんにちは" "2016-04-22T18:00" "こんばんは" "2016-04-22T23:59" "こんばんは")) ςετίʔυ

Slide 23

Slide 23 text

࢖͍ͬͯΔςΫχοΫ BSFϚΫϩʹΑΔύϥϝλϥΠζυςετ XJUISFEFGTʹΑΔςετμϒϧͷ࣮ݱ

Slide 24

Slide 24 text

BSFϚΫϩ ࢓૊Έࣗମ͸୯७ JTϚΫϩͷܗʹల։͞ΕΔ ;; これが (are [a b x] (= (+ a b) x) 1 2 3 5 10 15) ;; こう展開される (do (is (= (+ 1 2) 3)) (is (= (+ 5 10) 15)))

Slide 25

Slide 25 text

XJUISFEFGT 7BSΛ࠶ఆٛ͢Δ CPEZ಺෦ͷΈͰ༗ޮ (defn add3 [x] (+ x 3)) (with-redefs [add3 (fn [x] (+ x 10))] (= (add3 10) 20)) ;; => true

Slide 26

Slide 26 text

(do (is (with-redefs [g/current-date-time (constantly (LocalDateTime/parse "2016-04-22T00:00"))] (= (greet) "こんばんは"))) ;; ... 中略 (is (with-redefs [g/current-date-time (constantly (LocalDateTime/parse "2016-04-22T23:59"))] (= (greet) "こんばんは")))) ͭ·Γ͜͏ͳΔ

Slide 27

Slide 27 text

ଞͷ ςετϑϨʔϜϫʔΫ ʹ͍ͭͯ

Slide 28

Slide 28 text

લఏͱͯ͠ ࠷ۙͰ͸৽͍͠%4-Λ࢖Θͳ͍Ͱ
 DMPKVSFUFTUΛ࢖͏ͷ͕ྲྀߦΓ IUUQTSBTUFSJ[FJPCMPHDMPKVSFUIFHPPE QBSUTIUNM ࢖͍ͬͯΔଆͷײ֮ͱͯ͠΋
 DMPKVSFUFTUͰ଍ΓΔͱײ͡Δ͜ͱ͸ଟ͍

Slide 29

Slide 29 text

TQFDMK 34QFDΛ$MPKVSFͱ$MPKVSF4DSJQUʹ
 ͖࣋ͬͯͨͱ͍͏ײ͡ͷςετϑϨʔϜϫʔΫ ͋·Γಛ༗ͷػೳΈ͍ͨͳͷ͕ͳ͍ͷͰ
 ࢖͏ϝϦοτ͕ྑ͘෼͔Βͳ͍

Slide 30

Slide 30 text

.JEKF ϙϐϡϥʔͳςετϑϨʔϜϫʔΫ GBDUBDUVBMFYQFDU ͱॻ͚Δ ߏ଄ͷൺֱ͕༰қͰ͋Δͷͱ.FUBDPOTUBOUT ͕ศརͰ͋Δ Ϧϩʔυ͢Δͱςετ͕࣮ߦ͞Εͯ͠·͏ υΩϡϝϯτ͕͋·Γ៉ྷʹ·ͱΊΒΕͯͳ͍

Slide 31

Slide 31 text

(def complex-data {"平成" [ {:id 1 :name "ayato_p"} {:id 2 :name "alea12"} ] "昭和" [ {:id 99 :name "foo"} {:id 100 :name "bar"} ]}) (fact complex-data => (contains {"平成" (contains [{:id 1 :name "ayato_p"}])})) .JEKF

Slide 32

Slide 32 text

(def members {1 "ayato_p" 2 "alea12" 3 "zer0_u"}) (defn get-id [m] (get m :id)) (defn find-member [m] (get members (get-id m))) (fact (find-member ...m...) => "ayato_p" (provided (get-id ...m...) => 1)) .JEKF

Slide 33

Slide 33 text

GVEKF ܰྔ൛.JEKF _LCKBS ґଘؔ܎͕গͳ͍ͷ΋ಛ௃ ·ͩࢼͨ͜͠ͱ͸ͳ͍͚Ͳྑͦ͞͏

Slide 34

Slide 34 text

DMPKVSFUFTUDIFDL 2VJDL$IFDLGPS$MPKVSF $MPKVSFຊମͷςετʹ΋࢖ΘΕ͍ͯΔ

Slide 35

Slide 35 text

·ͱΊ

Slide 36

Slide 36 text

·ͱΊ $MPKVSFͰςετΛॻ͘ͷ͸؆୯ ͱΓ͋͑ͣ໎ͬͨΒDMPKVSFUFTUΛ࢖͏ UFTUDIFDL͸Ұॹʹ࢖͑Δ