タグ: TDD

  • JavaでTDDに挑戦してみる(N+1回目

    JavaでTDDに挑戦してみる(N+1回目

    前回の記事はこちら

    参考にさせてもらってるのはこちら


    さて、前回までは、テストケースを作るところまで来ました。
    前回の参照

    No.クラス名ピックアップした数字期待結果
    115, 5, 330FizzBuzz
    215, 545FizzBuzz
    315, 315FizzBuzz
    45, 360Buzz
    51575FizzBuzz
    6510Buzz
    739Fizz
    8上記以外7171
    9111
    10100100100
    FizzBuzz問題の同値分割(1と100を追加、そして期待結果も追加

    さてここで、私はちょっと考えました。

    期待結果が同じものは、省いちゃっても良いんじゃないか説

    どっかで過去に学んだ説

    つまりNo. 1、2、3、5は、一つのケースにまとめてしまっても良いのではないか。
    クラス名のところ、組み合わせが、含まれているからです。

    • No.1は15, 5, 3
    • No.2は15, 5
    • No.3は15, 3
    • No.5は15

    これらが、細かな組み合わせによって出力するという設計になっているのであれば、それぞれ別のケースとして成立させる必要があるような気がしますが、今回はそんな設計にしていない(要件から、3の倍数はFizz、5の倍数はBuzz、15の倍数はFizzBuzzとするだけ)ので、端折っても良いのかなと思います。
    ただ、TDDという観点では、途中でリファクタリングを挟むことが一つのステップになっているので、まずは愚直に上記の10ケースを組んでいきたいと思います。

    No.1 30でFizzBuzzと表示させる

    前回の記事を見るとわかりますが、本プログラムの方では、現状ではまだ「入力した数字をそのまま返す」状態にしかなっていません。

    これで、テストコードのほうを、30を入力したらFizzBuzzと表示させる、のところまで持っていってみたいと思います。

    で、実行した結果がこちら。予想通り失敗しました。30を入力したら、30を出力する、ってプログラムなので当然ですね。

    さて、この赤いバーを、緑に変える必要があります。

    まずはシンプルに、30を入力したら、FizzBuzzを返す、としてみます。

    この上なくシンプルなコード。IF文で、30を入れたらFizzBuzzを返すというコードを追加しました。

    結果はこちら。緑になりました。そりゃそうだ。

    これでNo.1は完了です。

    No.2 45でFizzBuzzと表示させる

    これもNo.1と同様に、45と入れたらFizzBuzzと返すようにするだけですね。

    まずテストコードを先に。

    実行、そしてエラー。ですが、一方で「入れた数字はそのまま返す」という要件のテストができていることを横目に感じつつ。

    では本プログラムの方を修正してみます。No.1と同様に、45をIF文で。

    else if がちょっと増えて、めんどくさいプログラムになってきたなー、と感じます。リファクタリングしたい欲がこうやって増えていくんでしょうか。
    バーはめでたくグリーンに。

    そりゃそうだ。
    まぁ、けど、これでNo.2は終了ですね。

    No.3 15でFizzBuzzと表示させる

    これもまた同様ですね。まず失敗コード、で本プログラムを修正という流れかと思うんですが、さすがにめんどくさくなってきました。ので、ここで、本プログラムの方にリファクタリングをしていきたいと思います。やり方としては、

    1. 現状:30でFizzBuzz、45でFizzBuzzとなっている
    2. リファクタリングの内容:15の倍数を取る場合は、FizzBuzzと表示させる

    こうすることで、本プログラム自体がすっきりするはずです。

    試しに15でFizzBuzzと出力するのを書いてみました。else if が2つ続いてて、しかもreturn がFizzBuzzと同様となっていて、効率的ではないように見えますね。

    まず、テストコードのほうは愚直にやっていく、と宣言した手前、こっちは整理せずに追加すべきだろうと考え、15でFizzBuzzを追加しました。

    そして、本プログラムのほう。
    こちらは、「15で割り切れる場合はFizzBuzzと表示させて」というプログラムにしてみました。

    テストを実行させてみます。見事、緑のバーになりました。

    これで、FizzBuzzと表示させるところは完了したように思います。

  • JavaでTDDに挑戦してみる(n回目

    JavaでTDDに挑戦してみる(n回目

    何度挑戦しているか分からないんですが、相変わらず仕事の切れ目とか、ちょっと落ち着いた時間帯にやったりしています。

    参考にしているのはこちら

    私の現在地

    • Javaはほとんど初心者です。Hello, Java!は書けます
    • テスト駆動開発は、ケントベックさんの本を何度か読みました。そこで写経しつつ、JavaでのTDDを理解しました
    • 使ってるIDEはEclipseです。Javaをなんとか自分のものにしたかったので。
    • QA経験は長いです。キャリア17年とか。テスト駆動開発の良し悪しとか、JSTQBのALTM持ってたりとか。今は事業会社でQAやってます。

    ケントベックさんの本はこちら。JavaとPythonで、TDDについて順を追って書いてあります。プログラムのことがわからなくても、読んでみると新たな発見があるかもしれません。

    テスト駆動開発/KentBeck/和田卓人【3000円以上送料無料】

    価格:3,080円
    (2023/6/2 18:29時点)
    感想(0件)

    どこまで進んでいるか

    上述した、参考にさせてもらってるサイトで、ここまで来ています。
    とりあえず入力値をそのまま返すようプログラムを組み、テストの方は2を入れてそのまま返すところまで。

    FizzBuzz.java
    FizzBuzzTest.java

    次のステップは、3を入れたらFizzと返すところでしょうか。

    FizzBuzz問題のテストを考えてみる

    ちょっとその前に、テストの組み立てを考えてみたいと思います。
    今更ですがFizzBuzz問題の要件はこちら。まだ初心者なので簡略化しています。上述した、参考にさせてもらってるサイトではちゃんとしたものを書いているので、本物を知りたい方はそちらをご参照ください。

    1. 数字は1から100まで。
    2. 3では、Fizzと返す。
    3. 5では、Buzzと返す。
    4. 100では、FizzBuzzと返す。

    さて、テストケースはどうなるか。
    私はここで、同値分割を考えてみたいと思います。同値分割というのは、結果が同じになる範囲をひとまとまり(これを同値クラスと理解しています)にし、そこから適当な値をピックアップするやり方、という理解です。

    • 3の倍数クラス
    • 5の倍数クラス
    • 15の倍数クラス
    • 上記以外

    シンプルに4つ、と言いたいところですが、3、5、15は公倍数があるので(45とか)、そこは15が優先されるというふうに考えると順番が変わるのかなと思います。ここで追加要件として、以下を追加してみたいと思います。

    • 2つ以上の組み合わせで公倍数となる場合は、数字の大きい方を優先する。

    すると、以下のようになります。

    1. 15、5、3の倍数クラス
    2. 15、5の倍数クラス
    3. 15、3の倍数クラス
    4. 5、3の倍数クラス
    5. 15の倍数クラス
    6. 5の倍数クラス
    7. 3の倍数クラス
    8. 上記以外

    さてここで問題が発生しました。
    上記、1と、例えば6では、ピックアップする数字がかぶってしまうことがわかりました。
    例えば、1では15と5と3なので、30を選ぶとしましょう。
    そうすると、6でも、30が選べちゃうわけです。
    こういう時、自分のルールとして、数字の若い方でピックアップされた数字は、選ばないということにしたいと思います。

    さて、それでは数字を選んでみましょう。

    /

    No.クラス名ピックアップした数字
    115, 5, 330
    215, 545
    315, 315
    45, 360
    51575
    6510
    739
    8上記以外71
    FizzBuzz問題の同値分割

    これで十分でしょうか。私の要件であれば、十分なのかもしれないです、が、最初の要件(数字は1から100まで)を忘れていました。
    ここは境界値分析が使えそうです。
    ホントは0と101を加えたいんですが、残念ながら私のJavaスキルでは、どうやってもエラーを期待結果と置くことができなかったので、泣く泣く省略したいと思います。
    なので、シンプルに、1と100を追加したいと思います。

    上記の表に1と100を追加してみます。

    No.クラス名ピックアップした数字期待結果
    115, 5, 330FizzBuzz
    215, 545FizzBuzz
    315, 315FizzBuzz
    45, 360Buzz
    51575FizzBuzz
    6510Buzz
    739Fizz
    8上記以外7171
    9111
    10100100100
    FizzBuzz問題の同値分割(1と100を追加、そして期待結果も追加

    これでようやく、全ケースが揃いました。ほんとは数字とか、全角半角とかもあるかなーと思ったんですが、ここではTDDを体験することが目的なので、上記で十分だろうということにします。

    と思ったんですが、書いてて力尽きました。ここから先はまた改めて。こっからようやくTDDってところなんですけどね。

  • FizzBuzz問題をテスト設計してみる

    FizzBuzz問題をテスト設計してみる

    FizzBuzz問題とは

    FizzBuzz問題は、以下のようなリストになる。めっちゃシンプル。

    • 数字を1から100まで数える。
    • 数字が3の倍数に当たる時は、数字ではなくFizzと返す。
    • 数字が5の倍数に当たる時は、数字ではなくBuzzと返す。
    • 数字が15の倍数に当たる時は、数字ではなくFizzBuzzと返す。
    • 0以下、101以上はエラーを返す。

    テストケースを考えてみる

    数字をテスト条件として与え、期待結果を得るというブラックボックステストを考える時、最小テストケースになるのはどんなパターンになるか。
    私は以下のように考えてみた。が、テストエンジニアとして気になるのは、追加したい箇所として100、-1、Aなど。
    100は正常系、-1やAは例外系として扱われるだろう。

    与えたいテスト条件期待結果
    0エラー
    11
    3Fizz
    5Buzz
    15FizzBuzz
    101エラー
    テスト条件と、期待結果の対照表

    上記の例でいくと、テストケースは6つとなる。
    期待結果で同じ値を取るものとして、エラーが2つ挙げられる。
    これは見方によっては、どちらか一つでも良いかもしれない。
    けれど、境界値を考えた場合、両端に取るべきなので、私は2つにした。
    また、上述したけれど、-1やAなどを追加してみても良いかもしれない。
    それらを追加すると合計で8つになるか。テスト実行時間がそんなにかからないのであれば、テストケースとして加えてみても良いような気がする。

  • テスト駆動開発:テストコードに先立って考えておくテスト設計など

    テスト駆動開発:テストコードに先立って考えておくテスト設計など

    前回の投稿では、FizzBuzz問題を題材として取り上げ、テストコードを使ってテスト駆動開発をするのに挑戦しました。
    テスト駆動開発、私はJavaを習いたてということもあり、まだまだ未知なものだなという印象でした。

    一方、私はテストエンジニアとして長らく従事しているので、FizzBuzz問題ではどのようなテストケースを作れば良いのか、少し頭を悩ませました。
    シンプル且つ、カバレッジの広いものを作るべきだと思うのですが、そこにはテストのパターンをきちんと考えることが必要だと思ったからです。

    Christina Morillo at Pexels

    テストを考える時、プログラムの処理を考える必要があるかどうか

    テストタイプにも依ると思うのですが、例えばFizzBuzz問題で考える時に、

    • 3の倍数はFizzを返す
    • 5の倍数はBuzzを返す

    というものと、

    • 15の倍数はFizzBuzzを返す

    これら、どっちを先に処理するか、プログラマーの頭の中を考える必要があるかな、と思いました。
    というのも、私はJavaでプログラミングした時、後者を先に書きました。
    15の倍数でFizzBuzzを通過するケースの時は、3や5の倍数ではあるけれどそちらは通過してしまうから、考慮しなくても良い、つまりケースとして、テスト条件に45を選んだ時、FizzBuzzを返すこと、は期待結果として設けるべきで、FizzやBuzzを返さないことというものは期待結果として選択しない、ということになります。

    そもそも1つの結果しか返さないこと、というのが仕様として明記されていれば、↑こんな考え方でも良いでしょうけど、「1つの結果しか返さない」という仕様は記載されていない場合は、「結果が1つしか出てこないこと」というのを期待値として挙げておく必要があるのかもしれないです。

    その辺がプログラミング中に分からなくて、ちょっともやもやしました。

    同値クラスで分ける場合

    私がJSTQBで理解した同値クラスというのは、結果のまとまりで見る、ということでした。
    なので、

    • 数字をそのまま返す
    • Fizzを返す
    • Buzzを返す
    • FizzBuzzを返す
    • エラーを返す

    この5つをそれぞれのまとまりと見立て、適当なテスト条件をピックアップすれば良いのか、と思います。

    • 数字をそのまま返す:1、2、99、100
    • Fizzを返す:3、39
    • Buzzを返す:5、20
    • FizzBuzzを返す:15、45
    • エラーを返す:0、101、☆

    FizzBuzz問題で難しいのは、45です。3の倍数でもあるし、5の倍数、15の倍数でもあるような数字です。これはどっかの同値クラスでまとめてテストしちゃうのが手っ取り早いのでしょうけど、Fizzを返すこと、というテストの目的に対して3を入れて正解を見るパターンと、45を入れて不正解を見るパターン、両方やるのが一番カタいのかなぁと思います。
    どっちみち15の同値クラスで45を見るのだから、3の同値クラスでやる必要はないだろう、というのはテストアプローチとして(効率的にやっちゃおうぜ的な考え方)は良いのでしょうけど、いったん全部出してみようぜ、っていう時には忘れずに盛り込んでおくべきだと思います。

  • Java でTDD(FizzBuzz問題)失敗

    Java でTDD(FizzBuzz問題)失敗

    表記、先日こちらのブログでもお伝えした通り自分のJavaプログラミングスキル自体が足りず、結局意味が分からなくて終わりにしました。

    そこからJava入門の本を買って読んだりして、少しずつJavaのことを理解しようとしています。

    本はこちらを購入しました。めちゃくちゃ分厚くて、まだ半分もいけていません。

    スッキリわかるJava入門第3版 [ 中山清喬 ]

    価格:2,860円
    (2022/11/21 15:02時点)
    感想(13件)

    また、こちらのサイトを参考にしながら、ひたすら写経をしています。ほんとこちらの執筆をされた@tentomさんという方に足を向けて眠れないような感覚。

    とはいえ、こちらのサイトで割愛されているところが私には到底難しくて分からず、けどなんとかしようということで、今頑張っているところです。
    そのあたりを、こちらで書いていこうと思います。

    前提

    • Visual Studio をMacにインストールして、そこで書いています
    • Extensionとして、Test Runner for Javaをインストールしています

    とっかかり

    まずは上記で書かれている、2の引数まで通るコードを書きました。
    で、3は数字そのままではなく、Fizzを返す必要があるんですね。

    FizzBuzzTestのほう。引数に3を与えたらFizzを返すところまで含めています
    FizzBuzzのほう。参考にさせてもらってるブログで、2まで通ってるところそのまま
    そのまま通し、怒られているところ。FizzがExpectedなのに3が返ってきてる!と怒られています

    3でFizzが返ってくるようにFizzbuzz.javaを修正する

    ここで、私の少ない知識をフル稼働させ、修正を試みます。

    参考にさせてもらったサイトから、必要と思われているところを抜き出したもの。

    3だけ条件式を作り、それ以外はそのまま、という流れ、ということなのかな、、半分くらい理解できていません。。

    全部通りました。

    次は5

    3に倣い、5でBuzzが返ってくるようなものを作ってみます。

    5のテストコードを追加したところ
    はい、失敗。そりゃそうだ、Buzzが返ってくるようなコードを書いてないんだから。

    ここで、普通に5を条件分岐で追加すれば良いのですが、

    5の条件分岐を通したもの。
    テストも通りました。

    この辺で一度リファクタリングを

    この辺りで、テストコードの方、毎回インスタンスを立ち上げる式を追加していて、これは冗長だなと思われます。

            FizzBuzz fizzbuzz = new FizzBuzz();

    このコードを毎回追加するのではなく、最初にまとめて書けたらいいなぁと思いながら見てると、はい、元のサイトで以下のように追加しているのに気づきました。こういうふうに、立ち上げ時にやるんすね。

    @Beforeとして最初にインスタンスを作るとこだけ切り出して書く
    残念、、全部通らなくなってしまいました。

    何が悪いのか。おそらく、メソッドを先に追加しなかったからなのかな、と。

    今イマ、こんな感じ。@Beforeから始まるところを追加しています。fizzbuzzのところに赤いアンダーラインがあるということは、ここが悪い、ということですね。。

    参照させてもらってるサイトを参考にし、メソッドを追加することにします。

    赤いアンダーラインが消えた!(まだテスト実行はしていません

    早速テストを流してみます。

    全部通りませんでした。。ううーん。メソッドを追加したのは正解ではなかった模様です。
    良く見ると、
    @Before

    のところに赤いアンダーラインが引いてあるんですよね。

    “Before cannot be resolved to a type”とあります。ううーん。
    カーソルを移動していくと、 @Beforeではなく、@BeforeAllの方が良さそう、みたいな提案を受けました。

    再度流しても失敗。

    また怒られて、長い英文が。。読むの辛い。

    これはもう後で考えることにしよう。。コードを元に戻します。

    気を取り直して15を

    テスト用のコードに追加して、本文には15の倍数に関して何も追加しなかったのに、テストが通ってしまった図。

    これはおかしい。3の倍数、5の倍数のところで先に処理しちゃってるから、ここに引っかかるものがなく通過してしまっているような気がします。

    怪しいので最初に15の倍数を通るように処理を
    すると、失敗しました。FizzBuzzを期待したのに、結果はFizzBuzzFizzBuzzと。
    思わず笑ってしまいました。

    多分、3と5の倍数でもあるから、そのせいなのかなと思ったり、、

    試しに、5の倍数でBuzzっていうのを削除して、トライしてみると、

    はいビンゴ、FizzFizzBuzzが返ってきました。

    うーん。3と5を通らずに、15だけできるものは、、

    答えはelse if

    ぱっと思いつきました。そうじゃん、ifを並列に書いてたからダメで、else if を使って分岐させればいいんじゃん、と思いつきました。

    else if を追加して書いたもの
    テストもこの通り。

    ここまできたら大きな山は超えたかな、という気分です。

    0にトライ

    あとは1未満と、101以上を超えたらダメですよ、を、元のサイトを参考にして追加してみます。

    0のテストコードを追加。
    何も変更していないのでエラー。ちなみに0ではFizzBuzzが返ってくるそうです。

    ちなみに0では、なぜFizzBuzzが返ってくるのか。
    以下、条件分岐のところで、最初に15の倍数で当ててるから、そこに0を入れても0になっちゃう、ということでFizzBuzzが返ってくるのかな、と思います。

    今イマの、FizzBuzzのコード。

    num < 1 の時にエラーを返すコードを追加しました。
    うーん、なんか違うって言われました。。

    本日のおさらい

    • FizzBuzz問題という題材を使って、3の倍数、5の倍数、15の倍数でそれぞれ処理させ、テストして内容が正しいことを学びました。
    • 1未満の時にエラー処理をさせたかったのですが、それがうまくコーディングできず、時間切れとなりました。
    • 101以上についても時間が足りず、作成していません。
    • 参照させてもらってるコードで、StringBuilderというパーツ?を使っていて、その内容をきちんと理解せずに使っています。多分、数字を入力する時に使うものなんだと思ってます。
  • ChromeをJavaで起動するコード

    ChromeをJavaで起動するコード

    テスト駆動開発をやってみたくて、Javaを勉強しています。

    テスト対象はWebブラウザを想定しているので、はじめの一歩ということでChromeの起動をすることができたので備忘録を兼ねてコードを。もともとのコードはこちらのサイトを参考にさせていただきました。

    import java.awt.Desktop;
    import java.net.URI;
    
    public class ChromeLaunch {
    	public static void main(String[] args) {
    		String uriString = "https://www.google.com";
    		Desktop desktop = Desktop.getDesktop();
    		try{
    			URI uri = new URI (uriString);
    			desktop.browse(uri);
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    }

    めっちゃシンプル。GoogleのURLのところを適当なものに変えれば、そのサイトを開くことができます。

    上のコードで、私がまだわかってないもの

    • URIの意味。大文字なので、なのかの略語なのかなと思ったりしている
    • catch (Exception e) {
      e.printStackTrace();
      }
      ここで何をしているのか分かっていない。参照させていただいたコードをそのまま写経しただけ。

    私が無知ということを理解しているのは良いですね。そこを学習することで、成長できるということだと思うので。

  • テスト駆動開発 6日目(完結)

    テスト駆動開発 6日目(完結)

    挫折しました。

    こちらのサイトを参考にして進めていたのですが、1と2を返すところまではこの内容通りにできました。
    が、その後が省略されていて、私の力では順を追ってコーディングしていくところが全く分からず、とりあえず写経して終わり。。
    しかもテストが通らず、うーん、ってなって諦めました。私の力不足です。

    失敗しまくってる

    まずはJavaだな、話はそこからだ、うん

  • テスト駆動開発 5日目

    テスト駆動開発 5日目

    前回はPythonでテスト駆動開発をやってみよう、という意気込みで始めて見たのですが、そもそもPythonのことも良く分かっていない状態でいきなりテスト駆動開発に着手したということで、なんともお粗末な結果で終わってしまいました。

    なーんにも分かっていない状態というのは、逆に強かったりしますよね。
    自分が無知であることを知っている、とかの哲学者がおっしゃられていました。
    確かにそうなんですけども。それは自分の器がこれから大きくなっていくぞ、と言う決意の表れとも考えられるかもしれません。

    脱線しました。

    前回まではVisual Studio Codeで、イケてるPythonで、みたいな超絶カタチから入る男の典型として臨みましたが、全くダメだったので、気分を一新、Eclipse + Javaで再トライすることにしました。jUnitのことが書いてあったので。それを使って写経できるサイトが見つかったので。リンクはこちらです。ありがとうございます。

    Pixabay at Pexels

    FizzBuzz 問題をおさらいする

    何よりも私が忘れているからなんだけど、FizzBuzz問題とはどういうものか?それを改めて記載したいと思います。

    • 数を1ずつ増やしていくゲーム
    • 3の倍数が出たらFizz!と叫ぶ
    • 5の倍数が出たらBuzz!と叫ぶ
    • 15の倍数が出たらFizzBuzz!と叫ぶ

    シンプルなゲームですね。

    テストを始める

    最初のステップ

    今回は2つのファイルを作るんですね。早速上記のサイトから写経させていただきました。

    本体のほう
    テストのほう

    そして、jUnitでのテスト結果はこちら。はいはい、赤くなった。よしよし。

    テスト結果

    ちょっと面白くなってきました。

    次のステップ

    次は、強引に緑のバーを出すんですね。はいはい。

    本体のほう、1を返すようにした。ハードコードしてるから気持ち悪い
    実施結果。そりゃそうだ。

    師匠(と勝手に呼ばせていただく)のサイトでは、次に、2を返すテストケースに着手していますね。早速私の方でも追加していこう。

    2のアサーションを追加した
    2がエラーに。

    はいきた、そりゃそうだ。

    今日はここまで。

  • テスト駆動開発 4日目

    テスト駆動開発 4日目

    前回のところで、次のステップを書いたところ、予定通りにAttribute errorが出されました。

    Attribute Error で怒られた

    ちょっと待て

    違う、私がやりたかったのはケント・ベックさんのテスト駆動開発を写経したかったのではなく、Pythonでテスト駆動開発を体験したかったんでした。
    なぜケント・ベックさんのテスト駆動開発を参照したのかというと、テスト駆動開発へのとっかかりを思い出したかったからです。

    気を取り直す

    さて、それでは何の題材に選べば良いのか?とかるーくググったところ、fizzbuzz問題というのがありました。
    というか、とても良い写経の題材がありました。リンクはこちら。

    fizzbuzz問題ってなに?みたいなのはこのリンク先をご参照いただくとして、私の、このブログではテスト駆動開発を進めていきたいとおもいます。

    何は無くともToDoリスト

    最初は、ToDoリストを作るところから。ここから写経になります。

    1. 数を文字列にして返す
      1. 1の時は、1と表示する
      2. 2の時は、2と表示する
    2. 3の倍数はFizzと返す
    3. 5の倍数はBuzzと返す
    4. 3と5の倍数はFizzBuzzと返す

    そしてコード。ここも分からないことだらけですが、いったん写経してみます。ホント、Qiitaで書いてくださった方、感謝です

    import pytest
    
    class TestStringConvert:
        # 前準備
        @pytest.fixture
        def target(self):
            from fizz_buzz import string_convert
            return string_convert
        
        # 検証
        def test_return_value(self, target):
            assert target(1) == '1'

    ドキドキで実行してみると、出たよー見つからないやつー環境変数に追加しないといけないやつー。もう見慣れました。

    pytestはどこだよ!って怒られている

    もう疲れた、、今日はここをキャンプ地とさせていただきます。