SlideShare una empresa de Scribd logo
1 de 62
Descargar para leer sin conexión
TDD Boot Camp

古川 剛啓
http://www.flickr.com/photos/utest/5609991407
アジェンダ
1. TDD概論
2. ワークショップ1(Fizz Buzz)
3. 振り返り
注意事項
•

今日は学びの場です。納期とかコストとか関係
ありません。気楽に行きましょう。

•

失敗しても問題ありません。失敗から学ぶこと
は多々あります。どんどん失敗しましょう。

•

何か1つでも持って帰って貰えたら嬉しいです。
プロジェクト終盤でありがちな状況

✓単体テストを省略した
✓いつの間にかテストが壊れている
✓ テストが直ぐ壊れるのでテストするのを
やめた

✓ テストに時間が掛かるのでテストしてな
い

✓そもそもユニットテストなんかしてない
http://www.flickr.com/photos/bagger2009/3630270346
http://www.flickr.com/photos/eivindw/2062037429
http://www.flickr.com/photos/edgarallanbro/7197914274

設計にセーフティネットを掛ける
よく見るV字モデル
要件定義

受入試験

基本設計

システム試験

詳細設計

結合試験

ユニットテスト /
コーディング

ここでやる。
対象はメソッド。
TDDの利点
• テストカバレッジが向上する
• テスタビリティが向上する
• メソッドや構造をシンプルに保つことが出来る
• 書いたコードに自信が持てる
• テストメソッドを読めばメソッドの使い方が分かる
• その他 Twitter #TDDやっててよかったのまとめ
http://togetter.com/li/258537

等
TDDの欠点
• コードを書くのに時間が掛る
• 簡単ではない
• 設計しなくなる

http://www.flickr.com/photos/ismarbadzic/7250079044/
ユニットテストを難しくする幾つかのこと

✓ コードがハードウェアに依存している
✓ データベースやらネットワークに
アクセスして状態が安定しない

✓ クラス間の結合が強くて連鎖的に
インスタンス化する必要がある

✓ GUIばっか
http://www.flickr.com/photos/tcrazyfish/6864732291
http://www.flickr.com/photos/planetschwa/99535218
SOLIDを意識する
S Single Responsibility Principle
単一責任の原則
O Open-Closed Principle
オープン・クローズドの原則
L Liskov Substitution Principle
リスコフの置換原則
I Interface Segregation Principle
インターフェース分離の原則
D Dependency Inversion Principle
依存関係逆転の原則
ちゃんとレイヤー化する
薄く保つ
GUI等

ユーザーインターフェース層
(又はプレゼンテーション層)

ドメイン層
(又はモデル層)

インフラストラクチャ層

デバイスへのI/F等
DB

HDD
TDDをやると本当は何がいいの?

http://www.flickr.com/photos/mikedefiant/429402831
今までのプログラミング
(Debug Later Programming)
Td

Tfind

Tfix
時間

バグ混入

バグ顕在化

バグ発見

バグFix

バグが混入してから顕在化するまでに時間が掛かると、
バグがある場所を探すまでに時間が掛かる
テスト駆動開発
(Test Driven Development)
Td

Tfind

Tfix
時間

バグ混入

バグ顕在化 バグ発見

バグFix

バグ混入から顕在化するまでの時間を短くし、
バグがある場所を探すまでの時間を短縮する
ユニットテストフレームワークを使う
JUnit, Google Test, CppUTest・・・
Mockフレームワークを使う
jMock, GMock・・・

http://www.flickr.com/photos/kazk/198640938
と言うことで・・・
Google Testをインストールしてみよう
• 以下のサイトからGoogle Mockのソースを
ダウンロードする(Google Testのソースも
含まれている)
http://code.google.com/p/googlemock/
• zipファイルを適当な場所に解凍する
• READMEに従って、ビルド&インストール
で、実際に始める前に・・・
テストメソッドの構造
 準備
 オブジェクトの生成や状態のセット等を
行う
 実行
 テスト対象メソッドを実行する
 検証
 実行結果を検証し、Red/Greenを判定
する
 後始末
 オブジェクトを破棄する
