Upgrade to Pro — share decks privately, control downloads, hide ads and more …

標準パッケージにおけるテストでの利用例から学ぶ testing / quick パッケージ/golang-testing-quick

標準パッケージにおけるテストでの利用例から学ぶ testing / quick パッケージ/golang-testing-quick

Go Conference 2019 Spring の発表資料
https://gocon.jp/

70d9714ea13fc1133803d61fb16e4160?s=128

Yusuke Hosonuma

May 18, 2019
Tweet

Transcript

  1. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ඪ४ύοέʔδʹ͓͚Δ ςετͰͷར༻ྫ͔ΒֶͿ UFTUJOHRVJDLύοέʔδ

    1 Go Conference 2019 Spring 2019/5/18ʢSatʣ 
 ࡉপ ༞հ@DeNA
  2. "CPVU 2 Copyright (C) DeNA Co.,Ltd. All Rights Reserved.

  3. ॴଐ • 48&5άϧʔϓˏ%F/" • ςετࣗಈԽνʔϜɿJ04(Pݴޠ ޷͖ͳ΋ͷ • ݴޠɿ4XJGUɺ)BTLFMMɺ-JTQʢʁʣ • झຯɿɺαΠΫϦϯάɺొࢁ

    ίϛϡχςΟ • ϖϯΪϯଜ ۙگ • USZ4XJGU50,:0Ͱొஃ Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 3 ෼τʔΫ :VTVLF)PTPOVNB!UPCJʢͱͼʣ
  4. ࠓ೔࿩͢͜ͱ 4 Copyright (C) DeNA Co.,Ltd. All Rights Reserved.

  5. UFTUJOHRVJDLύοέʔδ 5 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ඪ४ύοέʔδʹؚ·ΕΔ

  6. 6 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. (PݴޠͷύοέʔδҰཡ IUUQTHPMBOHPSHQLH

  7. 7 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. (PݴޠͷύοέʔδҰཡ IUUQTHPMBOHPSHQLH

    ʮϒϥοΫϘοΫεςετʯͷͨΊͷ6UJMJUZΛఏڙ
  8. 8 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. (PݴޠͷύοέʔδҰཡ IUUQTHPMBOHPSHQLH

    ʮϒϥοΫϘοΫεςετʯͷͨΊͷ6UJMJUZΛఏڙ ୺తʹݴͬͯ͠·͑͹ɺ ʮϥϯμϜ஋ʯΛ࢖ͬͨςετ
  9. ଍͠ࢉͷςετͰ ൺֱͯ͠ΈΔ 9 Copyright (C) DeNA Co.,Ltd. All Rights Reserved.

  10. ௨ৗͷςετ 10 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. UFTUJOHύοέʔδ

  11. 11 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 0 ʴ

    1 ʹ 1 1 ʴ 1 ʹ 2 ௨ৗͷςετ
  12. 12 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 0 ʴ

    1 ʹ 1 1 ʴ 1 ʹ 2 ௨ৗͷςετ ೖྗ஋
  13. 13 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 0 ʴ

    1 ʹ 1 1 ʴ 1 ʹ 2 ௨ৗͷςετ ೖྗ஋ ظ଴஋
  14. 14 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 1 ʴ

    0 ʹ 1 1 ʴ 1 ʹ 2 ௨ৗͷςετ ೖྗ஋ ظ଴஋ ໌֬ͳೖྗ஋ͱظ଴஋Λ ༩͑ͯݕূ͢Δ
  15. 15 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ௨ৗͷςετ import

    "testing" func TestAdd(t *testing.T) { tests := []struct { x int y int want int }{ {x: 0, y: 1, want: 1}, // 0 + 1 = 1 {x: 1, y: 1, want: 2}, // 1 + 1 = 2 } for _, tt := range tests { if got := Add(tt.x, tt.y); got != tt.want { t.Errorf("Add() = %v, want %v", got, tt.want) } } }
  16. 16 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ௨ৗͷςετ import

    "testing" func TestAdd(t *testing.T) { tests := []struct { x int y int want int }{ {x: 0, y: 1, want: 1}, // 0 + 1 = 1 {x: 1, y: 1, want: 2}, // 1 + 1 = 2 } for _, tt := range tests { if got := Add(tt.x, tt.y); got != tt.want { t.Errorf("Add() = %v, want %v", got, tt.want) } } } ໌֬ͳʮೖྗ஋ʯͱʮظ଴஋ʯΛ༩͑Δ
  17. ϥϯμϜςετ 17 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. UFTUJOHRVJDLύοέʔδ

  18. 18 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. x ʴ

    y ʹ z y ʴ x ʹ z’ ϥϯμϜςετ
  19. 19 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. x ʴ

    y ʹ z y ʴ x ʹ z’ ϥϯμϜςετ ೖྗ஋ YͱZΛϥϯμϜʹੜ੒
  20. 20 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. x ʴ

    y ʹ z y ʴ x ʹ z’ ϥϯμϜςετ ೖྗ஋ ଍͠ࢉ͸ަ׵๏ଇΛຬͨ͢ͷͰ [ͱ[`͸ৗʹҰக͢Δ
  21. 21 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. x ʴ

    y ʹ z y ʴ x ʹ z’ ϥϯμϜςετ ೖྗ஋ ଍͠ࢉ͸ަ׵๏ଇΛຬͨ͢ͷͰ [ͱ[`͸ৗʹҰக͢Δ ϥϯμϜ஋ʹରͯ͠ ຬͨ͢΂͖ੑ࣭Λݕূ͢Δ
  22. 22 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ϥϯμϜςετ import

    ( "testing" "testing/quick" ) func TestAddQuick(t *testing.T) { f := func(x, y int) bool { return Add(x, y) == Add(y, x) } if err := quick.Check(f, nil); err != nil { t.Error(err.Error()) } }
  23. 23 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ϥϯμϜςετ import

    ( "testing" "testing/quick" ) func TestAddQuick(t *testing.T) { f := func(x, y int) bool { return Add(x, y) == Add(y, x) } if err := quick.Check(f, nil); err != nil { t.Error(err.Error()) } } UFTUJOHRVJDLΛJNQPSU
  24. 24 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ϥϯμϜςετ import

    ( “testing" "testing/quick" ) func TestAddQuick(t *testing.T) { f := func(x, y int) bool { return Add(x, y) == Add(y, x) } if err := quick.Check(f, nil); err != nil { t.Error(err.Error()) } } νΣοΫ༻ͷϔϧύʔؔ਺ ϥϯμϜͳೖྗ஋͕ೖͬͯ͘Δ૝ఆ
  25. 25 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ϥϯμϜςετ import

    ( "testing" "testing/quick" ) func TestAddQuick(t *testing.T) { f := func(x, y int) bool { return Add(x, y) == Add(y, x) } if err := quick.Check(f, nil); err != nil { t.Error(err.Error()) } } ަ׵๏ଇΛຬͨͤ͹USVF
  26. 26 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ϥϯμϜςετ import

    ( "testing" "testing/quick" ) func TestAddQuick(t *testing.T) { f := func(x, y int) bool { return Add(x, y) == Add(y, x) } if err := quick.Check(f, nil); err != nil { t.Error(err.Error()) } } ؔ਺͕ৗʹUSVFΛฦ͔͢ςετ
  27. 27 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ϥϯμϜςετ import

    ( "testing" "testing/quick" ) func TestAddQuick(t *testing.T) { f := func(x, y int) bool { return Add(x, y) == Add(y, x) } if err := quick.Check(f, nil); err != nil { t.Error(err.Error()) } } USVFΛฦ͞ͳ͍৔߹͸&SSPS͕ฦ٫
  28. ࣦഊ͢ΔέʔεΛݟͯΈΔ 28 Copyright (C) DeNA Co.,Ltd. All Rights Reserved.

  29. 29 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ࣦഊ͢Δέʔε func

    Add(x, y int) int { return x - y } // ίϯιʔϧग़ྗ --- FAIL: TestAddQuick (0.00s) #1: failed on input -8046014121776288896, -2929560796466791850
  30. 30 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ࣦഊ͢Δέʔε func

    Add(x, y int) int { return x - y } // ίϯιʔϧग़ྗ --- FAIL: TestAddQuick (0.00s) #1: failed on input -8046014121776288896, -2929560796466791850 ަ׵๏ଇΛຬͨ͞ͳ͍ʮҾ͖ࢉʯ
  31. 31 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ࣦഊ͢Δέʔε func

    Add(x, y int) int { return x - y } // ίϯιʔϧग़ྗ --- FAIL: TestAddQuick (0.00s) #1: failed on input -8046014121776288896, -2929560796466791850 Y Z
  32. 32 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ࣦഊ͢Δέʔε func

    Add(x, y int) int { return x - y } // ίϯιʔϧग़ྗ --- FAIL: TestAddQuick (0.00s) #1: failed on input -8046014121776288896, -2929560796466791850 Y Z ͜ΕΒͷ஋ͷ৔߹ʹࣦഊͨ͠ͱ͍͏ใࠂ
  33. ༻ޠͷ੔ཧ 33 Copyright (C) DeNA Co.,Ltd. All Rights Reserved.

  34. 34 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ༻ޠͷ੔ཧ •

    &YBNQMFCBTFE5FTU ⁃ ໌֬ͳೖྗ஋ͱظ଴஋Λ༩͑Δςετ
  35. 35 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ༻ޠͷ੔ཧ •

    &YBNQMFCBTFE5FTU ⁃ ໌֬ͳೖྗ஋ͱظ଴஋Λ༩͑Δςετ • 1SPQFSUZCBTFE5FTU ⁃ ϥϯμϜ஋ʹج͍ͮͨςετ ⁃ ຬͨ͢΂͖ੑ࣭ʢQSPQFSUZʣΛݕূ ⁃ )BTLFMMͷ2VJDL$IFDL͕ൃ঵
  36. 36 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ༻ޠͷ੔ཧ •

    &YBNQMFCBTFE5FTU ⁃ ໌֬ͳೖྗ஋ͱظ଴஋Λ༩͑Δςετ • 1SPQFSUZCBTFE5FTU ⁃ ϥϯμϜ஋ʹج͍ͮͨςετ ⁃ ຬͨ͢΂͖ੑ࣭ʢQSPQFSUZʣΛݕূ ⁃ )BTLFMMͷ2VJDL$IFDL͕ൃ঵ ʢͨͿΜʣRVJDLͱ͍͏໋໊͸͔͜͜Β
  37. ඪ४ύοέʔδʹ͓͚Δར༻ྫ 37 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. UFTUJOHRVJDLύοέʔδͷ

  38. ᶃ໌നͳ࣮૷ͱͷൺֱ 38 Copyright (C) DeNA Co.,Ltd. All Rights Reserved.

  39. 39 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ᶃ ໌നͳ࣮૷ͱͷൺֱ

    • ໌നͳ࣮૷ • ͍͍ͨͯͷ৔߹ɺ஗͍ • ྫɿϑΟϘφον਺ྻΛ࠶ؼͰղ͘ • ͦ͏Ͱͳ͍࣮૷ • ͍͍ͨͯͷ৔߹ɺෳࡶ • ྫɿϑΟϘφον਺ྻΛ຤ඌ࠶ؼͰղ͘
  40. 40 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ᶃ ໌നͳ࣮૷ͱͷൺֱ

    • ໌നͳ࣮૷ • ͍͍ͨͯͷ৔߹ɺ஗͍ • ྫɿϑΟϘφον਺ྻΛ࠶ؼͰղ͘ • ͦ͏Ͱͳ͍࣮૷ • ͍͍ͨͯͷ৔߹ɺෳࡶ • ྫɿϑΟϘφον਺ྻΛ຤ඌ࠶ؼͰղ͘ ͲͪΒ΋ಉ͡ೖྗʹରͯ͠͸ ඞͣಉ݁͡ՌΛฦ͢͸ͣ
  41. DPOTUBOU@UJNFHP 41 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. DSZQUPTVCUMF

  42. 42 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. $POTUBOU5JNF#ZUF&Rؔ਺ //

    ConstantTimeByteEq returns 1 if x == y and 0 otherwise. func ConstantTimeByteEq(x, y uint8) int { return int((uint32(x^y) - 1) >> 31) } ςετର৅
  43. 43 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. $POTUBOU5JNF#ZUF&Rؔ਺ //

    ConstantTimeByteEq returns 1 if x == y and 0 otherwise. func ConstantTimeByteEq(x, y uint8) int { return int((uint32(x^y) - 1) >> 31) } YͱZΛఆ਺࣌ؒͰൺֱ͢Δ Ұக͢Ε͹ɺҰக͠ͳ͚Ε͹Λฦ͢ ςετର৅
  44. 44 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. $POTUBOU5JNF#ZUF&Rؔ਺ func

    byteEq(a, b uint8) int { if a == b { return 1 } return 0 } func TestConstantTimeByteEq(t *testing.T) { err := quick.CheckEqual(ConstantTimeByteEq, byteEq, nil) if err != nil { t.Error(err) } } ςετίʔυ
  45. 45 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. $POTUBOU5JNF#ZUF&Rؔ਺ func

    byteEq(a, b uint8) int { if a == b { return 1 } return 0 } func TestConstantTimeByteEq(t *testing.T) { err := quick.CheckEqual(ConstantTimeByteEq, byteEq, nil) if err != nil { t.Error(err) } } ఆ਺࣌ؒͰ͸ͳ͍໌നͳൺֱؔ਺ ςετίʔυ
  46. 46 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. $POTUBOU5JNF#ZUF&Rؔ਺ func

    byteEq(a, b uint8) int { if a == b { return 1 } return 0 } func TestConstantTimeByteEq(t *testing.T) { err := quick.CheckEqual(ConstantTimeByteEq, byteEq, nil) if err != nil { t.Error(err) } } ςετ༻ͷؔ਺ ςετίʔυ
  47. 47 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. $POTUBOU5JNF#ZUF&Rؔ਺ func

    byteEq(a, b uint8) int { if a == b { return 1 } return 0 } func TestConstantTimeByteEq(t *testing.T) { err := quick.CheckEqual(ConstantTimeByteEq, byteEq, nil) if err != nil { t.Error(err) } } ͭͷؔ਺ʹ͍ͭͯಉ݁͡ՌΛฦ͢͜ͱ ςετର৅ ໌നͳ࣮૷ ςετίʔυ
  48. 48 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. $POTUBOU5JNF#ZUF&Rؔ਺ func

    byteEq(a, b uint8) int { if a == b { return 1 } return 0 } func TestConstantTimeByteEq(t *testing.T) { err := quick.CheckEqual(ConstantTimeByteEq, byteEq, nil) if err != nil { t.Error(err) } } ͭͷؔ਺ʹ͍ͭͯಉ݁͡ՌΛฦ͢͜ͱ ςετର৅ ໌നͳ࣮૷ ಉ͡࢓༷ʢͷ͸ͣʣͷؔ਺Ͱ͋Ε͹ CheckEqualؔ਺ͰಉҰੑΛݕূͰ͖Δ ৽چͷΞϧΰϦζϜൺֱʹ΋࢖͑Δ
  49. ᶄ'V[[ςετ 49 Copyright (C) DeNA Co.,Ltd. All Rights Reserved.

  50. 50 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ᶄ Fuzz

    ςετ • 'V[[ςετ • ༧ଌෆՄೳͳೖྗσʔλʢGV[[ʣΛ༩͑ɺ
 ෆ۩߹͕ൃੜ͢Δέʔε͕ແ͍͔୳͢
  51. 51 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ᶄ Fuzz

    ςετ • 'V[[ςετ • ༧ଌෆՄೳͳೖྗσʔλʢGV[[ʣΛ༩͑ɺ
 ෆ۩߹͕ൃੜ͢Δέʔε͕ແ͍͔୳͢ ϥϯμϜͳ Fuzz ςετ͸ ࣮֬Ͱ͸ͳ͍͕҆৺ײʹͭͳ͕Δ
  52. QFNHP 52 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. FODPEJOHQFN

  53. 53 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. &ODPEFؔ਺ //

    A Block represents a PEM encoded structure. // // The encoded form is: // -----BEGIN Type----- // Headers // base64-encoded Bytes // -----END Type—— // where Headers is a possibly empty sequence of Key: Value lines. type Block struct { Type string Headers map[string]string Bytes []byte } // Encode writes the PEM encoding of b to out. func Encode(out io.Writer, b *Block) error { } ςετର৅
  54. 54 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. &ODPEFؔ਺ //

    A Block represents a PEM encoded structure. // // The encoded form is: // -----BEGIN Type----- // Headers // base64-encoded Bytes // -----END Type----- // where Headers is a possibly empty sequence of Key: Value lines. type Block struct { Type string Headers map[string]string Bytes []byte } // Encode writes the PEM encoding of b to out. func Encode(out io.Writer, b *Block) error { } 1&.ܗࣜͷσʔλߏ଄ ςετର৅
  55. 55 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. &ODPEFؔ਺ //

    A Block represents a PEM encoded structure. // // The encoded form is: // -----BEGIN Type----- // Headers // base64-encoded Bytes // -----END Type----- // where Headers is a possibly empty sequence of Key: Value lines. type Block struct { Type string Headers map[string]string Bytes []byte } // Encode writes the PEM encoding of b to out. func Encode(out io.Writer, b *Block) error { } Τϯίʔυ༻ͷؔ਺ ςετର৅
  56. 56 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. &ODPEFؔ਺ func

    TestFuzz(t *testing.T) { testRoundtrip := func(block Block) bool { var buf bytes.Buffer if err := Encode(&buf, &block); err != nil { t.Errorf("Encode of %#v resulted in error: %s", &block, err) return false } decoded, rest := Decode(buf.Bytes()) if !reflect.DeepEqual(decoded, &block) { t.Errorf("Encode of %#v decoded as %#v", &block, decoded) return false } return true } quick.Check(testRoundtrip, nil) } ςετίʔυ
  57. 57 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. &ODPEFؔ਺ func

    TestFuzz(t *testing.T) { testRoundtrip := func(block Block) bool { var buf bytes.Buffer if err := Encode(&buf, &block); err != nil { t.Errorf("Encode of %#v resulted in error: %s", &block, err) return false } decoded, rest := Decode(buf.Bytes()) if !reflect.DeepEqual(decoded, &block) { t.Errorf("Encode of %#v decoded as %#v", &block, decoded) return false } return true } quick.Check(testRoundtrip, nil) } ςετ༻ͷؔ਺ ςετίʔυ
  58. 58 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. &ODPEFؔ਺ func

    TestFuzz(t *testing.T) { testRoundtrip := func(block Block) bool { var buf bytes.Buffer if err := Encode(&buf, &block); err != nil { t.Errorf("Encode of %#v resulted in error: %s", &block, err) return false } decoded, rest := Decode(buf.Bytes()) if !reflect.DeepEqual(decoded, &block) { t.Errorf("Encode of %#v decoded as %#v", &block, decoded) return false } return true } quick.Check(testRoundtrip, nil) } ೚ҙͷσʔλͰΤϯίʔυʹࣦഊ͠ͳ͍͜ͱ ςετίʔυ
  59. 59 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. &ODPEFؔ਺ func

    TestFuzz(t *testing.T) { testRoundtrip := func(block Block) bool { var buf bytes.Buffer if err := Encode(&buf, &block); err != nil { t.Errorf("Encode of %#v resulted in error: %s", &block, err) return false } decoded, rest := Decode(buf.Bytes()) if !reflect.DeepEqual(decoded, &block) { t.Errorf("Encode of %#v decoded as %#v", &block, decoded) return false } return true } quick.Check(testRoundtrip, nil) } σίʔυͨ͠ΒݩͱҰக͢Δ͜ͱ Τϯίʔυɾσίʔυͨ݁͠Ռ ݩσʔλ ςετίʔυ
  60. 60 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. &ODPEFؔ਺ func

    TestFuzz(t *testing.T) { testRoundtrip := func(block Block) bool { var buf bytes.Buffer if err := Encode(&buf, &block); err != nil { t.Errorf("Encode of %#v resulted in error: %s", &block, err) return false } decoded, rest := Decode(buf.Bytes()) if !reflect.DeepEqual(decoded, &block) { t.Errorf("Encode of %#v decoded as %#v", &block, decoded) return false } return true } quick.Check(testRoundtrip, nil) } σίʔυͨ͠ΒݩͱҰக͢Δ͜ͱ Τϯίʔυɾσίʔυͨ݁͠Ռ ݩσʔλ ϥϯμϜͳೖྗ஋Ͱ΋ຬͨ͢΂͖ੑ࣭Λ ςετίʔυͱͯ͠هड़Ͱ͖Δ ࠓճ͸ ɾΤϥʔʹͳΒͳ͍͜ͱ ɾΤϯίʔυɾσίʔυͨ͠Βݩʹ໭Δ͜ͱ
  61. ·ͱΊ 61 Copyright (C) DeNA Co.,Ltd. All Rights Reserved.

  62. 62 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ·ͱΊ •

    UFTUJOHRVJDL͸ϥϯμϜ஋ʹΑΔςετ • 1SPQFSUZCBTFE5FTUJOHͱ΋ݴΘΕΔ • (Pඪ४ύοέʔδͷςετͰ΋࢖ΘΕ͍ͯΔ ᶃ໌നͳ࣮૷ͱͷൺֱ ᶄ'V[[ςετ গͳ͍͚Ͳ
  63. 63 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ·ͱΊ •

    UFTUJOHRVJDL͸ϥϯμϜ஋ʹΑΔςετ • 1SPQFSUZCBTFE5FTUJOHͱ΋ݴΘΕΔ • (Pඪ४ύοέʔδͷςετͰ΋࢖ΘΕ͍ͯΔ ᶃ໌നͳ࣮૷ͱͷൺֱ ᶄ'V[[ςετ গͳ͍͚Ͳ ར༻γʔϯ͸ଟ͘ͳ͍͕ɺ దࡐదॴͰ࢖͑͹༗ޮͳख๏Ͱ͸ʁ ߟ͑ํͱ͓֮ͯ͑ͯ͘͠ͷ΋༗ޮ
  64. 8F`SF)JSJOH ςετࣗಈԽʹڵຯ͋Δํͥͻʂ 64 Copyright (C) DeNA Co.,Ltd. All Rights Reserved.

    ࠙਌ձɾ5XJUUFSͳͲ͓ؾܰʹʂ