なんでテストを書くの?

思ったとおりに動いていることを確認する

ちょっとずつ確認しながら進んでいくとつまらないバグがなくなる。

プロダクトコードの振る舞いのリスト

テストメソッド名で振る舞いを説明する。
テストコードなのでウソの(疑わしい)ドキュメントとならない。
(--testdoxオプション)

実際に動かすことができるサンプル

初めて見る処理に修正を加えないといけなくなった時、
とりあえず動かして何が起こるのか見てみたかったりしない?

手軽に再現可能な動作確認の手段

あるバッチ処理を動かすために・・・
マスターテーブルにデータを入れて、別のバッチでランキングデータを作って(1時間)、ブログの管理ツールから新規の記事を公開して、YAMLファイルをアップロードして、キャッシュが切れるまで1時間待って、ブラウザで現在の記事リストを確認して、バッチプログラムを実行して、記事リストに追加された記事を確認!

動作確認のたびにこれが必要だとしたら・・・?

  • ユニットテストでの解決
    • モックによって修正対象コードの動作確認に注力
  • システムレベルのテストの自動化での解決
    • 無駄な待ち時間無しに誰もが実行できるシステムレベルの動作確認手順の作成
      • 最初からこれを意識した作りで準備するのが重要
      • あとからやろうとするとかなり辛い
      • 最初からテストを作っていくことが重要
      • 最初からテストを作っていくことが重要

設計に関するスキルの向上

実際のプロダクトコードでは、簡単にテストを書けるケースはあまり多くない。

  • シンプルにテストが可能な単位に分割したり
  • そもそもテストが可能なように外部依存を切り出したり

といったことをしていくことでスキルの向上につながる。

PHPカンファレンス2012メモ #phpcon2012

気になったところのみ。


基調講演

マルチバイト(mb_*関連)がネイティブサポート

デフォルトの文字コードUTF-8に → htmlspecialchars()注意
絵文字もネイティブサポートへ。

Composer

RubyでいうBundler的なライブラリ依存管理の仕組み。
Symphony2を始めとして多くのものが対応している。
(というかsymfony2はコンポーザーでインストール!)
「みんな対応している」重要

初心者セッション

php.netおすすめ
  • 関数マニュアル
  • ユーザーコントリビューション
    • 英語だけどコードの投稿が多い、参考になる
  • チュートリアル
開発を支えるツール等

いまだからできる、ふつうのはなし Gree

終盤5分くらい聞いた。
古いシステムの改善は、機能毎に区切って(縦に切って)少しずつリプレイスしていくのがいいと思ってたけど、どうもそうではなく、既存のシステムに新たに層を2つくらい積み重ねて(横に追加して)いくことで改善を行うような話だったらしい。
聞きたかった・・・

徳丸本に学ぶ 安全なPHPアプリ開発の鉄則2012

と・と・鳥ランド!
IPAやセキュリティ専門家をウォッチ、騒ぎ出したら急いで対応

脆弱性の意見度が高くても、対象範囲が狭いとそんなに騒がれない。
(対象範囲が狭い ← あるシステムがその脆弱性の影響を受けるかどうかも攻撃者からはわからない、というのも重要?)

IEしねばいいのに

jsonがHTMLとして解釈されて、その中のscriptタグが評価実行されてしまう。
X-Contenttype-nosniff

最先端Web開発

アジェンダ見たところ、自社開発フレームワーク(dietcake)の紹介かとおもいきや、プレゼン開始直後のスライドでそのアジェンダに取り消し線が入った!
とてもいい話でした。感動した。

PHPという言語自体のポリシーに通じる部分もあり、とても共感できました。

新しくjoinする人をどのように迎え、どのように育ててゆくか。

フレームワークはシンプルに保つ

Symphonyとか1,2で変わりすぎて学習はやり直し、Doctrineのコードなんか全部ちゃんと読める人などほとんどいない。
フレームワークのコードが現実的に読める内容であること。
「変わらない」ということの価値。

グループプログラミング

ドライバー1、ナビゲータ3 でのペアプロ
join.meというサービスでドライバーの画面をナビゲータの端末で共有
なんと生産性自体は一人の時とそんなに変わらないらしい(4倍近くになってる!?)

Githubでプロジェクトの健全性を測る

コミットの回数とタイミングが統計的に確認できる
→ 夜中土日のコミットが多いとデスマってるなーとなる

Git x Pull Request ~ チーム開発最終奥義

svnからgitへの移行

svnとgitコマンドの対応を覚えることではない、開発フローの刷新である!

gitのメリット

ローカルでの気軽なコミット、手軽なブランチング、賢くて高速なマージ

リリースを細かく

リニューアルとかの大きな案件でも「○○の構造変更」とかだけでリリース等
こうするとあとでマージが大変とかにならない

featureブランチから更にfeatureブランチを生やす

複数人での機能開発での混乱を少なく

PullRequestを通して必ずレビュー

これを繰り返してメンバーの長所短所など特徴を知ることができる
細かい単位で行うことで、レビューの効率がとても良くなる
どのような要求に対してどのような変更を行ったかが重要であり、そこに対して効果的なレビューが出来る

チームにあったやり方で

KLabさんとか、基本master一本でそこからいくつも細かい開発ブランチ生やすようなシンプルなやり方だし。