テストコードのポイント
 良いユニットテストはRepeatable (繰り返し可能、再現可能)
 テストダブルを使いこなす
 外部環境との界面にインターフェイスを作成し、テストダブルで置き換える
 良いユニットテストは独立 (Independent) していなければならない
 後始末を忘れずに行い、テストを独立させる
 static を避け、テストメソッド間の依存関係を断つ
 Assertion Roulette に注意する
 目指すのは「テストメソッド毎にアサーションひとつ」(しかし、やりすぎは禁物)
 カスタムアサーションを使う
 パラメタライズドテスト(Parameterized Test)を使いこなす
 Fragile Test (脆いテスト) に注意する
 テストだけに使う部分の可視性を下げる
 private メソッドを扱いたくなったら要注意
 テストを設計ツールとして使う
 テストコードのノイズを減らす
 日本語テストメソッドを試してみる
 シンプルなコードとテスト失敗時の情報のバランスを考える
これらのポイントを考えながらテストコードを書くことで、テスト容易性を考慮した設計が見えてく
るはずです。
出展: CodeIQ MAGAZINE
https://codeiq.jp/magazine/2013/11/1475/
準備
(1) 先ずは、テスト対象となるクラス/モジュール
を準備する。
(2) テストクラスを準備する。
(3) ビルドするためのMakefileを書く

ツールを準備しました!!
./prepairFiles [--lang=c | -lang=cpp]
[--target=targetName] [--without_Makefile]
className ・・・
準備
hogeディレクトリ下でコマンドを実行すると以下
のファイルが生成される
(classNameは"fuga")
hoge/
|- src/
| |- Makefile
| |- productionSources.mk
| |- productionObjects.mk
| |- testSources.mk
| |- testObjects.mk
| |- fuga.h
| |- fuga.cpp (fuga.c)
|

|
|- test/
|- fugaTest.h
|- fugaTest.cpp
|- testMain.cpp
準備
fuga.h (c++)

fuga.h (c)

#ifndef FUGA_H_
#define FUGA_H_

#ifndef FUGA_H_
#define FUGA_H_

class fuga {
public:
fuga();
virtual ~fuga();
};

#endif

#endif

fuga.cpp
#include "fuga.h"
fuga::fuga() {
}

fuga::~fuga() {
}

fuga.c
#include "fuga.h"
準備
fugaTest.h (c)
#ifndef FUGATEST_H_
#define FUGATEST_H_

#include <gtest/gtest.h>
extern "C" {
#include "fuga.h"
}
class fugaTest : public ::testing::Test {
protected:
void SetUp();
void TearDown();

public:
fugaTest();
virtual ~fugaTest();
};
#endif
準備
fugaTest.h (c++)
#ifndef FUGATEST_H_
#define FUGATEST_H_

#include <gtest/gtest.h>
#include "fuga.h"
class fugaTest : public ::testing::Test {
protected:
fuga* sut;
void SetUp();
void TearDown();
public:
fugaTest();
virtual ~fugaTest();
};
#endif
準備
fugaTest.cpp
#include "fugaTest.h"
fugaTest::fugaTest() {
}
fugaTest::~fugaTest() {
}
void fugaTest::SetUp() {
sut = new fuga(); // c用には無い
}
void fugaTest::TearDown() {
delete sut; // c用には無い
}
TEST_F (fugaTest, testNameIsHere_ChangeThis) {
/* Write a test code here. */
}
準備
ファイルが生成されたら、srcディレクトリに移動
(cd src)して、

make test
--targetに指定した名前+Testの実行ファイルが
ビルドされる。(デフォルトは、「a.outTest」)

main関数が無いからmakeはできないので注意
よく使うアサーション
2つの値を比較する
致命的なアサーション

致命的ではないアサーション

ASSERT_EQ(expected, actual);EXPECT_EQ(expected, actual);
ASSERT_NE(val1, val2);
EXPECT_NE(val1, val2);
ASSERT_LT(val1, val2);
EXPECT_LT(val1, val2);
ASSERT_LE(val1, val2);
EXPECT_LE(val1, val2);
ASSERT_GT(val1, val2);
EXPECT_GT(val1, val2);
ASSERT_GE(val1, val2);
EXPECT_GE(val1, val2);

致命的なアサーション
ASSERT_STREQ(expected_str, actual_str);
ASSERT_STRNE(str1, str2);

検証内容
expected == actual
val1 != val2
val1 < val2
val1 <= val2
val1 > val2
val1 >= val2

致命的ではないアサーション

検証内容

EXPECT_STREQ(expected_str, actual_str);

