Watson's Blog

Proxy サーバを用意して HTTP 通信をテストしよう

| Comments

この記事は RubyMotion Advent Calendar 2012 の 4 日目の記事です。

以前「RubyMotion もくもく会」で HTTP 通信のテストはどうすれば良いのだろうかという話題でモックを用意するのですかねと話が収束したのですが、面倒だし極力アプリに手を加えたくないなぁと一人もやもやしておりました。

Proxy サーバを用意すれば比較的簡単にテストできるんじゃないかと思い、ブログに書いてみました。

きっかけは

何を検索していてたどり着いたのかは忘れましたが、http://ja.favstar.fm/users/Psychs/status/3507370903 というツイートを見かけ、

Psychs 先生のツイート

さすが @Psychs 先生。神!と思った次第です。iOS シミュレータなど Cocoa API を使ったアプリの HTTP 通信は簡単に Proxy を経由するように設定できるわけですね。

Proxy サーバを作る

CRuby には WEBrick というライブラリが付属しています。このライブラリは HTTP サーバはもちろん Proxy サーバも作ることができます。今回はこれを使ってみます。

proxy.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/usr/bin/env ruby
# -*- coding: utf-8 -*-
require 'webrick'
require 'webrick/httpproxy'
require 'uri'

handler = Proc.new() do |req, res|
  # クライアントに対してテストしたいレスポンスを返す
end

s = WEBrick::HTTPProxyServer.new(
       :BindAddress => '0.0.0.0',
       :Port => 8080,
       :ProxyContentHandler => handler)

Signal.trap('INT') do
  s.shutdown
end

s.start

上記の proxy.rb を実行すると 8080 ポートで Proxy サーバが起動します。

あとはハンドラの処理をテスト内容に応じて追加してあげると良いでしょう。たとえば画像に対しては 404 Not Found を返してあげたい場合には

1
2
3
4
5
6
handler = Proc.new() do |req, res|
  if res["content-type"] =~ /image/
    res.body = "Not Found"
    res.status = 404
  end
end

といったような処理を追加すると良いでしょう。特定の URL に対するアクセスも同じように簡単に処理できるかと思います。あるいは、sleep を追加して一定時間レスポンスを返さないテストも行えるかと思います。

プロキシを設定し利用してみよう

[システム環境設定] の [ネットワーク] でプロキシを設定します。

プロキシを設定

これで Cocoa API を使用したアプリの通信がプロキシを経由するようになります。

あとは、先ほど作成した proxy.rb を起動した状態で RubyMotion アプリを rake コマンドで実行するだけです。シミュレータ上での HTTP 通信もプロキシを経由するようになります。

プロキシサーバのログにはいろいろ出力されることでしょう。

1
2
3
4
5
6
7
8
9
10
$ ruby proxy.rb
[2012-12-02 19:24:14] INFO  WEBrick 1.3.1
[2012-12-02 19:24:14] INFO  ruby 1.9.3 (2012-11-10) [x86_64-darwin12.2.0]
[2012-12-02 19:24:14] INFO  WEBrick::HTTPProxyServer#start: pid=55229 port=8080
localhost - - [02/Dec/2012:19:24:20 JST] "GET http://gspa21.ls.apple.com/config/prod-resources-lodpi-18 HTTP/1.1" 200 8088
- -> http://gspa21.ls.apple.com/config/prod-resources-lodpi-18
localhost - - [02/Dec/2012:19:24:19 JST] "GET http://gsp1.apple.com/pep/gcc HTTP/1.1" 200 2
- -> http://gsp1.apple.com/pep/gcc
localhost - - [02/Dec/2012:19:24:20 JST] "GET http://gspa23.ls.apple.com/tile?style=13&size=2&scale=0&v=46&z=6&x=33&y=21&lang=en&sid=120413474228982680818307689923224195391&tk=11e206b6e88472f89a46a8358fe131fe&mapkey=1354448060_71cded0e981b896e87214a6be0d8e71d HTTP/1.1" 200 1160
- -> http://gspa23.ls.apple.com/tile?style=13&size=2&scale=0&v=46&z=6&x=33&y=21&lang=en&sid=120413474228982680818307689923224195391&tk=11e206b6e88472f89a46a8358fe131fe&mapkey=1354448060_71cded0e981b896e87214a6be0d8e71d

この Proxy サーバは iPhone などの実機からも利用することができます。[設定] の [Wi-Fi] からプロキシを設定してください。

プロキシを設定

テストが終わりましたら、プロキシの設定は元に戻してくださいね。

まとめ

この記事を書いてみて分かったのですが RubyMotion に関するコードが全く出てきませんでした、、、が、RubyMotion アプリのテストに限らず、iOS アプリ全般で簡単に HTTP 通信のテストができるようになるかと思います。

参考

Comments