テスターちゃん【4コマ漫画】

ソフトウェアテストの用語、やり方などを4コマ漫画でわかりやすく説明する(予定の)ブログです。脱線も多いです。



ChatGPTを用いたTDD part.4 (Mock編)

ChatGPTを用いたTDD part.4 (Mock編)

ChatGPTを用いたTDD part.3の続きです。

TDDでTODOを行っていきます。

次は、これまで作ったget_time,get_cpu,get_memを入力された文字列に応じて処理をわける部分の実装です。

ここはMockを使ってテストを実装していきます。

 

 

top,cpu,memを判別してそれぞれのデータを返す

top,cpu,memを判別してそれぞれのデータを返す
    文字列の先頭がtopだった場合、topに対応するメソッドを呼び出し戻り値を返す
    文字列の先頭が%Cpu(s)だった場合、cpuに対応するメソッドを呼び出し戻り値を返す
    文字列の先頭がKiB Memだった場合、memに対応するメソッドを呼び出し戻り値を返す

イメージとしては、topが含まれた行を受け取った時はget_timeを呼び出し、cpuが含まれた行を受け取った時はget_cpuを呼び出し、memを含んだ行を受け取った時はget_memを呼び出し、それぞれに応じた戻り値を得るメソッドです。

まずは最初のtopだったときの戻り値を確認するテストコードを書きましょう。

top - 13:52:54 up 6 min,  0 users,  load average: 0.01, 0.07, 0.03

これを受け取った時に期待結果は以下です。

["13:52:54", "00:06"]

 

テストコードを書く

 

以下のプロンプトを与えました。

pythonで、以下のテストデータを与えて戻り値が["13:52:54", "00:06"]であることを確認するテストコードを書いてください。

top - 13:52:54 up 6 min,  0 users,  load average: 0.01, 0.07, 0.03

テスト対象はget_data(string)とします。

またget_time(string)をmockしてください。mockの戻り値は["13:52:54", "00:06"]です。

またget_cpu(string)をmockしてください。mockの戻り値は["16.2", "20.3", "5.0"]です。

またget_mem(string)をmockしてください。mockの戻り値は["2.6\n"]です。

以下importしてください。

from ModuleConvertTop import ConvertTop

テストコードの上部に

from unittest.mock import patch

を足します。

あと、ChatGPTからの出力は以下のようになっていますが、これはこのclassでは動きません。

@patch('ModuleConvertTop.get_time', return_value=["13:52:54", "00:06"])
@patch('ModuleConvertTop.get_cpu', return_value=["16.2", "20.3", "5.0"])
@patch('ModuleConvertTop.get_mem', return_value=["2.6\n"])

classですので以下のようにClass名であるConvertTopを入れる必要があります。

(ファイル名.クラス名.メソッド名のイメージ)

以下のような形です。

@patch('ModuleConvertTop.ConvertTop.get_time', return_value=["13:52:54", "00:06"])
@patch('ModuleConvertTop.ConvertTop.get_cpu', return_value=["16.2", "20.3", "5.0"])
@patch('ModuleConvertTop.ConvertTop.get_mem', return_value=["2.6\n"])

ですので以下のようなテストコードになります。

そしてうっかりしていましたが、mockを全部用意してしまいました。

テストコードはわけるつもりだったのでget_timeだけでよかったです。

いったんこのままでいきます。

 

最初のテスト実行(レッドの状態)

では、テストコードを実行します。

既存の5つはテストが通るはずですが、最後はメソッドがないのでレッドになるはずです。

レッドになりました。

 

最短でグリーンになるコードを実装

では次は最短でグリーンになるコードを書きます。

与えたプロンプトは以下です。

pythonでget_data(string)メソッドを書いてください。
内部にはget_time(string)の呼び出し、get_cpu(string)の呼び出し、get_mem(string)の呼び出しがあります。
ただし戻り値は["13:52:54", "00:06"]固定です。
classのメソッドなのでselfを入れてください。

メソッド部分のみをコードに追加しました

テストを実行してみます。

グリーンとなりました。

詳細の実装

詳細を実装していきます。

入力したプロンプトは以下です。

pythonでget_data(string)メソッドを書いてください。

・入力された文字列の先頭が"top"だった場合はget_time(string)を呼び出して、戻り値をそのまま返してください。

・入力された文字列の先頭が"%Cpu(s)"だった場合はget_cpu(string)を呼び出して、戻り値をそのまま返してください。

・入力された文字列の先頭が"KiB Mem"だった場合はget_mem(string)を呼び出して、戻り値をそのまま返してください。

・入力された文字列の先頭がそれ以外だった場合、[]を返してください。

・classのメソッドなのでselfを入れてください。

パッと見動きそうには見えます。

コードを変更してテストしてみましょう。

一発合格です。(処理がほとんどありませんから)

 

テストコードを追加し、すべてがグリーンになるまでテストを行う

続いて、CPUの場合とMemの場合とそれ以外の場合のテストコードも追加しましょう。

一つずつテストコードを追加してテストをグリーンにしてから、次のテストコード追加に移ります。

まずはCpuからです。

前のコードが間違っていたので、それに付け加える形にしたので間違いが多いコードが出てきてしまいました。

付け加えるテストコードは以下です。

@patch('ModuleConvertTop.ConvertTop.get_cpu', return_value=["16.2", "20.3", "5.0"])
    def test_get_cpu(self, mock_get_cpu):
        test_string = "%Cpu(s):  16.2 us,  20.3 sy,  5.0 ni,63.5 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st"
        result = ConvertTop().get_data(test_string)
        self.assertEqual(result, ["16.2", "20.3", "5.0"])

全てをmock化して進めてもいいですが、get_time側のテストもmockを減らしておきます。

ですので以下のようになります。

テスト実行します。

通りました。

 

-------------------------------------------------------

 

この調子でテストを追加していきます。

テストデータと期待結果を変えるだけなのでコピペで行います。

テストを実行します。

テストはグリーンです。

 

-------------------------------------------------------

 

最後はその他の行が来た時の処理です。

最後はmockを使っていません。

テスト実行します。

テストはグリーンです。

 

-------------------------------------------------------

 

あと、入力が空だった場合の処理のテストコードも追加します。

テスト実行します。

グリーンです。

オールグリーンです。

 

ChatGPTを用いたTDD part.5

に続きます。

testerchan.hatenadiary.com