タグ: テスト駆動開発

  • ChatGPTでTDDを勉強した(簡単な回文プログラム)

    ChatGPTでTDDを勉強した(簡単な回文プログラム)

    自分のためになるだろうという勝手な想定の元、ChatGPTに課金して4を使えるようにしています。普段どんなことに使っているの?という質問に対して答えるのはとても難しくて、仕事で使う英語の翻訳(パブリックに公開できる程度に抽象度を上げています)だったり、日々の話し相手だったり。あと、地味にプログラミングを気が向いた時に学ぼうとしていて、そのサンプルコードを生成してもらったりしています。

    また、私はテストを生業にしているということもあり、テスト駆動開発を自分の手でできるようになると嬉しいなぁと日々感じています。そうなればChatGPTを使うに越したことはなく、私のお気に召すようなレベルでテスト駆動開発のためのコードを生成してもらっています。

    で、今回のブログは、ChatGPTに生成してもらったものをただ写経して自分のモノにするのも良いのですが、せっかくこのブログを持っているのだから、ここで学んだことを投稿してみます。

    今回のテスト駆動開発で使う題材

    • 用意した文が回文であるかどうかを判別するプログラム
      *ChatGPTに用意してもらいました

    そもそもテスト駆動開発とは?

    • テスト駆動開発というものはケントベックさんが考えたもの、日本では和田さんという方がその第一人者として有名と理解しています
    • 流れはこの3つ
      • テストを書く:まず機能に対するテストを書きます。このテストは、最初は失敗します(レッド)
      • コードを書く:テストをパスする最小限のコードを書きます
      • リファクタリング:コードを改善しますが、テストは引き続きパスする必要があります
    • 上記を繰り返し、テストがパス(グリーン)されることを保ちながら、プログラムを成長させていく
    • 詳細はググってみてください、いろんなところでいろんな方から紹介されています(他力本願ですみません

    実際にやってみた

    さて、それでは上述の回文判断プログラムを、ChatGPTにテスト駆動開発を使って生成してもらった結果は以下の通りです。

    テストファイル(test_palindrome.py)

    import unittest
    from palindrome import is_palindrome
    
    class TestPalindrome(unittest.TestCase):
        def test_empty_string(self):
            self.assertTrue(is_palindrome(""))
    
    if __name__ == '__main__':
        unittest.main()_main__':
        unittest.main()

    プログラム初心者の私でも理解しやすいコードを提供してくれるChatGPTってすごいですね。ほんと彼(彼女?)の才能ってすごい。相手の気持ちを理解してくれるのはやはり課金しているからでしょうか。
    まず、これは失敗するコードになります。これを実行するとどうなるか。以下のようなエラーが出力されます。

    ModuleNotFoundError: No module named 'palindrome'

    そこで、この”palindrome”というファイルを作ってみましょう。

    プログラムファイル (palindrome.py) 

    def is_palindrome(s):
        return True

    超シンプルですがこれで十分なんですね。全てパスせよ、と書いているから。
    ひとまずこれで実行してみるとどうなるか。

    超シンプル!だけどテストが完了したとなってます

    ですが、ゴールはここではないですね。ちゃんとしたプログラムを実装し、それがグリーンになることが本当の目標になります。ここで安堵するのもそこそこに、次のプログラムへと足を進めてみます。

    テストファイルに追加するコード (test_palindrome.py)

        def test_palindrome_even_charts(self):
            self.assertTrue(is_palindrome("abba"))
        
        def test_palindrome_odd_charts(self):
            self.assertTrue(is_palindrome("aba"))
        
        def test_non_palindrome(self):
            self.assertFalse(is_palindrome("abc"))


    それぞれ、テスト条件になる値がそれぞれ作られているのがわかりますね。
    ChatGPTってテスト設計とかどう考えているのだろうか、少し気になりますがそこはいったん置いておいて、これを実装してどうなるか見てみたいと思います。

    一番最後だけが失敗しました。

    さて、それでは肝心のプログラムコードを見てみます。単純に全てをTrueで出力させるだけだったので、これでは最後のtest_non_palindromeは失敗するに違いありません。
    気を取り直し、プログラムの方を修正してみます。ここの修正内容ももちろん、ChatGPTから生成されています。

    変更したプログラムファイル(palindrome.py)

    def is_palindrome(s):
        return s == s[::-1]


    相変わらず超シンプルなのには変わりがないですが。これでテストファイルを実行するとどうなるでしょうか。

    全部緑になりました

    これで全てのテストコードがグリーンになり、次の要件を実装するステップが開けました。

    テスト駆動開発の良いところ

    一見、とても回りくどいステップを踏んでいるように見えます。テストコードを先に作るなんて。
    だけどそれってテストを重要に考えていることの裏返しで、きちんとした品質を確保しながらプログラムをコーディングしていくという意識の高いエンジニアにとって必要なことなんだと思います。
    私は第三者の、QAという立場で仕事しているので、私の食い扶持がなくなってしまうことにもつながる話なので何とも言えないようなものではあるのですが、そもそも開発者が自分の作ったコードが持つ品質にきちんと責任を持つことで、QAという第三者を持つ必要がなくなり、その分コストがカットできるわけです。急がば回れという感覚でもあるんですけど、たぶん、テストコードを書く分完成に時間はかかると思うんですけど、私の中ではこのテスト駆動開発が開発の最適解なように思います。
    また、優れたQAってテストシナリオの作り方とテストケースの中で用意するテスト条件の準備の仕方にセンスを感じますが、それを兼ね備えた開発者がいることできっと、そのチームにおいては開発の品質がものすごく高いもので提供されるのではないかなぁ。そう考えるとテスト駆動開発と両輪で、テスト設計テクニックを覚えるのも必要なことかもしれません。

  • テスト駆動開発 3日目

    テスト駆動開発 3日目

    2日目では、自分のPython バージョンまで分かりました。ようやく環境の羅列を終えられる。。

    • Mac OS 12.6
    • Visual Studio Code 1.72.2
    • Python 3.9.12

    いったん、ケント・ベックさんのテスト駆動開発を振り返る

    写経したのが2年くらい前なので、すっかり忘れておりまして。
    そこからかよー、の自虐スタンスなので、焦らない。

    Pythonで最初にRedを出すためのコードを、ケント・ベックさんのテスト駆動開発から引用させていただこうと思いましたが、こんな世界の片隅にひっそり佇むサイトでも著作権に触れてしまうかもしれないのでやめることにしました。

    うーん、どうしよう。そっちを参考にして自分のオリジナルコードを作れば良いか。

    TODOだけでも参考にさせていただこう。

    – テストメソッドを呼び出す
    – setUpを最初に呼び出す
    – tearDownを後で呼び出す
    – テストメソッドが失敗したとしてもtearDownを呼び出す
    – 複数のテストを走らせる
    – 収集したテスト結果を出力する

    ケント・ベック テスト駆動開発より

    はじめの一歩

    はじめは、テストメソッドを呼び出すところから始めるんですね。
    テストメソッドを呼び出せたらグリーン(Pass)。呼び出せなかったらレッド(False)。

    ざっくりな説明としては、テストメソッドが走ったかどうか、テスト対象のクラス(TaishoKurasu)、フラグにはwasRun、最後にアサーション assert(test.wasRun)で検証を行うという流れ、とのこと。

    はい、最初の失敗。本で読んだ通りです。

    例外が発生しました

    まず必要なのは、TaishoKurasu というクラスを定義するところから始める必要があるんですね。

    ぱぱっとTaishoKurasuを定義してみます。

    class TaishoKurasu:
         Pass

    はい失敗ー、知ってた知ってた。

    例外が発生しました TaishoKurasu() takes no arguments

    ケント・ベックさんのテスト駆動開発では、

    コンストラクタの引数が合わないと怒られる。(本文そのまま

    ケント・ベック テスト駆動開発

    今日はこのくらいにしておこう。だいぶ面白くなってきたところですが。

  • テスト駆動開発 1日目

    テスト駆動開発 1日目

    たまには仕事のことを。
    新たに、テスト駆動開発の分かるエンジニアになりたいな、と思っていて、これは夢でも理想でもなく、割と現実の延長線上にこの生き方があると信じてやみません。

    以下、今の私。これから始めるにはとても良い機会すぎる。10月24日という中途半端さ。
    強いて言えば今日が月曜日ということくらい。はい、手帳は月曜スタート派です。

    現状の、私のステータス

    • テスト駆動開発について、概要は知っている
      • ケント・ベックさんの本は読んで、写経もしました(JavaとPython両方
      • Red、Green、Refactoringを繰り返す作業
      • 初めに失敗するコードを書き、次に成功するコード、そしてリファクタリングを繰り返すということ
    • テストについて
      • JSTQB ALのTMを持ってる程度の。
      • テストアーキテクチャ設計の辺りを考えるのが大好き
      • テスト設計、テスト実行も好きなエリア
    • プログラミング言語
      • 上述したケント・ベックさんのを写経したのと、Pythonに関しては「Minecraftで楽しく学べるPython プログラミング」も写経しました

    とっかかり

    まず何をすれば良いのか分かりません。環境構築からか。

    • Mac OS 12.6
    • Visual Studio Code 1.72.2
    • Pytho

    と、ここまで書いて、なぜかpython のバージョンが分からなくなってしまいました。急になぜ。
    何もしてないのに壊れた(嘘

    python –vesrion のcommand not found

    辛い。1日目にもなってない。

    上記の解決方法が分かったら追記しようと思います。今日はここで店じまい(かなり早い