2つの C 文字列の内容が等しい

EXPECT_STRNE(str1, str2);

2つの C 文字列の内容が等しくない

ASSERT_STRCASEEQ(expected_str, actual_str);EXPECT_STRCASEEQ(expected_str, actual_str); 大文字小文字を無視した場合,2つの
C 文字列の内容が等しい
ASSERT_STRCASENE(str1, str2);

EXPECT_STRCASENE(str1, str2);

大文字小文字を無視した場合,2つの C 文字列
の内容が等しくない
Google Testの使い方
戻り値がある関数をテストする
テストクラス

関数 f()

関数の戻り値を期待値と比較する

例
EXPECT_EQ(1, Factorial(0));
EXPECT_EQ(1, sut->Factorial(0));

(c)
(c++)

注
• c++のstd::stringは、このアサーションでテストする
• cの文字列は、「ASSERT_STREQ」や「EXPECT_STREQ」等を使用する
Google Testの使い方
変数を更新する関数をテストする
テストクラス

関数 f()

変数の値を期待値と比較する

例
Factorial(0);
EXPECT_EQ(1, result);

(c)

sut->Factorial(0);
EXPECT_EQ(1, sut->getResult());

(c++)

変数 v
よく使うアサーション
明示的な失敗
FAIL();

例外アサーション
致命的なアサーション

致命的ではないアサーション

検証内容

ASSERT_THROW(statement, exception_type);EXPECT_THROW(statement, exception_type); statement が与えられた型の例外を投げる
ASSERT_ANY_THROW(statement);
EXPECT_ANY_THROW(statement);
statement が任意の型の例外を投げる
ASSERT_NO_THROW(statement);
EXPECT_NO_THROW(statement);
statement が例外を投げない
Google Testの使い方
例外がある関数をテストする
テストクラス

関数 f()

例外発生の有無や例外の型を期待値と比較する

例
ASSERT_THROW( sut->parseArguments(argc, argv), std::invalid_argument );

注
このアサーションは例外をキャッチする
依って、try/catchで囲んでも期待する動作をしない
Tips
関数の呼び出しをテストする (c)
テストクラス

関数 f()

関数 g()

関数 g()

関数 f()が、関数 g()を正しく呼び出していることを確認する場合、
• 関数 g()をモックモジュールの関数 g()に置き換える
• モックモジュールの関数 g()で引数の値の保存等、必要な処理
を実施
• アサーションにより保存した値等をチェック
注
• 同じ関数を持つオブジェクトファイルをリンクするとエラー(duplicate symbol)が出るので
プロダクションコードはライブラリにしてモックモジュールより後にリンクする
• テスト対象のモジュールが変わったら、再ビルドが必要かも
Tips
privateメソッドをテストする (c++)
テストクラス

テスト対象クラス
+ 関数 f()
# 関数 g()

△
Spyクラス
+ 関数 g()

privateメソッドをどうしてもテストしたい場合、
• privateメソッドをprotectedメソッドに変更する
• テスト対象クラスを継承するSpyクラスを定義し、その中で
publicに変更した同名のメソッドを定義する
• Spyクラスのメソッドは、元のメソッドを呼び出すだけ
注
• privateメソッドをテストする必要性を検討する必要あり
• privateメソッドは、publicメソッドから呼び出されているので何らかの形でテスト済みなハズ
Tips
標準出力への出力内容をテストする (c/c++)
テストクラス

関数 f()

stdout/stderrへの出力をテストしたい場合、
• Google Testに付属の関数を使用する
• stdoutへの出力を変数に保存する
• stdoutへの出力をファイルに保存する

標準出力
Tips

(Google Testに付属の関数を使用する) (c/c++)
テストクラス

関数 f()

標準出力

#include <gtest/internal/gtest-port.h>

TEST_F(aaaTest, stdoutTest) {
testing::internal::CaptureStdout();
sayHello();
ASSERT_STREQ("Hello", testing::internal::GetCapturedStdout().c_str());
}

CaptureStdout()とGetCapturedStdout()の間は、標準出力に出力
されるはずだった文字列は保存され、 GetCapturedStdout()で取
り出すことができる。

標準エラー出力は、
CaptureStderr()とGetCapturedStderr()を使用する。
Tips

(stdoutへの出力を変数に保存する) (c++)
テストクラス

