これは何?
名著として名高いKent Beckの「テスト駆動開発」の新訳版の訳者t_wadaさんは、この本は写経すべしと説いています。教えに従って写経をしてみたい。悟りを開いてみたい。みたいんだけど、それ以前にIDEのインストールで躓いてにっちもさっちも・・・という初心者向けのガイドです。そういう勉強会を社内でやったんですわ。
IDEは素晴らしいものなんで、そのうちそっちも勉強してください。
Macを対象にしています。その他の環境では何がどのぐらい違うのかよくわかりませんけど、だいたい大筋で同じでどうにかなるんじゃないのかなあ。
準備
使うものは以下
- GitHub(または、GitHub Enterprise)
- Git
- JDK
- Gradle
以下の準備をしておいてください。
- GitHubのアカウントをとって、SSHのKeyを登録します。
- Git, JDK, Gradleをインストールします。
やり方は調べましょう。Qiitaにもいっぱいガイドがあるはずです。触ったことがない?。一応、その前提で以下、書いていきますが、ググれば大丈夫。
リポジトリの作成
GitHubで、新しいリポジトリを作りましょう。どんな名前にするのかは自由。そう、自由です。
出来たら、リポジトリをクローンするための情報を入手しておきましょう。
クローン
GitHubで作ったリポジトリを自分のPCへ持ってきましょう。 好きなディレクトリで実行して構いません。
> git clone git@github.ibm.com:TAMBARA/tdd_study.git
Cloning into 'tdd_study'...
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (3/3), done.
tdd_studyというディレクトリが出来ているので、中を見てみましょう。
> ls -la
total 8
drwxr-xr-x 4 tambara staff 128 3 12 17:38 .
drwxr-xr-x+ 109 tambara staff 3488 3 12 17:38 ..
drwxr-xr-x 10 tambara staff 320 3 12 17:38 .git
-rw-r--r-- 1 tambara staff 61 3 12 17:38 README.md
README.mdはGitHubさんが作ったものです。.gitはGitさんが使う情報です。他にはなにもなし。
Gitさんのご機嫌を伺っておきますか。
> git status
On branch master
Your branch is up to date with 'origin/master'.
nothing to commit, working tree clean
何も変更が加えられていないと、こんな感じです。
Gradle init
何にもないとどこに何を作ったら良いのか、不安になります。なので、オススメ構成を作って貰いましょう。Gradleがいろいろよろしくやってくれます。では、初期構成を作って貰いましょう。
> gradle init
Starting a Gradle Daemon (subsequent builds will be faster)
Select type of project to generate:
1: basic
2: application
3: library
4: Gradle plugin
Enter selection (default: basic) [1..4] 2
Select implementation language:
1: C++
2: Groovy
3: Java
4: Kotlin
5: Swift
Enter selection (default: Java) [1..5] 3
Select build script DSL:
1: Groovy
2: Kotlin
Enter selection (default: Groovy) [1..2] 1
Select test framework:
1: JUnit 4
2: TestNG
3: Spock
4: JUnit Jupiter
Enter selection (default: JUnit 4) [1..4] 4
Project name (default: tdd_study):
Source package (default: tdd_study):
> Task :init
Get more help with your project: https://docs.gradle.org/6.2.2/userguide/tutorial_java_projects.html
BUILD SUCCESSFUL in 3m 3s
2 actionable tasks: 2 executed
注意点です。
- type of projectはapplicationを選びます。basicにすると、何も作ってくれません。
- test frameworkはJUnit Jupiterを選びます。本に合わせるためです。
- Project nameは、ホントは本に合わせてmoneyにすべきだったんですが、間違えました。まあ、いいでしょう。
では、何が作られたのか確認してみましょう。
> ls -la
total 64
drwxr-xr-x 13 tambara staff 416 3 12 18:00 .
drwxr-xr-x+ 109 tambara staff 3488 3 12 17:38 ..
drwxr-xr-x 10 tambara staff 320 3 12 17:53 .git
-rw-r--r-- 1 tambara staff 154 3 12 18:00 .gitattributes
-rw-r--r-- 1 tambara staff 103 3 12 18:00 .gitignore
drwxr-xr-x 6 tambara staff 192 3 12 17:57 .gradle
-rw-r--r-- 1 tambara staff 61 3 12 17:38 README.md
-rw-r--r-- 1 tambara staff 1156 3 12 18:00 build.gradle
drwxr-xr-x 3 tambara staff 96 3 12 17:57 gradle
-rwxr-xr-x 1 tambara staff 5764 3 12 17:57 gradlew
-rw-r--r-- 1 tambara staff 3056 3 12 17:57 gradlew.bat
-rw-r--r-- 1 tambara staff 358 3 12 18:00 settings.gradle
drwxr-xr-x 4 tambara staff 128 3 12 18:00 src
いっぱい作られていますが、gradleという単語が含まれたファイルやディレクトリはすべてGradleさんのためのものなので、今は気にしなくて良いです。ということは、srcというディレクトリだけですね。これはsourceの略なんで、ここにソースコードを置けや、ということです。
最初のコミット
やたらファイルが増えましたが、このことについてGitさんはどうお考えか、伺っておきましょう。
> git status
On branch master
Your branch is up to date with 'origin/master'.
Untracked files:
(use "git add <file>..." to include in what will be committed)
.gitattributes
.gitignore
build.gradle
gradle/
gradlew
gradlew.bat
settings.gradle
src/
nothing added to commit but untracked files present (use "git add" to track)
なんか、知らんファイルが増えてるけど気にしなあかんのん?という感じのようです。git add
して気にして貰いましょう。とりあえず、全部。
> git add --all
さて、ご気分は変化されたでしょうか。
> git status
On branch master
Your branch is up to date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: .gitattributes
new file: .gitignore
new file: build.gradle
new file: gradle/wrapper/gradle-wrapper.jar
new file: gradle/wrapper/gradle-wrapper.properties
new file: gradlew
new file: gradlew.bat
new file: settings.gradle
new file: src/main/java/tdd_study/App.java
new file: src/test/java/tdd_study/AppTest.java
コミットする気まんまんですね。コミットしましょう。コミットメッセージはちゃんと書きましょう。
> git commit -m 'gradle initしただけ'
[master c22d029] gradle initしただけ
10 files changed, 382 insertions(+)
create mode 100644 .gitattributes
create mode 100644 .gitignore
create mode 100644 build.gradle
create mode 100644 gradle/wrapper/gradle-wrapper.jar
create mode 100644 gradle/wrapper/gradle-wrapper.properties
create mode 100755 gradlew
create mode 100644 gradlew.bat
create mode 100644 settings.gradle
create mode 100644 src/main/java/tdd_study/App.java
create mode 100644 src/test/java/tdd_study/AppTest.java
Gitさんもすっきりした面持ちです。
> git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)
nothing to commit, working tree clean
いよいよテスト
初めてのテスト実行はコンパイルエラー
さて、いよいよソースコードを触っていきましょう。Finderでファイル構成を確認してみましょうか。
> open .
とすると、Finderが開きます。
srcディレクトリの下はこんな感じになってるんですね。ご想像の通り、mainの下にアプリケーションのコードを、testの下にテストのコードを書きます。
「テスト駆動開発」の1章を見ながら、テストコードを書いていきましょう。AppTest.javaをMoneyTest.javaに名前を変えて、本の通りに編集します。
出だしのpackage
のところだけ、本と違うことになっちゃってますが、ここは目をつむって下さい。さっき間違えたところです。
テストがかけたから、実行しましょう。テストの実行はgradle test
です。
> gradle test
> Task :compileTestJava FAILED
/Users/tambara/tdd_study/src/test/java/tdd_study/MoneyTest.java:9: エラー: シンボルを見つけられません
Dollar five = new Dollar(5);
^
シンボル: クラス Dollar
場所: クラス MoneyTest
/Users/tambara/tdd_study/src/test/java/tdd_study/MoneyTest.java:9: エラー: シンボルを見つけられません
Dollar five = new Dollar(5);
^
シンボル: クラス Dollar
場所: クラス MoneyTest
エラー2個
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':compileTestJava'.
> Compilation failed; see the compiler error output for details.
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Get more help at https://help.gradle.org
BUILD FAILED in 18s
2 actionable tasks: 2 executed
いろいろ怒られているようで怯みますが、臆することなく眺めてください。compileTestJava FAILED
と書いているからには、コンパイルが通らなかったようです。Doller
クラスってなんやねんと言われているようです。いや、こっちも知らんし。テストしか書いてないので、当然ですね。
テストは実行されたけど、失敗している
コンパイルエラーではテストができません。今度はApp.javaをDollar.javaに書き換えて、本の通りに編集しましょう。なんせ写経ですから。
Dollar
クラスの定義ができました。中身はカラっぽですけど。さあ、テストだ。
> gradle test
> Task :test
MoneyTest > testMultiplication() FAILED
org.opentest4j.AssertionFailedError at MoneyTest.java:11
1 test completed, 1 failed
> Task :test FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':test'.
> There were failing tests. See the report at: file:///Users/tambara/tdd_study/build/reports/tests/test/index.html
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Get more help at https://help.gradle.org
BUILD FAILED in 5s
3 actionable tasks: 3 executed
test FAILED
と出ていますが、気を落とす必要はありません。今度はテストが実行されたのだから大きな前進です。というか、Dollar
クラスの中身が空っぽなのに、テストが成功したらヤバいです。ちゃんとテストが失敗するのを確認するのが大事です。
そういえば、ここにレポートが出ているよ、と書いてありますね。file:///Users/tambara/tdd_study/build/reports/tests/test/index.html
をブラウザで表示してみましょう。
赤い。赤いね。これが、テストがレッドだという状態です。
ついにテストが成功
では、本に従ってコードを直しましょう。
どう考えてもこの修正で良いわけないんですが、テストを通過させるにはこれで十分。この後の展開は本をじっくり楽しんで下さい。
> gradle test
BUILD SUCCESSFUL in 2s
3 actionable tasks: 2 executed, 1 up-to-date
そっけないですが、どうやらテストが成功したようです。レポートファイルも見てみましょう。
コンディション・グリーンでございます。
プッシュ
では、ここまでの成果をコミットしましょう。まず、Gitさんのご機嫌を伺います。
> git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
deleted: src/main/java/tdd_study/App.java
deleted: src/test/java/tdd_study/AppTest.java
Untracked files:
(use "git add <file>..." to include in what will be committed)
.DS_Store
src/.DS_Store
src/main/.DS_Store
src/main/java/.DS_Store
src/main/java/tdd_study/Dollar.java
src/test/.DS_Store
src/test/java/.DS_Store
src/test/java/tdd_study/MoneyTest.java
no changes added to commit (use "git add" and/or "git commit -a")
なんか作った覚えのない.DS_Store
というファイルがたくさんあって目障りですな・・・。これが何なのかは調べて貰うとして、これはコミットする必要はありません。Gitさんに気にして貰う必要もない。そういうファイルは、.gitignoreに書いておく決まりになっています。末尾に1行足しておきましょう。
> vi .gitignore
> cat .gitignore
# Ignore Gradle project-specific cache directory
.gradle
# Ignore Gradle build output directory
build
.DS_Store
Gitさんのご機嫌はいかがでしょうか。
> git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: .gitignore
deleted: src/main/java/tdd_study/App.java
deleted: src/test/java/tdd_study/AppTest.java
Untracked files:
(use "git add <file>..." to include in what will be committed)
src/main/java/tdd_study/Dollar.java
src/test/java/tdd_study/MoneyTest.java
no changes added to commit (use "git add" and/or "git commit -a")
自動で作られたApp.javaとAppTest.javaがなくなって、Dollar.javaとMoneyTest.javaが増えました。そうそう、.gitignoreの変更も上がってますね。では、addして、commitしましょう。
> git add --all
> git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: .gitignore
deleted: src/main/java/tdd_study/App.java
new file: src/main/java/tdd_study/Dollar.java
deleted: src/test/java/tdd_study/AppTest.java
new file: src/test/java/tdd_study/MoneyTest.java
> git commit -m '1章 最初のグリーンがでたところ'
[master f4c8b07] 1章 最初のグリーンがでたところ
5 files changed, 24 insertions(+), 28 deletions(-)
delete mode 100644 src/main/java/tdd_study/App.java
create mode 100644 src/main/java/tdd_study/Dollar.java
delete mode 100644 src/test/java/tdd_study/AppTest.java
create mode 100644 src/test/java/tdd_study/MoneyTest.java
さて、ここまでは自分のPCの中の話。このコミットをGitHubに送ると、チームのメンバーにアドバイスも貰えるというもの。そのためには、プッシュをします。
> git push
Enumerating objects: 34, done.
Counting objects: 100% (34/34), done.
Delta compression using up to 4 threads
Compressing objects: 100% (20/20), done.
Writing objects: 100% (33/33), 58.37 KiB | 6.49 MiB/s, done.
Total 33 (delta 2), reused 0 (delta 0)
remote: Resolving deltas: 100% (2/2), done.
remote: detect-secrets-stream (beta) ver=164-1ac7e673b9acf31ed1ba86a8422cf59cb8a848be FAQ: https://ibm.biz/detect-secrets-stream-faq
remote:
remote: Successfully send push metadata.
remote: Push info collect pre-receive hook finished within 3 seconds.
To github.ibm.com:TAMBARA/tdd_study.git
47be568..f4c8b07 master -> master
これでGitHubからでも自分の作ったファイルが参照できます。
自分の書いたコードを見られるのはこっぱずかしいですが、見られないと上達しません。キリのよいタイミングでプッシュしましょう。
それでは、「テスト駆動開発」の写経を完走できることをお祈りしております。チャオ。