📖

【学習備忘録】(Swift)TDDでポーカーを実装(STEP3)

2022/05/24に公開

はじめに

「Swiftで書いておぼえるTDD」のポーカーアプリのコードをもとに学習しました。
TDDでポーカーアプリを実装します。

サンプルコード

0. 今回実装すること

  • rankとsuitの順番を並び替える。
     - 理由:文字列表記の順序に沿う形が望ましいため。
  • 不要なテストコードを削除。

1. テストコードを修正

  • 修正前
class Practice_TDD_PokerTests: XCTestCase {
    func testInitializeCard() {
        var card: Card

        card = Card(suit: .heart, rank: .three)
        XCTAssertEqual(card.suit, .heart)
        XCTAssertEqual(card.rank, .three)

        card = Card(suit: .spade, rank: .jack)
        XCTAssertEqual(card.suit, .spade)
        XCTAssertEqual(card.rank, .jack)
    }

    func testCardNotation() {
        var card: Card

        card = Card(suit: .heart, rank: .three)
        XCTAssertEqual(card.notation, "3❤︎")

        card = Card(suit: .spade, rank: .jack)
        XCTAssertEqual(card.notation, "J♠︎")
    }
}
  • 修正後
class Practice_TDD_PokerTests: XCTestCase {
    func testInitializeCard() {
        var card: Card

        card = Card(rank: .three, suit: .heart)
        XCTAssertEqual(card.rank, .three)
        XCTAssertEqual(card.suit, .heart)

        card = Card(rank: .jack, suit: .spade)
        XCTAssertEqual(card.rank, .jack)
        XCTAssertEqual(card.suit, .spade)
    }

    func testCardNotation() {
        var card: Card

        card = Card(rank: .three, suit: .heart)
        XCTAssertEqual(card.notation, "3❤︎")

        card = Card(rank: .jack, suit: .spade)
        XCTAssertEqual(card.notation, "J♠︎")
    }
}

これでテストを実行すると初期化時のrankとsuitの順番が逆になっているのでエラーが出ます。

2. コードを修正

  • 修正前
struct Card {
    enum Suit: String {
        case spade = "♠︎"
        case heart = "❤︎"
        case club = "♣︎"
        case diamond = "♦︎"
    }

    enum Rank: String {
        case ace = "A"
        case two = "2"
        case three = "3"
        case four = "4"
        case five = "5"
        case six = "6"
        case seven = "7"
        case eight = "8"
        case nine = "9"
        case ten = "10"
        case jack = "J"
        case queen = "Q"
        case king = "K"
    }

    let suit: Suit
    let rank: Rank

    var notation: String {
        return rank.rawValue + suit.rawValue
    }
}
  • 修正後
struct Card {
    enum Suit: String {
        case spade = "♠︎"
        case heart = "❤︎"
        case club = "♣︎"
        case diamond = "♦︎"
    }

    enum Rank: String {
        case ace = "A"
        case two = "2"
        case three = "3"
        case four = "4"
        case five = "5"
        case six = "6"
        case seven = "7"
        case eight = "8"
        case nine = "9"
        case ten = "10"
        case jack = "J"
        case queen = "Q"
        case king = "K"
    }

    let rank: Rank
    let suit: Suit

    var notation: String {
        return rank.rawValue + suit.rawValue
    }
}

rankとsuitの順番を入れ替えることで初期化の順番の整合性がとれ、テストが成功します。

3. 不要なテストケースを削除

  • notationが期待通りの文字列を返却できれば、Cardの初期化とrankとsuitが期待通りにインスタンスに保持されることが担保されるため、testInitializeCard()を削除する。

  • 削除前

class Practice_TDD_PokerTests: XCTestCase {
    func testInitializeCard() {
        var card: Card

        card = Card(rank: .three, suit: .heart)
        XCTAssertEqual(card.rank, .three)
        XCTAssertEqual(card.suit, .heart)

        card = Card(rank: .jack, suit: .spade)
        XCTAssertEqual(card.rank, .jack)
        XCTAssertEqual(card.suit, .spade)
    }

    func testCardNotation() {
        var card: Card

        card = Card(rank: .three, suit: .heart)
        XCTAssertEqual(card.notation, "3❤︎")

        card = Card(rank: .jack, suit: .spade)
        XCTAssertEqual(card.notation, "J♠︎")
    }
}
  • 削除後
class Practice_TDD_PokerTests: XCTestCase {
    func testCardNotation() {
        var card: Card

        card = Card(rank: .three, suit: .heart)
        XCTAssertEqual(card.notation, "3❤︎")

        card = Card(rank: .jack, suit: .spade)
        XCTAssertEqual(card.notation, "J♠︎")
    }
}

これで、不要なテストコードの削除は完了です。

GitHub

https://github.com/MasakatsuTagishi/Practice-TDD-Poker/tree/step3

参考にしたもの

1.Swiftで書いておぼえるTDD

https://www.amazon.co.jp/Swiftで書いておぼえるTDD-技術書典シリーズ(NextPublishing)-田中-賢治/dp/484439858X

さいごに

実際に業務で追加機能を実装をしたときに、コードを読み解くだけでものすごい時間がかかりました。
その経験からメンテナンスのしやすさというのは、後々の改修に大きな影響を与えるものだと思っています。
今回、TDDの入門ですが、とてもワクワクしながら勉強しています。
初期化の順序については、個人開発では見逃してしまいそうになるので、細かいところまで気配りできるようにならないといけないと感じました。
また、不要なコードもついつい残してしまうことがあるので、必要のないコードは削除し、常に見やすいコードをかくことを意識したいです。
間違いや認識違いがあれば指摘いただければ幸いです。

Discussion