なんでテストを書くの?
思ったとおりに動いていることを確認する
ちょっとずつ確認しながら進んでいくとつまらないバグがなくなる。
プロダクトコードの振る舞いのリスト
テストメソッド名で振る舞いを説明する。
テストコードなのでウソの(疑わしい)ドキュメントとならない。
(--testdoxオプション)
実際に動かすことができるサンプル
初めて見る処理に修正を加えないといけなくなった時、
とりあえず動かして何が起こるのか見てみたかったりしない?
手軽に再現可能な動作確認の手段
あるバッチ処理を動かすために・・・
マスターテーブルにデータを入れて、別のバッチでランキングデータを作って(1時間)、ブログの管理ツールから新規の記事を公開して、YAMLファイルをアップロードして、キャッシュが切れるまで1時間待って、ブラウザで現在の記事リストを確認して、バッチプログラムを実行して、記事リストに追加された記事を確認!
動作確認のたびにこれが必要だとしたら・・・?
- ユニットテストでの解決
- モックによって修正対象コードの動作確認に注力
- システムレベルのテストの自動化での解決
- 無駄な待ち時間無しに誰もが実行できるシステムレベルの動作確認手順の作成
- 最初からこれを意識した作りで準備するのが重要
- あとからやろうとするとかなり辛い
- 最初からテストを作っていくことが重要
- 最初からテストを作っていくことが重要
- 無駄な待ち時間無しに誰もが実行できるシステムレベルの動作確認手順の作成
設計に関するスキルの向上
実際のプロダクトコードでは、簡単にテストを書けるケースはあまり多くない。
- シンプルにテストが可能な単位に分割したり
- そもそもテストが可能なように外部依存を切り出したり
といったことをしていくことでスキルの向上につながる。
PHPカンファレンス2012メモ #phpcon2012
気になったところのみ。
基調講演
Composer
RubyでいうBundler的なライブラリ依存管理の仕組み。
Symphony2を始めとして多くのものが対応している。
(というかsymfony2はコンポーザーでインストール!)
「みんな対応している」重要
初心者セッション
いまだからできる、ふつうのはなし Gree
終盤5分くらい聞いた。
古いシステムの改善は、機能毎に区切って(縦に切って)少しずつリプレイスしていくのがいいと思ってたけど、どうもそうではなく、既存のシステムに新たに層を2つくらい積み重ねて(横に追加して)いくことで改善を行うような話だったらしい。
聞きたかった・・・
徳丸本に学ぶ 安全なPHPアプリ開発の鉄則2012
と・と・鳥ランド!
最先端Web開発
アジェンダ見たところ、自社開発フレームワーク(dietcake)の紹介かとおもいきや、プレゼン開始直後のスライドでそのアジェンダに取り消し線が入った!
とてもいい話でした。感動した。
PHPという言語自体のポリシーに通じる部分もあり、とても共感できました。
新しくjoinする人をどのように迎え、どのように育ててゆくか。
フレームワークはシンプルに保つ
Symphonyとか1,2で変わりすぎて学習はやり直し、Doctrineのコードなんか全部ちゃんと読める人などほとんどいない。
フレームワークのコードが現実的に読める内容であること。
「変わらない」ということの価値。
グループプログラミング
ドライバー1、ナビゲータ3 でのペアプロ
join.meというサービスでドライバーの画面をナビゲータの端末で共有
なんと生産性自体は一人の時とそんなに変わらないらしい(4倍近くになってる!?)
Githubでプロジェクトの健全性を測る
コミットの回数とタイミングが統計的に確認できる
→ 夜中土日のコミットが多いとデスマってるなーとなる
Git x Pull Request ~ チーム開発最終奥義
gitのメリット
ローカルでの気軽なコミット、手軽なブランチング、賢くて高速なマージ
リリースを細かく
リニューアルとかの大きな案件でも「○○の構造変更」とかだけでリリース等
こうするとあとでマージが大変とかにならない
featureブランチから更にfeatureブランチを生やす
複数人での機能開発での混乱を少なく
PullRequestを通して必ずレビュー
これを繰り返してメンバーの長所短所など特徴を知ることができる
細かい単位で行うことで、レビューの効率がとても良くなる
どのような要求に対してどのような変更を行ったかが重要であり、そこに対して効果的なレビューが出来る
チームにあったやり方で
KLabさんとか、基本master一本でそこからいくつも細かい開発ブランチ生やすようなシンプルなやり方だし。
Composer による依存管理と Packagist によるライブラリ公開
日本語化頑張り中だそう
https://github.com/kawahara/composer
herokuでbootstrap入れたらActionView::Template::Error ('twitter/bootstrap.less' wasn't found.
twitter bootstrap railsを使ったら職が見つかり彼女も出来て背も3センチ伸びました。
↑が親切すぎたので何も考えずにやってたらherokuでエラーがでてハマった話。
twitter-bootstrap-rails入れてherokuにデプロイしたらエラーが出る
$ git push heroku master $ heroku open $ heroku logs 2012-02-28T12:11:12+00:00 app[web.1]: Completed 500 Internal Server Error in 205ms 2012-02-28T12:11:12+00:00 app[web.1]: 2012-02-28T12:11:12+00:00 app[web.1]: ActionView::Template::Error (couldn't find file 'twitter/bootstrap' 2012-02-28T12:11:12+00:00 app[web.1]: (in /app/app/assets/stylesheets/application.css:6)): 2012-02-28T12:11:12+00:00 app[web.1]: 5: %meta{:charset => "utf-8"}
原因
Gemfileのgroup :assetsに追加します。
- -
cd tbrsample
vim Gemfile
- -
- -
のところで、group :assetsの中じゃなくて外に指定しないといけなかったぽい。
こうじゃなくて
# assets用のgem、デフォルトでは本番で不要となる group :assets do # ・・・ gem 'twitter-bootstrap-rails' end
↓
こう
gem 'twitter-bootstrap-rails' # assets用のgem、デフォルトでは本番で不要となる group :assets do # ・・・ end
herokuにrailsアプリをデプロイする(Error H10 ってなに;;)
railsによるアジャイルWebアプリケーション開発第4版を読んだので早速herokuでアプリでも・・・
と思ったらRubyもrailsも初心者で結構つまづいたのでメモ。
herokuへのサインアップ等は終わってるものとします。
Hello Worldまでは以下が参考になりました。
http://d.hatena.ne.jp/ruedap/20110128/ruby_heroku_sinatra_hello_world
まずはRailsアプリを普通に用意する
memberlist というアプリで、userテーブルを作って、scaffoldでCRUDできるところまで作ります。
アプリ作成
$ mkdir ~/projects/ruby $ cd ~/projects/ruby $ rails new memberlist
scaffold でユーザーテーブルともろもろコード生成
$ cd memberlist $ rails g scaffold user code:string name:string $ rake db:migrate
rootを設定しておく
config/routes.rb
root :to => 'users#index'
$ rm public/index.html
(既にgit initされてる場合は git rm public/index.html)
ローカルで確認
http://localhost:3000/ にアクセスして「Listing users」とか出てればOK。
heroku にデプロイ
git にする
$ git init $ git ci -am "initial commit"
とりあえずデプロイしてみる
heroku create 時にアプリ名を指定することも出来ます。
$ heroku create $ git push heroku master $ heroku rake db:migrate $ heroku open
Application Error となる
ブラウザでherokuのアプリが表示されるがApplication Errorとなっている。
$ heroku logs 2012-06-15T12:08:37+00:00 heroku[router]: Error H10 (App crashed) -> GET morning-sword-1974.heroku.com/ dyno= queue= wait= service= status=503 bytes=
Error H10 謎のエラー。
対処
本番はassetsとかのプリコンパイルが必要
heroku rake assets:precompire とかの方法もあるらしいが、とりあえずライブコンパイルを有効に。
config/environments/production.rb
config.assets.compile = true
false -> true に変更。
herokuにJS実行環境が無い
gem入れる。
Gemfile
gem 'therubyracer'
herokuはsqlite3じゃなくてPostgreSQL
config/database.yml は書き換えなくても勝手にPostgreSQL使うらいい。
gemを追加しておく。
Gemfile
gem 'pg'
github でサブアカウント、ユーザー切り替え
Githubでサブアカウントを使おうとしてもSSH公開鍵が同じだと同じユーザーと判断されてしまうため、そのままだとユーザー切り替えとか簡単には出来ません。
以下やりかた
メインアカウントの設定は既にできてるものとします。
まずはサブアカウントの準備
サブアカウント用のsshキーペア作成
cd mkdir ~/.ssh/key4github/ cd ~/.ssh/key4github/ ssh-keygen -t rsa -C "hoge@example.com"
接続確認
さっき作った鍵でアクセスできるかどうか試します。
ssh -i ~/.ssh/key4github/id_rsa -T git@github.com
メインとサブの使い分け
簡単にサブアカウントアクセスできるようにSSHの設定を行います。
hoge.github.com でsshできるようにする
~/.ssh/config 編集
Host hoge.github.com User git Port 22 Hostname github.com IdentityFile ~/.ssh/key4github/id_rsa TCPKeepAlive yes IdentitiesOnly yes
確認
ssh -T hoge.github.com
サブアカウント用リポジトリ作成
githubのチュートリアルどおり新repository作ってこのリポジトリ(サブアカ)用のconfigを設定する。
しかし、このままだといつものSSHキーを使ってしまうのでメインのアカウントにつなげてしまいます。
SSHしか通らないサーバーで適当なポートに立ち上げたサービスにアクセスする
railsとかjsTestDriverとかJenkinsとか最近ではPHPのビルトインウェブサーバーもそうなんですが、コマンド一発サービス起動して後はブラウザからアクセスするだけで利用できるものがよくあります。
でも、サービスを起動したサーバーでは開けてるポートが限られてて結局使えない、とかいうこともままあります。
↓
ダイナミック転送、SocksProxyでかいけつ!
PuTTY + pfwd でダイナミック転送の設定
pfwd.iniの編集
puttyのインストールフォルダに pfwd_sample.ini ファイルがあります。
それをコピーして pfwd.ini を作成して編集。
編集を行なう部分を抜粋しました。
接続先サーバーの設定
[SSH] ; SSHサーバーアドレス ; PuTTYで保存したセッションの設定を使用する場合には@セッション名で指定します。 ; 省略できません。 Host=dev.example.com
秘密鍵(.ppk)
; プライベートキーファイル (rsa, rsa2, dsa) ; ・省略時にはセッションに設定されているものが使われます ; puttygen.exeで作成(変換)したファイル PrivateKey=C:\path\to\privatekey\hoge_dsa.ppk
ユーザー名
; ログインユーザ ; ・省略時にはセッションに設定されているものが使われます User=calpo
ポート1080でダイナミック転送を行なう設定
;;================================================= ;; HOST4 Dynamic Forwarding ;;================================================= 01=D1080
pfwd 実行
これで、pfwdがlocalhost:1080で受けて、iniで指定したホストに転送を行なうようになります。
エラーなどあった場合こちらのページが参考になりました。
http://old.typemiss.net/blog/kounoike/20061019-100
ブラウザの設定
そして肝心のブラウザの設定です。
やろうとしていること
- ブラウザには http://development-server:8080/ みたいにして、アクセス
- ブラウザは development-server へのアクセスを localhost:1080 に投げる
proxy.pac の作成
development-serverへのアクセスの場合のみプロキシを通すようにしたいです。
これにはスクリプトが使えます。
以下のようなファイルを作ります (名前は何でもいい)
proxy.pac
function FindProxyForURL(url, host) { if (host == "development-server") { return "SOCKS5 127.0.0.1:1080"; } return "DIRECT"; }
ブラウザの設定
プロキシの設定に先ほど用意したスクリプトを使うようにします。
- Firefox の場合
- ツール > オプション > 詳細 > 接続 > 接続設定
- 自動プロキシ設定スクリプトURL にproxy.pacを指定 > 再読み込み
- 例) file:///C:/etc/proxy.pac
Firefoxで問題があった場合の追加設定
名前解決で問題があった場合はこちらが参考になりました。
http://www.knonline.net/d/?date=20080611
- アドレスバーに「about:config」と入力して開く
- network.proxy.socks_remote_dnsの項をtrueに変更する
準備完了
あとは dev.example.com サーバーでJenkinsなり何なり立ち上げて
http://development-server:8080/ とかでアクセスしてみましょう。
git svn switch --relocate 的なことをする (patch利用)
http://d.hatena.ne.jp/do_aki/20110530/1306751266
↑で紹介されているような .git/config を書き換える方法が使えない場合の話です。
(旧svnリポんジトリが時すでに削除済み とか)
新gitワーキングツリーに手動でブランチを移植する感じでがんばります。
全体の流れ
- 旧gitワーキングツリーで対象ブランチのパッチ作成
- 新gitワーキングツリーで対応するブランチ作成
- 新gitワーキングツリーのブランチでパッチ適用
旧gitワーキングツリーで対象ブランチのパッチ作成
こんな感じの状態だとします
$ tree . |-- patch #パッチ置き場 |-- new_gitrepo #新git-svnワーキングツリー `-- old_gitrepo #旧git-svnワーキングツリー
旧リポジトリで移植したいブランチを確認します。
ブランチの派生元となるmasterのコミット
と
移植したいブランチの最新コミット
を確認。
$ cd ~/old_gitrepo $ git log --oneline --decorate --all --graph * d456789 (br2) 修正bar | * c345678 (br1) 修正foo |/ * b234567 (HEAD, git-svn, master) 修正fuga * a123456 修正hoge ・・・
パッチを生成します
git format-patch 取得範囲自..取得範囲至 -o パッチ保存ディレクトリ
$ git format-patch b234567..c345678 -o ~/patches/br1 $ git format-patch b234567..d456789 -o ~/patches/br2
新gitワーキングツリーにブランチを作ってパッチ適用
ブランチ作成してパッチ適用
$ cd ~/new_gitrepo $ git checkout -b br1 $ git apply ~/patches/br1/* $ git ci -m "修正foo"
もう一つのブランチも同様に
masterからブランチ作る
$ git checkout master $ git checkout -b br2 $ git apply ~/patches/br2/* $ git ci -m "修正bar"
以上。
パッチのメッセージがメール用にエンコードされたままっぽかったので、git am とせずに apply でコミットメッセージを改めて設定しています。
というか旧ワーキングツリーのブランチの個々のコミットの情報は失われてひとまとめになっちゃいますね。