ツールはGitLabおすすめ

もしくはGithubEnterprise
githubのプライベートリポジトリもいいけど、それだと落ちてる時リリースできないよね。

と、聞いて思ったけど、composerによるライブラリインストールがビルドプロセスに入ってるとpackagistが死んでたらビルドできないじゃん、そういうのってどうしてるのかしら?

基本はGithub,Packagistだよりだけど、急ぎのリリースの場合はこれら無しでローカルのリソースからデプロイできる、って感じかなぁ。

Composer による依存管理と Packagist によるライブラリ公開

日本語化頑張り中だそう
https://github.com/kawahara/composer

フレームワークアップデート

Symfony2

twigいいなー
composerでインストール

Yii

よく知らなかったので期待していました。
海外ではだいぶ人気があるみたい。国内はFuelPHPに完全敗北状態。
なんとPHP5.1以上対応。
↑逆に心配になったけど、どうなんだろ?
Yii2から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

                                                            • -

gem "twitter-bootstrap-rails"

                                                            • -

のところで、group :assetsの中じゃなくて外に指定しないといけなかったぽい。

こうじゃなくて

# assets用のgem、デフォルトでは本番で不要となる
group :assets do
  # ・・・
  gem 'twitter-bootstrap-rails'
end

 ↓
こう

gem 'twitter-bootstrap-rails'

# assets用のgem、デフォルトでは本番で不要となる
group :assets do
  # ・・・
end

まとめ

本家のREADMEも読んだほうがいい。

issuesにあった。
https://github.com/seyhunak/twitter-bootstrap-rails/issues/123

herokuにrailsアプリをデプロイする(Error H10 ってなに;;)

railsによるアジャイルWebアプリケーション開発第4版を読んだので早速herokuでアプリでも・・・
と思ったらRubyrailsも初心者で結構つまづいたのでメモ。

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'

改めてデプロイ

bundle install するとGemfile.lockが更新される。

$ bundle install
$ git add .
$ git ci
$ git push heroku master
$ heroku rake db:migrate
$ heroku open

これでheroku上でも「Listing users」が見えてるはずです。

結局数行修正するだけで良かったんだけど、herokuもRubyrailsも全部初心者だったので結構辛かった。
Rubyの文化なのか、すぐにバージョンが上がってちょっと前の情報通りに行かないとかがよくあって大変。

github でサブアカウント、ユーザー切り替え

Githubサブアカウントを使おうとしてもSSH公開鍵が同じだと同じユーザーと判断されてしまうため、そのままだとユーザー切り替えとか簡単には出来ません。

以下やりかた

メインアカウントの設定は既にできてるものとします。

まずはサブアカウントの準備

サブアカウント用のsshキーペア作成
cd
mkdir ~/.ssh/key4github/
cd ~/.ssh/key4github/
ssh-keygen -t rsa -C "hoge@example.com"

キーの場所指定で ~/.ssh/key4github/ とする
パスフレーズを忘れないように

サブアカウント用のGithub側設定

右上アイコンAccountSettings>SSH Keys>Add SSH Keys から
できた id_rsa.pub をはりつけ。

接続確認

さっき作った鍵でアクセスできるかどうか試します。

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/configで設定したホストにする
(gitコマンドで add remote するときに指定しちゃったほうが手っ取り早いかも)

[remote "origin"]
#   url = git@github.com:hoge/firstrepo.git
    url = git@hoge.github.com:hoge/firstrepo.git

これでgithubへの接続時にさっき作ったサブアカウントSSHキーを使うようになり、サブアカウントでの接続となります。

おまけ

ユーザー名や(あれば)APIキーも変更。

[github]
    user = hoge
    token = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[user]
    name = hoge 
    email = hoge@example.com

ここまでだと毎回パスフレーズを聞かれるがそれはまた別件。

SSHしか通らないサーバーで適当なポートに立ち上げたサービスにアクセスする

railsとかjsTestDriverとかJenkinsとか最近ではPHPのビルトインウェブサーバーもそうなんですが、コマンド一発サービス起動して後はブラウザからアクセスするだけで利用できるものがよくあります。
でも、サービスを起動したサーバーでは開けてるポートが限られてて結局使えない、とかいうこともままあります。

  ↓

ダイナミック転送SocksProxyでかいけつ!

(SSH接続にはPuTTYを使ってるものとします)

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
pageant 実行

いつものようにpageant秘密鍵を指定しておきます。

pfwd 実行

これで、pfwdがlocalhost:1080で受けて、iniで指定したホストに転送を行なうようになります。

エラーなどあった場合こちらのページが参考になりました。
http://old.typemiss.net/blog/kounoike/20061019-100

ブラウザの設定

そして肝心のブラウザの設定です。

やろうとしていること
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


  • Chrome の場合
    • スパナアイコン > 設定 > 詳細設定を表示... > ネットワーク > プロキシ設定の変更... > 接続 > LANの設定
    • 自動構成スクリプトを使用する にチェック
    • アドレス にproxy.pacを指定 > OK
      • 例) 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 でコミットメッセージを改めて設定しています。

というか旧ワーキングツリーのブランチの個々のコミットの情報は失われてひとまとめになっちゃいますね。