More Related Content Similar to Try_to_writecode_practicaltest #atest_hack (20) More from kimukou_26 Kimukou (8) Try_to_writecode_practicaltest #atest_hack12. なんでテストが必要?(Mediationレイヤー)
● CustomEventBanner継承クラスが現在は必要
○ 日本の国内Ad広告に対してAdapterが提供されてないから
○ =>自前で作りましょう の流れ
● AdMob SDKのソースはAndroid版は非公開
(IOS版はソースもろらしいですが。。
■ <そもそも2009年頃にAdMobはGoogleが買収した会社
■ ステップデバック等でも結構限界がある
● 実際試してみて呼び出し周期がどうも一定しないような感じ
■ 偏って呼ばれる感じがする。。
■ AdWhirlの頃はもっと安定していたらしいが。。。発展途上?
13. なんでテストが必要?(Ad側)
● Ad SDK自体がWebViewをくるんだカスタムレイアウト+α
なので
○ WebViewの不安定さに引きずられる
=>よく「アプリ落ちる」という話題はこれ
○ 作り自体もNWの調子が良いことが前提で作られている
(通信エラー対応とかしてない。粗い)
■ ココらへんはAdMobとかも同じ
=>
● 広告会社さん的には
○ クリック率を上げるために
■ 視聴者にあった広告を出すための情報収集
■ 収集しやすい形にする為に鯖側も改修
● =>常に最新使ってね(更新がすごい早い)
● 落ちるときはアプリ側で頑張って
14. Mediationの動き的な話
端末側
(AdMob 6.1.0導入)
loadAd
AdMob管理鯖
枠キー送信
(またはメディエーションキー)
指定されたクラスファイルがサー
キーに対応したクラスを読 バーパラメータ受信する形で呼
込なさい& ばれる
情報送信 例)
(サーバーパラメータ) com.nihon0tc.ad.MedibaMasAd
のような指定の仕方
15. CustomEventBanner
を継承したクラス
com.nihon0tc.ad.MedibaMasAd listener.onReceivedAd
(View)
で他の広告SDKのViewを
AddViewする
@Override
public void requestBannerAd(
final CustomEventBannerListener listener,
final Activity activity,
String label,
String serverParameter,
AdSize adSize, Exception等で失敗したら
MediationAdRequest request) { listener.
onFailedToReceiveAd();で
「新しいリクエストおくれ」
と再リクエストを行う<手動
16. テストコンセプトとして
● requestBannerAdを直接叩く
○ 単体のAd SDKが初期化エラー等がおきないような検証
○ onFailedToReceiveAdの段階では
テストを失敗させるように
CustomEventBannerListenerのMockを作ってAdMobの
動きをエミュレートする
● 単一のCustomEventBannerをよぶようなメディ
エーションIDを設定して初期化する
○ 全部を呼ぶようなメディエーションIDを設定できるがどう
も偏っていてテストしづらい
21. テスト構成
ライブラリプロジェクト AdManager
メインプロジェクト template_canvas
テストプロジェクト template_canvas_test
● 枠キー情報(ad_key.xml)は下記に有
○ ライブラリプロジェクト(定義だけで中身は空)
○ メインプロジェクト(実際のキーを記述)
<ライブラリプロジェクト側のキーはfinalで無いので上書き可能
● メインプロジェクトのAndroidManifest.xmlに
○ AdMob
○ Mediba
の広告用のActivityの記述を追記する(各Adの説明書に依存)
● テストプロジェクト側に
○ テスト用のメディエーションキー配列(ad_key_test.xml)配置
22. 実行時のイメージ
● duckをクリックする毎に上下に広告
位置が変更されるイメージ
● 最近の流行で(ゲーム)画面を
OpenGLで作る事が多いようなので
FrameLayoutで広告を重ねています
● レポジトリは
○ https://github.com/nihon-
tc/mediationtest
参照してください
23. リソースの参照
● テスト書いてて混乱したので整理
○ com.nihon0tc.example.test.R
○ com.nihon0tc.example.R
と明示してIDを指定した方が混乱が無いようです
(ここら辺は常識かも知られませんが<汗)
テスト対象のリソース参照 getActivity().getResource()
または
getInstrumentation().getTargetContext().
getResources()
テストプロジェクトのリソー getInstrumentation().getContext().getResources()
ス参照
(テストデータとか)
24. AdMobの初期化の仕方の修正
● 実装観点から
■ 本来はメディエーションキー/枠キーは固定なので
■ レイアウトから呼ぶ形でも良いはず
LayoutInflater inflater = activity.getLayoutInflater();
ViewGroup adParentView =(ViewGroup)inflater.inflate(R.layout.ad, null);
adMob = (AdView)adParentView.findViewById(R.id.AdMob_medview);
<?xml version="1.0" encoding="utf-8"?>
<com.google.ads.AdView xmlns:android="http://schemas.android.
com/apk/res/android" xmlns:ads="http://schemas.android.com/apk/lib/com.google.
ads"
android:id="@+id/AdMob_medview"
android:layout_width="320dip"
android:layout_height="70dp"
ads:adUnitId="@string/adUnitId_mediation"
ads:adSize="BANNER"
ads:loadAdOnCreate="false" />
25. ● テスト観点から
■ 動的に生成しないとMediation_IDが再設定できない
● AdMobさんの方であとからキーを再設定できる関数がな
い
■ ココらへんは微妙かなと思う面もある
String key = activity.getResources().getString(R.string.
adUnitId_mediation)
adMob = new AdView(activity, AdSize.BANNER, key)
26. CustomEventBannerListenerのMock
(挙動推測から下記イメージで
import com.google.ads.AdView;
import com.google.ads.mediation.customevent.CustomEventBannerListener;
public class MockEventBannerListener implements CustomEventBannerListener{
@Override
public void onFailedToReceiveAd() {
throw new RuntimeException("onFailedToReceiveAd");
}
@Override
public void onReceivedAd(View arg0) {
ViewGroup parent = (ViewGroup)arg0.getParent();
if(parent !=null) parent.removeAllViews();
adMob.addView(arg0);
}
}
28. メディエーション・Adの導入的な話は
● @HiroakiKamata さんの記事
○ テクノード鎌田社長に聞いた!ゼロから分かるAdMobメ
ディエーションツール導入方法
■ http://android.dtmm.co.jp/development/32475
● Ad広告自体の話
○ ad-stirさんの Android SDKの使い方
■ http://wiki.ad-stir.com/Android_SDK%E3%81%
AE%E4%BD%BF%E3%81%84%E6%96%B9
あたりを参考に
29. CustomEventBunner実装時の注意点(1)
● 一度作ったAdのインスタンスはstatic変数に確保した方が
良
○ Ad広告会社さん毎にアクティブ数管理してる
○ 何度もCustomEvent発行されるたびに作り直すのは非推奨
● 複数の画面レイアウトを切り替えている場合は、理想は
AdMobの枠自体を
○ 前の画面から外す(RemoveView)
○ 今の画面の指定位置に追加(AddView)
する形が良いかと思う
(最近はredirect-urlを挟んで誤クリック判定等も厳しくなっているので、誤クリックしに
くいレイアウト配置も大事)
30. CustomEventBunner実装時の注意点(2)
● NW状態悪いと何回も通信リトライする物も
○ 重くなる原因
■ Androidは通信がらみが重くなる
■ GoogleAnalytics もANRでる原因になる事も
○ 可能であばNW状態が悪いときはローテトを止める
■ Receiver等でConectivityManagerを監視する話はググると出てきます
が、3G環境は4系から動くようになっているので2系は厳しめ
(READ_PHONE_STATE追加で電波状況判定等を入れると騒がれるか
ら対応難な面も)
■ 表示Activeかみて動いている物もあるようなので、オフライン時に一時
的にレイアウトから外す手も
(なら広告入れるな議論する人もいるけど霞食って生きてはいけない
はずなんだけどな・・orz)
31. CustomEventBunner実装時注意点(3)
● リアルタイム製を重視するゲームの場合はゲーム中は
pause等できるなら検討する
○ でもずっと止めてると単価はのびないかも・・
○ 対応が入っていない物も結構あるorz
■ (1個ローテート用のスレッドが動いているイメージ)
● onReceivedAd関数のタイミングでAddViewし直しているイ
メージなので
○ 切替前にはpauseかけられる物は止める
■ ローテート中に切り替えるとエラーになる事も
■ 可能であればアクティブな物のみ動かすようにする
○ 切替後に再始動(resume)のイメージ
32. CustomEventBunner実装時注意点(4)
● Ad自体に対して
● 基本Layoutだけでいきたかったりするが、日本でのAd自体が微
妙に使いづらいので、動的生成にならざるをえないのが難点(逆
にレイアウト固定の物も)
○ infrate初期化後に広告枠のキーを設定して初期化等の関数が用意されて
なかったり
○ 動的コンストラクタのパラメータか、レイアウトのパラメータとして設定すると
かの形になったりする
● アクセスキャッシュをtmpにガンガン貯める物も多いのでアプリ側でちょ
びちょび消さないと内部メモリを圧迫する
○ 最近はユーザ領域にsqliteでデータキャッシュする物もあるようなのでこれ
の対処は困り者><(ユーザ領域のデータ消すのは。。
33. 広告種別 Manifest記載 layout /code対応 resume/pouse(?)有無
AdMob △(Activity) ◎ ◎
AdLantis △(コード対応可) ◎ ×
Mediba △(Activity) ◎ ◎
AMoAd - ◎ ◎
iMobile △(PubKey) ◎(枠Key設定可) ◎
MicroAd ◎(Key) ◎ ×
Fluct △(コード対応可) ◎ ×
AdPapri - layoutのみ ◎
Nend - ◎ ◎
AdStir △(コード対応可) ◎ ×
resume/pause 対応の広告は増えてほしいかな・・とは正直思いますね・・
36. ● 長時間ランニングテスト
○ 担当者レベルの単体テストで終わってる
○ 収益性的には重要だが魅力あるコンテンツ作成に開発者
としては力を割きたい
■ =>
○ でもユーザさんからは
■ 「長時間動かしていると、アプリがどんどん重くなる」というPlayコメ等は頂
いている状態
● 特定のAd SDKで起きる現象
○ 特定の条件下でViewの初期化失敗
■ =>
○ onFailedToReceiveAdのリトライループで頻繁にアクセス
な状況が起きる・・
■ Mediation側の確率に偏り無ければ別Ad表示されればOKすが・・
37. ● Android JUnit で Parameterized test case
○ http://kokufu.blogspot.jp/2012/07/android-junit-
parameterized-test-case.html
○ サンプルも動かせなかった><
■ 2.3.3以降対応らしいけど、Xoomでダメ・・
(RuntimeExceptionがでる
■ でも2系のテストが普通に出来ないのは厳しめ
か。。。
● Native Driverでのテスト
○ テストプロジェクト側がjavaプロジェクトでないと動かない
というのに気づかなくてハマった><
38. 実機でテストしているとLOCKやKEYGUARDがかかっ
てしまう問題
○ NativeDriverのサンプルのように
■ 検証側のAndroidManifest.xml側に
<uses-permission android:name="android.permission.WEAK_LOCK" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
はどうなんでしょう??(有識者の知恵を聞きたいかも
<この状態でもUSB等で給電していなければ画面ロックがかかってしまったり
実際には)
● 画面を ON のままにする方法
○ http://android.keicode.com/basics/how-to-keep-screen-on.php
● WakeLockを取得し、Sleep状態からWake状態へ遷移する
○ http://techbooster.jpn.org/andriod/application/4429/
あたりの対応が必要らしいのですが・・
本体のコードはあまり弄りたくないかな・・(権限も含めて
39. emmaを使った実機テスト
● ant emma debug install test とか実行すると
○ WARNING: Code Coverage is currently only
supported on the emulator and rooted devices.
てのがでる。実機でのテストが多いのでちょっと微妙・・
(Ad系のテストは、端末情報を取得している面があり
基本実機で確認してほしいというお話はあったりとか)
● ここら辺の話は
● @3a3k さんが
○ 今更ながらAntでAndroidのTestを実行してみる
■ http://3a3k.blogspot.jp/2012/01/antandroidtest.html
で書かれたりしています
● あとはメインのbuild.xmlを弄るといい話も
○ http://stackoverflow.com/questions/2762665/how-to-use-emma-code-
coverage-in-android
● 他の参考ページ
○ http://d.hatena.ne.jp/halts/20120201/p1
40. 実行の仕方でエラーがでるテストも・・(謎
● OK:直接eclipse上からテスト右選択して実行
● NG:ant経由(勿論画面ロックはかかってない)
■ TouchUtils.tapView(this,(View)target);
○ あたりで
○ java.lang.SecurityException: Injecting to another application requires
INJECT_EVENTS permission
● ググると
○ AndroidのスクリーンロックをJenkinsでのビルド時に解
除する
■ http://d.hatena.ne.jp/makiczar/20111029/1319853201
■ adb shell input keyevent 82
の話が出てくるのですが・・・?
43. と長々と書きましたが
● Mediation対応自体はIOSでの対応が切望さ
れる事が多い
○ 理由としては、クリック単価率等が2−3円は違う
かららしい
○ IOSユーザ:富裕層、購買意欲高
○ Androidユーザ:ガラケーユーザと同じくタダで
端末手に入れたりした層(お金使わない)
な分析されていたり(汗
● IPhone/IPad
● スマートフォン(Android?)
● ガラケー
な分類が未だ一般的
44. エロ広告増えてる理由>
・Ad広告を設定する場合、カテゴリ設定をする
=>普通はエロは設定しない
=>なんで出ちゃうの?
在庫無い時)
・黒い画面が出てしまう
各社の対応)
・Google =>GoogleのAdSenseの広告を出す
・他社 =>黒い画面のまま か 自社広告か 担当の人が余って
いる広告をだそうとする(これがエロっぽかったりする事が多い)
だから実はソフト作っている人や会社に文句いってもどうにもならない
んですね。それだけ日本が景気悪くなっていると言う事かも
52. groovyスクリプトの活用
● groovy eclipse-pluginのインストール
○ インストールの話は下記の方のブログを参照
○ @shinyaa31 [Java][Groovy][Eclipse]Java/Groovy
エンジニアのためのEclipse開発環境構築/テスト実践方
法まとめ
■ http://d.hatena.ne.
jp/absj31/20120803/1344114579#eclipse_
groovyprog
○ @waman10da
Groovy Eclipse Plugin (1):インストールと設定
■ http://d.hatena.ne.
jp/waman/20090424/1240603561
53. ● ただAndroid Projectで使うのは問題有り
○ プログラミングGroovyでも書いててあるけど
「Groovy Project」で使える
○ eclipse上から便利スクリプトとして使いたい用
途にはちょっと
■ でも一応groovyファイルの色分け等はされるので全く
無駄ではないですよ!
■ =>
○ 外部ツールに
登録して使えばいいよね!
■ groovy自体は別途要インストール
56. どんな利用が考えられるか?
● usbで複数端末繋がってる全部の端末に一
度にインストールできると便利だよね
○ build.xml は端末1つ時のみ対応〜><
○ 複数端末つないで開発な環境だとすごく面倒><
で作ってみた
● https://gist.github.com/3669015
○ 以前 build.xml に手を入れて作っていた物の拡
張版です。次のようなアドバイスをウケたので。
基本的にbuild.xmlは更新かかる可能性がある
ので、手を入れない方が良いらしい
58. スクリプトの補足)
● eclipse3.7上では
○ ant.importBuild 'build.xml'
■ が上手く動きません
○ eclipseに含まれているantが1.7ベースなのでそ
ちらが参照されてしまう
● 従って下記のような迂回した形になります
def antFile = new File("./build.xml")
def project = new Project()
project.init()
ProjectHelper.configureProject(project, antFile);
project.executeTargets(['clean', 'release'] as Vector)
59. ● AntBuilderのoutputproperty等の値がキャッ
シュされ変更不可なのであえてカウンターで別
名をつけて状態を取得してます
cnt++
cmd = "-s $it install -r $file"
ant.exec(outputproperty:"cmdOut$cnt",
errorproperty: "cmdErr$cnt",
resultproperty:"cmdExit$cnt",
dir:".",
failonerror: "false",
executable: "${adb_home}/adb") {
arg(line:cmd)
}
println "[$cmd]<" + ant.project.properties."cmdExit$cnt" + ">=" + ant.
project.properties."cmdOut$cnt"
60. このスクリプトだとprintlnでSystem.outに出力して
ますが、下記のように囲んでしまうのも手
def stdOut = System.out; // save old System.out
def newFileOutputStream = new FileOutputStream
("log_${new Date().format("yyyy-MM-dd-HH-mm")}.txt",
true);
def newOutputFilePrintSteam = new PrintStream
(newFileOutputStream);
System.setOut(newOutputFilePrintSteam);
//処理
System.setOut(stdOut);
61. build.xmlの作り方の復習
ライブラリプロジェクト AdManager
メインプロジェクト template_canvas
テストプロジェクト template_canvas_test
● ライブラリプロジェクト
○ android update project -p ./
● メインプロジェクト
○ android update project -p ./ -l ../AdManager
● テストプロジェクト
○ android update test-project -m ../template_canvas -p
./
(ただこの場合、build.xmlでテストを動かした時にライブラリプロジェクトが見えないよう
で手動で追加したのでコマンド的には足りないかも)
62. ● 認証キーが無い場合
● keytool -genkey -v -keyalg RSA -keystore ./debug.
keystore -alias androiddebugkey -validity 10000
○ android/android で作るイメージで想定
● local.propertiesを編集します
# 自分の環境が違う場合はsdk.dirを修正する事
sdk.dir=/Users/◎◎/android-sdk-macosx
key.store=debug.keystore
key.alias=androiddebugkey
key.store.password=android
key.alias.password=android
release.app.name=hello
release.app.version=v01
67. groovyHelp
● groovyとjava-docのHelp検索ツール
○ http://syboos.jp/oss/doc/groovyhelp.html
○ java7u6以上が必要
○ macで動かすときはgroovyhelpのシェルを修正した
■ 検索とか微妙に動かなかったのでwin専用かも?
#!/bin/bash
export GROOVYHELP_JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.7.0_07.
jdk/Contents/Home
if [ -d "$GROOVYHELP_JAVA_HOME" ]; then
JAVA_EXE="$GROOVYHELP_JAVA_HOME/bin/java";
elif [ -d "$JAVA_HOME" ]; then
JAVA_EXE="$JAVA_HOME/bin/java";
else
JAVA_EXE="java";
fi
JAVA_EXE="`echo "$JAVA_EXE" | sed 's////g'`";
chmod -R 755 lib;
eval "`"$JAVA_EXE" -jar ./lib/groovyhelp_launcher.jar "$JAVA_EXE"`";