関数 f()

標準出力

std::string CWorkerSpy::output() {
std::stringbuf buf; // リダイレクト先の変数
std::streambuf* oldbuf = std::cout.rdbuf(&buf); // 標準出力のstreamを保存
CWorker::output();
std::cout.rdbuf(oldbuf); // 標準出力のstreamを復帰
return buf.str();
}

• テスト対象クラスのSpyクラスを定義
• アサーションでテストできるようにstringを返すラッパーメソッドを
定義
• 標準出力のstreamを保存
• 元のメソッドを呼び出す
• 標準出力のstreamを復帰
Tips

(stdoutへの出力をファイルに保存する) (c++)
テストクラス

関数 f()

標準出力

void CWorkerSpy::output() {
std::ofstream ofs("output.txt"); // リダイレクト先のファイル
std::streambuf* oldrdbuf = std::cout.rdbuf(ofs.rdbuf()); // 標準出力のstreamを保存
CWorker::output();
std::cout.rdbuf(oldrdbuf);
}

•
•
•
•
•

テスト対象クラスのSpyクラスを定義
ラッパーメソッドを定義
標準出力のstreamを保存
元のメソッドを呼び出す
標準出力のstreamを復帰
Google Testによるパラメータ化テスト
•パラメータ化テストとは、1つのテストメソッド内でテスト条件(引
数や期待値)を変えながらテストするもの。
•限界値分析や同値分割をやる際に有効

•テストクラスを継承すると共にWithParamInterface<T>を実装
•Tには、テスト対象メソッドの引数の型を指定
::testing::WithParamInterface<T>

△

::testing::Test

△
テストクラス

△
パラメータ化テストクラス
Google Testによるパラメータ化テスト
(引数が1つ)
#include <gtest/gtest.h>
#include "../test/hogeTest.h"
class IsEvenParametricTest : public hogeTest,
public ::testing::WithParamInterface<int> {
};

TEST_Pに変更
#include "IsEvenParametricTest.h"

パラメータを取得

TEST_P (IsEvenParametricTest, testNameIsHere_ChangeThis) {
/* Write a test code here. */
EXPECT_EQ(true, sut->isEven(GetParam()));
}

INSTANTIATE_TEST_CASE_P(EvenTest, IsEvenParametricTest,
testing::Values(2, 4)
);

パラメータを準備
Google Testによるパラメータ化テスト
(複数の引数だったり、戻り値もだったり)
#include <gtest/gtest.h>
#include <boost/tuple/tuple.hpp>
#include "../test/hogeTest.h"

複数のパラメータの場合は
tupleを使用

class IsEvenParametricTest2 : public hogeTest,
public ::testing::WithParamInterface< boost::tuple<bool, int> > {
};

#include "IsEvenParametricTest2.h"

パラメータを取得

TEST_P (IsEvenParametricTest2, testNameIsHere_ChangeThis) {
/* Write a test code here. */
const bool expect = boost::get<0>(GetParam());
const int num
= boost::get<1>(GetParam());
EXPECT_EQ(expect, sut->isEven(num));
}
INSTANTIATE_TEST_CASE_P(EvenTest, IsEvenParametricTest2,
testing::Values(
boost::make_tuple(true, 2),
boost::make_tuple(false, 3))
);

パラメータを準備
Red ー Green ー リファクタリング サイクル

テストメソッドを書く

テストをPassする最低限
のコードを実装する

リファクタリング
例:三角形のチェッククラスを考える
TriangleクラスのcheckTriangleメソッド

• 3辺が等しい三角形、”EqualateralTriangle”を返す
• 2辺が等しい三角形、”IsoscelesTriangle”を返す
• 三角形にならない時、”NotTriangle”を返す
例:三角形のチェッククラスを考える
Step 1
テストメソッド
三辺が同じ長さの時、”EqualateralTriangle”が返される事を確認
する
TEST_F(TriangleTest, AllSidesAreSameLength) {
EXPECT_EQ("EqualateralTriangle", sut->checkTriangle(1,1,1));
}
std::string Triangle::checkTriangle(int a, int b, int c) {
return "EqualateralTriangle";
}
例:三角形のチェッククラスを考える
Step 2
テストメソッド
二辺が同じ長さの時、”IsoscelesTriangle”が返される事を確認す
る
TEST_F(TriangleTest, TwoSidesAreSameLength_rhs_lhs) {
EXPECT_EQ("IsoscelesTriangle", sut->checkTriangle(1,1,2));
}
std::string Triangle::checkTriangle(int a, int b, int c) {
if((a == b) && (b == c) && (c == a)) {
return "EqualateralTriangle";
}
return "IsoscelesTriangle";
}
例:三角形のチェッククラスを考える
Step 3
テストメソッド
三角形にならない時、”NotTriangle”が返される事を確認する
TEST_F(TriangleTest, LhsLengthTooShort) {
EXPECT_EQ("NotTriangle", sut->checkTriangle(1,3,4));
}

