Slide 1

Slide 1 text

5PNPIJTB0EB(.01FQBCP *OD +VOF (FFLT8IP%SJOLJO'VLVPLB (P(P(PMBOH&EJUJPO (PͰ΋΍Ζ͏ʂ ΠϯςάϨʔγϣϯςετ

Slide 2

Slide 2 text

ϓϦϯγύϧΤϯδχΞ খా஌ԝ!MJOZPXT ٕज़෦ٕज़ج൫νʔϜ IUUQUPNPIJTBPEBDPN

Slide 3

Slide 3 text

ϒϩάɿIUUQUPNPIJTBPEBDPNQPTUTFBTF@NBOBHFNFOU@PG@MJOVY@TFSWFS@BENJOJTUSBUPSIUNM ࠷ۙ࡞ͬͨ044ͷ͝঺հ MJOVYϢʔβͷ໊લղܾΛHJUIVCͷUFBNTͰߦ͏

Slide 4

Slide 4 text

ৄࡉ͸໌ޙ೔ͷ :"1$'VLVPLBલʑ໷ࡇͰ ͓࿩͠͠·͢ʂ ⚠શવ໺ࡊ͸ɺલ໷ࡇͷલͷ࣌ؒʹ͋ΔϖύϘඇެࣜΠϕϯτͰ͢

Slide 5

Slide 5 text

(PΛۀ຿Ͱ࢖͍ͬͯ·͔͢ʁ ʕ◔ϖ◔ʔ ࣸਅఏڙɿ෱Ԭࢢ

Slide 6

Slide 6 text

(PΛۀ຿Ͱ࢖͍ͬͯ·͔͢ʁ wαʔϏεͷίΞͱͯ͠࢖͍ͬͯΔ wαʔϏεͷҰ෦ͱͯ͠࢖͍ͬͯΔ wࣾ಺ศརπʔϧͰ࢖͍ͬͯΔ wϓϥΠϕʔτͰ͸࢖͍ͬͯΔ

Slide 7

Slide 7 text

(Pͷςετ͸ॻ͍ͯ·͢Ͷʁ ʕ◔ϖ◔ʔ … ʕ◔ϖ◔ʔ ࣸਅఏڙɿ෱Ԭࢢ

Slide 8

Slide 8 text

΋ͪΖΜॻ͍ͯ·͢ϤΥʙ ʘશһखΛ͋͛Δʗ

Slide 9

Slide 9 text

࠷ۙͷ෩ܠ ϧʔςΟϯά͕ແ͍͍ͤͰɺͱ͋ Δ"1*͕ػೳ͍ͯ͠ͳ͔ͬͨɻ ϧʔςΟϯάͷςετΛ௥Ճʁ 3FRVFTU΍%#Λελϒͯ͠"1*Λ ࣮ߦ͢ΔςετΛॻ͘ʁ ͦΕ΋େࣄ

Slide 10

Slide 10 text

ͦ΋ͦ΋ ࠷ऴతͳಈ࡞Λ୲อ͢Δ ςετ͕ͳ͔ͬͨ

Slide 11

Slide 11 text

ͭ·ΓɺΠϯςάϨʔγϣϯςετ ʢ"1*ͩͱ&OEUP&OEʹ͍͔ۙ΋ʣ ࣸਅఏڙɿ෱Ԭࢢ

Slide 12

Slide 12 text

લఏ w)551(P"1*%#Λ౷߹ͨ͠ςετ w(PͷϓϩμΫτͳͷͰ(PͰ΍Γ͍ͨʢ wͦͯ͠γϯϓϧʹUFTUJOHύοέʔδͰ׬͍ྃͨ͠

Slide 13

Slide 13 text

ͳΔ΄Ͳʜ؆୯ʹ΍Ε·͢Ͷ func TestFooAPI(t *testing.T) { expectedBody, _ := ioutil.ReadFile(“./testdata/foo/get_res.json”) res, _ := http.Get(endpoint + “/foo”) gotBody, _ := ioutil.ReadALL(res.Body) res.Body.Close() if gotBody != expectedBody { t.Error(“FooAPI returns wrong body”) } }

Slide 14

Slide 14 text

Ϛελσʔλ΍ ظ଴͢ΔϨεϙϯεͷͨΊʹ 4FFEσʔλΛςετ࣮ߦલʹ ೖΕ͓͖͍ͯͨ

Slide 15

Slide 15 text

5FTU.BJO͕͋Γ·ͯ͠ͶʜॳظԽͱޙॲཧ func TestMain(m *testing.M) { setup() retCode := m.Run() os.Exit(retCode) } func setup() { db, _ := sql.Open(“postgres”, connInfo) db.Exec("DELETE FROM foo”) db.Exec("INSERT INTO bar(… defer db.Close() } func teardown() { db.Exec("TRUNCATE TABLE foo CASCAD… defer db.Close() }

Slide 16

Slide 16 text

5FTU.BJO͸QBDLBHF୯ҐͰDBMM͞ΕΔ /cmd/myapp/main.go /handlers/foo.go foo_test.go main_test.go /models/foo.go foo_test.go main_test.go /integration_test.go

Slide 17

Slide 17 text

5FTU.BJO͸ ύοέʔδ͝ͱ ̍౓͔࣮͠ߦ͞Εͳ͍ʜ ຖճॲཧ͍ͨ͠৔߹͸ʁ

Slide 18

Slide 18 text

ςετͷ౓ʹࣄલࣄޙॲཧΛ͢Δ func TestFoo(t *testing.T) { defer SetupTeardown(t)() . . . } func SetupTeardown(t *testing.T) func() { t.Log(“Setup”) return func() { t.Log(“Teardown”) } }

Slide 19

Slide 19 text

ීஈͷHPUFTUͰ ΠϯςάϨʔγϣϯςετ͸ ࣮ߦ͞Εͳ͍Ͱ΄͍͠

Slide 20

Slide 20 text

Ҿ਺Λ࢖͏

Slide 21

Slide 21 text

ͨͩ͠ɺ͢΂ͯͷςετʹ෼ذ͕ඞཁ var integration = flag.Bool(“integration”, false, “run integration test”) func TestMain(m *testing.M) { flag.Parse() if *integration { setup() } retCode := m.Run() if *integration { teardown() } os.Exit(retCode) } func TestIntegration1(t *testing.T) { if !*integration { t.Skip() } . . .

Slide 22

Slide 22 text

Ϣχοτςετ͸ HPUFTU ΠϯςάϨʔγϣϯςετ͸ HPUFTUJOUFHSBUJPO ͱ͍͏࢖͍෼͚͕ग़དྷΔ

Slide 23

Slide 23 text

͋͞ɺ͜ΕͰͲΜͲΜςετॻ͍ͯ ඼࣭Λ্͍͛ͯͧ͘ʂʂʂ ࣸਅఏڙɿ෱Ԭࢢ

Slide 24

Slide 24 text

༨ஊͰ͕͢ ςετͷཻ౓ʹ΋ όϥϯε͕͋Γ·͢ͷͰ ͝஫ҙ͍ͩ͘͞ 6*& (PPHMF5FTUJOH#MPH+VTU4BZ/PUP.PSF&OEUP&OE5FTUT IUUQTUFTUJOHHPPHMFCMPHDPNKVTUTBZOPUPNPSFFOEUPFOEUFTUTIUNM

Slide 25

Slide 25 text

·ͱΊ wΠϯςάϨʔγϣϯςετ͸खܰʹ͔͚·͢ wҾ਺Λ࢖͑͹ϢχοτςετͱΠϯςάϨʔγϣϯςετ Λ෼͚࣮ͯߦͰ͖Δ wύοέʔδ͝ͱ5FTU.BJOͰςετͷࣄલࣄޙॲཧ͕Ͱ͖Δ w֤ςετ͝ͱʹࣄલࣄޙॲཧΛ΍Γ͍ͨ৔߹΋Ұߦ௥Ճ͢ Ε͹Մೳ

Slide 26

Slide 26 text

ݕূͰ࢖ͬͨίʔυ͸ͪ͜Β IUUQTHJUIVCDPNMJOZPXTHPUFTUTFUVQUFBSEPXOTBOECPY

Slide 27

Slide 27 text

܅΋ϖύϘͰಇ͔ͳ͍͔ʁ ࠷৽ͷ࠾༻৘ใΛνΣοΫˠ !QC@SFDSVJU

Slide 28

Slide 28 text

͋Γ͕ͱ͏͍͟͝·ͨ͠