std::string Triangle::checkTriangle(int a, int b, int c) {
if((a == b) && (b == c) && (c == a)) {
return "EqualateralTriangle";
}
if(a == b) {
return "IsoscelesTriangle";
}
return "NotTriangle";
}
例:三角形のチェッククラスを考える
Step 4
リファクタリング(引数名の変更)

std::string Triangle::checkTriangle(int lhs, int rhs, int bottom) {
if((lhs == rhs) && (rhs == bottom) && (bottom == lhs)) {
return "EqualateralTriangle";
}
if(lhs == rhs) {
return "IsoscelesTriangle";
}
return "NotTriangle";
}
継続的にTDDをやるための材料
• 単体テストは設計(実装)の一部だと理解する
• 単体テストフレームワークを使用する
• テストコードも構成管理する
• テストカバレッジを「Doneの定義」に含める
• CI (Continuous Integration)サーバを導入する

http://www.flickr.com/photos/roboppy/312248677
最後に
• TDD は簡単なプラクティスではありません。
• しかし、コード品質は確実に向上します。
• 一度や二度の失敗で諦めずに取り組みましょう。

継続は、力なり
http://www.flickr.com/photos/picsbyperi/7457301384
ワークショップのルール
• 先ずは、ペアで自己紹介して下さい。
• ナビゲータとドライバを決めて下さい。

• ナビゲータがテストコードを、
ドライバがプロダクションコードを書いて下さい。
• ナビゲータとドライバは適当に交代して下さい。

• 時間は30分です。
ワークショップ1
FizzBuzzクラス(又は関数)を作る
• 引数が3の倍数の時、”Fizz”を返す
• 引数が5の倍数の時、”Buzz”を返す
• 引数が3と5の公倍数の時、”FizzBuzz”を返す
• それ以外の時、引数の整数を文字列にして返す
ワークショップ2
FizzBuzzを作る
さっき作ったクラス(関数)を使ってFizzBuzzを
作ってください
• 引数は、1~100で
• ディスプレイに表示するように
ワークショップ3
FizzBuzzを作る
さっき作ったFizzBuzzを改修してください
• 出力先をファイルに変更してください。
• ファイル名は任意でOKです。
ワークショップ4
FizzBuzzを作る
さっき改修したFizzBuzzを更に改修してください
• 出力先をファイルだけでなく、ディスプレイにも
表示するように変更してください。

• ファイル名は任意でOKです。
ワークショップ5
FizzBuzzを作る
さっき改修したFizzBuzzを更に改修してください
• 数字はディスプレイに、Fizz、Buzz、及びFizzBuzz
はファイルに出力するようにしてください

• ファイル名は任意でOKです。

Más contenido relacionado

La actualidad más candente

困らない程度のJDK入門
困らない程度のJDK入門困らない程度のJDK入門
困らない程度のJDK入門Yohei Oda
 
fastTextの実装を見てみた
fastTextの実装を見てみたfastTextの実装を見てみた
fastTextの実装を見てみたYoshihiko Shiraki
 
JAVA_HOME/binにあるコマンド、いくつ使っていますか?[JVM関連ツール編](JJUGナイトセミナー「Java解析ツール特集」 発表資料)
JAVA_HOME/binにあるコマンド、いくつ使っていますか?[JVM関連ツール編](JJUGナイトセミナー「Java解析ツール特集」 発表資料)JAVA_HOME/binにあるコマンド、いくつ使っていますか?[JVM関連ツール編](JJUGナイトセミナー「Java解析ツール特集」 発表資料)
JAVA_HOME/binにあるコマンド、いくつ使っていますか?[JVM関連ツール編](JJUGナイトセミナー「Java解析ツール特集」 発表資料)NTT DATA Technology & Innovation
 
マルチコア時代の並列プログラミング
マルチコア時代の並列プログラミングマルチコア時代の並列プログラミング
マルチコア時代の並列プログラミングAkihiko Matuura
 
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)Takeshi Yamamuro
 
Anaconda navigatorのアップデートが終わらないときの対処方法メモ
Anaconda navigatorのアップデートが終わらないときの対処方法メモAnaconda navigatorのアップデートが終わらないときの対処方法メモ
Anaconda navigatorのアップデートが終わらないときの対処方法メモayohe
 
DynamoDBの初心者に伝えたい初めて触るときの勘所
DynamoDBの初心者に伝えたい初めて触るときの勘所DynamoDBの初心者に伝えたい初めて触るときの勘所
DynamoDBの初心者に伝えたい初めて触るときの勘所Ryo Sasaki
 
Quine・難解プログラミングについて
Quine・難解プログラミングについてQuine・難解プログラミングについて
Quine・難解プログラミングについてmametter
 
CTF for ビギナーズ ネットワーク講習資料
CTF for ビギナーズ ネットワーク講習資料CTF for ビギナーズ ネットワーク講習資料
CTF for ビギナーズ ネットワーク講習資料SECCON Beginners
 
Where狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキーWhere狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキーyoku0825
 
PostgreSQLアンチパターン
PostgreSQLアンチパターンPostgreSQLアンチパターン
PostgreSQLアンチパターンSoudai Sone
 
サーバーが完膚なきまでに死んでもMySQLのデータを失わないための表技
サーバーが完膚なきまでに死んでもMySQLのデータを失わないための表技サーバーが完膚なきまでに死んでもMySQLのデータを失わないための表技
サーバーが完膚なきまでに死んでもMySQLのデータを失わないための表技yoku0825
 
あなたの知らないPostgreSQL監視の世界
あなたの知らないPostgreSQL監視の世界あなたの知らないPostgreSQL監視の世界
あなたの知らないPostgreSQL監視の世界Yoshinori Nakanishi
 
Goでかんたんソースコードの静的解析
Goでかんたんソースコードの静的解析Goでかんたんソースコードの静的解析
Goでかんたんソースコードの静的解析Takuya Ueda
 
Djangoフレームワークのユーザーモデルと認証
Djangoフレームワークのユーザーモデルと認証Djangoフレームワークのユーザーモデルと認証
Djangoフレームワークのユーザーモデルと認証Shinya Okano
 
いまさら聞けないパスワードの取り扱い方
いまさら聞けないパスワードの取り扱い方いまさら聞けないパスワードの取り扱い方
いまさら聞けないパスワードの取り扱い方Hiroshi Tokumaru
 
クックパッド春の超絶技巧パンまつり 超絶技巧プログラミング編 資料
クックパッド春の超絶技巧パンまつり 超絶技巧プログラミング編 資料クックパッド春の超絶技巧パンまつり 超絶技巧プログラミング編 資料
クックパッド春の超絶技巧パンまつり 超絶技巧プログラミング編 資料mametter
 
Cache-Oblivious データ構造入門 @DSIRNLP#5
Cache-Oblivious データ構造入門 @DSIRNLP#5Cache-Oblivious データ構造入門 @DSIRNLP#5
Cache-Oblivious データ構造入門 @DSIRNLP#5Takuya Akiba
 

La actualidad más candente (20)

C# 9.0 / .NET 5.0
C# 9.0 / .NET 5.0C# 9.0 / .NET 5.0
C# 9.0 / .NET 5.0
 
困らない程度のJDK入門
困らない程度のJDK入門困らない程度のJDK入門
困らない程度のJDK入門
 
fastTextの実装を見てみた
fastTextの実装を見てみたfastTextの実装を見てみた
fastTextの実装を見てみた
 
JAVA_HOME/binにあるコマンド、いくつ使っていますか?[JVM関連ツール編](JJUGナイトセミナー「Java解析ツール特集」 発表資料)
JAVA_HOME/binにあるコマンド、いくつ使っていますか?[JVM関連ツール編](JJUGナイトセミナー「Java解析ツール特集」 発表資料)JAVA_HOME/binにあるコマンド、いくつ使っていますか?[JVM関連ツール編](JJUGナイトセミナー「Java解析ツール特集」 発表資料)
JAVA_HOME/binにあるコマンド、いくつ使っていますか?[JVM関連ツール編](JJUGナイトセミナー「Java解析ツール特集」 発表資料)
 
マルチコア時代の並列プログラミング
マルチコア時代の並列プログラミングマルチコア時代の並列プログラミング
マルチコア時代の並列プログラミング
 
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
 
Native Memory Tracking
Native Memory TrackingNative Memory Tracking
Native Memory Tracking
 
Anaconda navigatorのアップデートが終わらないときの対処方法メモ
Anaconda navigatorのアップデートが終わらないときの対処方法メモAnaconda navigatorのアップデートが終わらないときの対処方法メモ
Anaconda navigatorのアップデートが終わらないときの対処方法メモ
 
DynamoDBの初心者に伝えたい初めて触るときの勘所
DynamoDBの初心者に伝えたい初めて触るときの勘所DynamoDBの初心者に伝えたい初めて触るときの勘所
DynamoDBの初心者に伝えたい初めて触るときの勘所
 
Quine・難解プログラミングについて
Quine・難解プログラミングについてQuine・難解プログラミングについて
Quine・難解プログラミングについて
 
CTF for ビギナーズ ネットワーク講習資料
CTF for ビギナーズ ネットワーク講習資料CTF for ビギナーズ ネットワーク講習資料
CTF for ビギナーズ ネットワーク講習資料
 
Where狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキーWhere狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキー
 
PostgreSQLアンチパターン
PostgreSQLアンチパターンPostgreSQLアンチパターン
PostgreSQLアンチパターン
 
サーバーが完膚なきまでに死んでもMySQLのデータを失わないための表技
サーバーが完膚なきまでに死んでもMySQLのデータを失わないための表技サーバーが完膚なきまでに死んでもMySQLのデータを失わないための表技
サーバーが完膚なきまでに死んでもMySQLのデータを失わないための表技
 
あなたの知らないPostgreSQL監視の世界
あなたの知らないPostgreSQL監視の世界あなたの知らないPostgreSQL監視の世界
あなたの知らないPostgreSQL監視の世界
 
Goでかんたんソースコードの静的解析
Goでかんたんソースコードの静的解析Goでかんたんソースコードの静的解析
Goでかんたんソースコードの静的解析
 
Djangoフレームワークのユーザーモデルと認証
Djangoフレームワークのユーザーモデルと認証Djangoフレームワークのユーザーモデルと認証
Djangoフレームワークのユーザーモデルと認証
 
いまさら聞けないパスワードの取り扱い方
いまさら聞けないパスワードの取り扱い方いまさら聞けないパスワードの取り扱い方
いまさら聞けないパスワードの取り扱い方
 
クックパッド春の超絶技巧パンまつり 超絶技巧プログラミング編 資料
クックパッド春の超絶技巧パンまつり 超絶技巧プログラミング編 資料クックパッド春の超絶技巧パンまつり 超絶技巧プログラミング編 資料
クックパッド春の超絶技巧パンまつり 超絶技巧プログラミング編 資料
 
Cache-Oblivious データ構造入門 @DSIRNLP#5
Cache-Oblivious データ構造入門 @DSIRNLP#5Cache-Oblivious データ構造入門 @DSIRNLP#5
Cache-Oblivious データ構造入門 @DSIRNLP#5
 

Similar a TDDワークショップ(第2回)

Androidでテストってどないすんねん!
Androidでテストってどないすんねん!Androidでテストってどないすんねん!
Androidでテストってどないすんねん!akimichi Yamada
 
テストゼロからイチに進むための戦略と戦術
テストゼロからイチに進むための戦略と戦術テストゼロからイチに進むための戦略と戦術
テストゼロからイチに進むための戦略と戦術Y Watanabe
 
xUTP Chapter19 (2). Testcase Class
xUTP Chapter19 (2). Testcase ClassxUTP Chapter19 (2). Testcase Class
xUTP Chapter19 (2). Testcase ClassTakuto Wada
 
Ruby初級者向けレッスン 第46回 ─── Test::Unit
Ruby初級者向けレッスン 第46回 ─── Test::UnitRuby初級者向けレッスン 第46回 ─── Test::Unit
Ruby初級者向けレッスン 第46回 ─── Test::Unithigaki
 
テストコードの定型化
テストコードの定型化テストコードの定型化
テストコードの定型化Shinichi Hirauchi
 
タダで始めるテストファースト入門 ~ C# Express + NUnit
タダで始めるテストファースト入門 ~ C# Express + NUnitタダで始めるテストファースト入門 ~ C# Express + NUnit
タダで始めるテストファースト入門 ~ C# Express + NUnitYasuhiko Yamamoto
 
C# から java へのプログラム移植で体験したtddの効果は?
C# から java へのプログラム移植で体験したtddの効果は?C# から java へのプログラム移植で体験したtddの効果は?
C# から java へのプログラム移植で体験したtddの効果は?Shinichi Hirauchi
 
あんなテスト、こんなテスト(this and that about testing)
あんなテスト、こんなテスト(this and that about testing)あんなテスト、こんなテスト(this and that about testing)
あんなテスト、こんなテスト(this and that about testing)Takuya Tsuchida
 
メディア・アートII 第3回 openFrameworks基礎 OOoF : オブジェクト指向 oF
メディア・アートII 第3回 openFrameworks基礎 OOoF : オブジェクト指向 oFメディア・アートII 第3回 openFrameworks基礎 OOoF : オブジェクト指向 oF
メディア・アートII 第3回 openFrameworks基礎 OOoF : オブジェクト指向 oFAtsushi Tadokoro
 

Similar a TDDワークショップ(第2回) (12)

Androidでテストってどないすんねん!
Androidでテストってどないすんねん!Androidでテストってどないすんねん!
Androidでテストってどないすんねん!
 
テストゼロからイチに進むための戦略と戦術
テストゼロからイチに進むための戦略と戦術テストゼロからイチに進むための戦略と戦術
テストゼロからイチに進むための戦略と戦術
 
xUTP Chapter19 (2). Testcase Class
xUTP Chapter19 (2). Testcase ClassxUTP Chapter19 (2). Testcase Class
xUTP Chapter19 (2). Testcase Class
 
Junit4
Junit4Junit4
Junit4
 
Akka Unit Testing
Akka Unit TestingAkka Unit Testing
Akka Unit Testing
 
Ruby初級者向けレッスン 第46回 ─── Test::Unit
Ruby初級者向けレッスン 第46回 ─── Test::UnitRuby初級者向けレッスン 第46回 ─── Test::Unit
Ruby初級者向けレッスン 第46回 ─── Test::Unit
 
テストコードの定型化
テストコードの定型化テストコードの定型化
テストコードの定型化
 
タダで始めるテストファースト入門 ~ C# Express + NUnit
タダで始めるテストファースト入門 ~ C# Express + NUnitタダで始めるテストファースト入門 ~ C# Express + NUnit
タダで始めるテストファースト入門 ~ C# Express + NUnit
 
Spock's world
Spock's worldSpock's world
Spock's world
 
C# から java へのプログラム移植で体験したtddの効果は?
C# から java へのプログラム移植で体験したtddの効果は?C# から java へのプログラム移植で体験したtddの効果は?
C# から java へのプログラム移植で体験したtddの効果は?
 
あんなテスト、こんなテスト(this and that about testing)
あんなテスト、こんなテスト(this and that about testing)あんなテスト、こんなテスト(this and that about testing)
あんなテスト、こんなテスト(this and that about testing)
 
メディア・アートII 第3回 openFrameworks基礎 OOoF : オブジェクト指向 oF
メディア・アートII 第3回 openFrameworks基礎 OOoF : オブジェクト指向 oFメディア・アートII 第3回 openFrameworks基礎 OOoF : オブジェクト指向 oF
メディア・アートII 第3回 openFrameworks基礎 OOoF : オブジェクト指向 oF
 

Más de Yoshihiro Furukawa

Más de Yoshihiro Furukawa (6)

Active learning
Active learningActive learning
Active learning
 
自動化ワークショップ
自動化ワークショップ自動化ワークショップ
自動化ワークショップ
 
Xp祭り2013
Xp祭り2013Xp祭り2013
Xp祭り2013
 
Tddワークショップ
TddワークショップTddワークショップ
Tddワークショップ
 
Agile2013参加報告
Agile2013参加報告Agile2013参加報告
Agile2013参加報告
 
Umlモデリングの勘所
Umlモデリングの勘所Umlモデリングの勘所
Umlモデリングの勘所
 

TDDワークショップ(第2回)