@neiraza

2匹の怪獣が寝た後にプログラマーしてる、最近はサイバーエージェントでゼミ長もしてる僕のネタ帳

【Appium】モバイルSafari上でテストを実行してみた

先日、iOSでAppiumを試してみたんですが、今回はiOSでやってみました。

お題

実機/シミュレータ上でモバイSafariを起動しテストを実施する。

Appiumって?

実践 Appium

実践 Appium

Appiumとは、iOSおよびAndroidプラットフォーム上で動く - ネイティブアプリ - モバイウェブサービス - ハイブリッドアプリ 等を自動化するオープンソースのツールです。

よくまとめられているコチラの記事をご参照ください。

Design(公式)

http://appium.io/slate/en/master/?ruby#appium-design

Concepts(公式)

http://appium.io/slate/en/master/?ruby#appium-concepts

なぜ必要に?

現在、広告配信タグ(モバイウェブサービス用)のE2EテストにNightmareを使用しています。 しかし、 バイSafariでしか発生しない事象Mac Safariでも再現しない)にぶち当たり、実機(シミュレータ)を使用したE2Eテストの必要性が出てきました。 また、せっかくなら広告配信SDK(ネイティブアプリ用)のテストにも使っていきたいと思い。 そこで、SeleniumぽくてWebDriberの流れを組むやつをチームメンバーに紹介されたので試してみました。

Appium環境を構築するさいにiOSで注意すべきこと

  • Mac環境のあるサーバーをたてないと実機/シミュ−レーターでのテストができない
  • Xcode8に対応していない(時間の問題なんだろけど)

必要な条件

http://appium.io/slate/en/master/?javascript#requirements

Appiumサーバを用意する

CUIでやるなら

githubからappiumをcloneしてくる。

その上で下記からOS毎のセットアップにうつる http://appium.io/slate/en/master/?javascript#appium-platform-support

僕はなかなかうまくいかなくて・・・・

GUIでやってみる

githubで生成するよりも、GUI版をダウソしてくると少しバージョンが古い。 実践 Appiumで紹介されているバージョンに近いのはこっち。

ダウソ

latest versionをダウンロードする

Appium GUIを起動

v1.5.3のAppium GUIを起動してみた。 f:id:redogu:20161215022701p:plain

Appium GUIの設定

  • Basic

    • Device SettingsiOS用シミューレータの名称とOSバージョンを入力する(Xcode上から確認可能) f:id:redogu:20161215022705p:plain
  • Adbanced

  • XcodePath Xcodeを複数入れている場合は使用するやつに変更する f:id:redogu:20161215022708p:plain

Appium GUIよりAppiumサーバを起動

Launch ボタンをタップする。ダーッと出てくるので待つ。

テストを実行する

下記動かせるように適当にNode.js環境を整備した上で、mocha で動かしてみてください。 元ネタは、関数を分割してしまっているのですが、見通しを良くするために僕のお試し版は、下記をご覧の通り1つの関数に全部つめこんじゃいました。

"use strict";

var wd = require("wd");

require('colors');
var chai = require("chai");
var chaiAsPromised = require("chai-as-promised");
chai.use(chaiAsPromised);
var should = chai.should();
chaiAsPromised.transferPromiseness = wd.transferPromiseness;

describe("ios safari", function () {
  this.timeout(300000);
  var driver;

  before(function () {
    var serverConfig = {
      host: 'localhost',
      port: 4723
    };

    driver = wd.promiseChainRemote(serverConfig);

    var desired = {
      browserName: 'safari',
      'appium-version': '1.6',
      platformName: 'iOS',
      platformVersion: '9.3',
      deviceName: 'iPhone 6s',
      app: undefined
    };
    return driver.init(desired);
  });

  after(function () {
    return driver
      .quit();
  });

  it("should get the url", function () {
    return driver
      .get('https://www.google.com')
      .sleep(1000)
      .waitForElementById('lst-ib')
      //.waitForElementByName('q', 5000)
        .type('cyberagent')
      .waitForElementByClassName('kpgrb')
      //.waitForElementByName('btnGNS')
        .click()
      .waitForElementByLinkText('サイバーエージェント')
        .click()
      .sleep(5000)
      .saveScreenshot('test.png');
  });

});

https://github.com/toguri/sample-code/blob/master/sample-code/examples/node/ios-safari-google.js

締め

まだ、うまくテストコードが書けてないけど、テストを実行するとシミュレータが起動してテストコードに書いて有る内容通りに、勝手に動きます。

実践 Appium

【iOS10】ATSのおさらい 2016年末

この記事は「iOS その2 Advent Calendar 2016」10日目の記事です。
テーマは、 2016年中iOSにおけるATSをおさらいしよう! です。

自己紹介

私は、株式会社サイバーエージェント CA ProFit-X という広告プロダクトで、メディア様の収益を最大化することを目標にエンジニアをやってます。
CA ProFit-X は、モバイル向けネイティブ広告(主にインフィード広告)専業のSSP事業者なのです!

お題

バイルアプリ/モバイウェブサービス上で広告運用時に気にしておきたい ATS について、今回は最新OSである iOS10 にターゲットを絞り、お話ししたいと思います。

ATSとは?

ATSは、App Transport Securityの略で、2015年にiOS9がリリースされた際に導入されたセキュリティ仕様です。
詳しい仕様は コチラ(Apple Developer Library)です。

簡単に言うと、アプリとWEBサービス間の接続のプライバシーと、データの整合性を向上を目的に、セキュリティ仕様に準拠していない接続は認めないってことです。
例えば下記とか。

サーバー証明書に関する要件

Webサーバーに関する要件

  • HTTPSについて
  • SSL/TLS のバージョンについて
  • Forward Secrecy に対応している暗号化スイートについて

2017年からは対応が必須になる

原則対応が必須になります。新規アプリ/既存アプリ問わずApp Storeに提出するには ATS有効化が必須条件 です。

対象

まぁ、ほとんど全部ですね。

  • iOS9.0以上
  • WKWebView
  • UIWebView
  • NSURLSession
  • NSURLConnection

ATSを無効化するには?

基本的に、セキュリティ仕様に準拠しとけば良いのですが、いちおう。
細かいキーの仕様についてはコチラです。

NSAllowsArbitraryLoads

  • デフォ値は No
  • Yes に設定した場合
  • NSExceptionDomains に設定したドメインのに対するネットワーク接続がATS無効化されて可能になる
  • App Storeへアプリを提出する際にAppleに対する説明が必要になる
  • (後述する)NSAllowsArbitraryLoadsInWebContentが Yes の場合、このキーは無効になる

NSAllowsArbitraryLoadsInWebContent

  • デフォ値は No
  • Yes に設定した場合
    • 下記のネットワーク接続がATS無効化されて可能になる
      • WKWebView
      • UIWebView
    • つまり、NSURLSession/NSURLConnection接続はATS有効化のまま、WebViewのみATS無効化が可能
  • iOS10以上が対象、iOS9以下については本キーを Yes にした上で、NSAllowsArbitraryLoads も設定する


(´ε`;)ウーン…

まとめ

iOS10なら、WebViewでATSを無視できるっちゃできるのね。
でも、これはAppleの独断とかではなく、セキュリティ的に安全な配信をしていこうぜって大きな流れの1つなわけで。
GoogleHTTPSサイコー!って言ってるわけだし。

ATS対応ができねーとかケチくさいこと言わずに、堂々とやってやりましょうよ!

Cycript入門 〜アプリをハックしてデバッグしてみよう〜

はじめに

この記事は、 僕が主宰する スマートデバイス向けアプリのマネタイズ研究と実践開発』ゼミの 活動記録です。

ゼミについて

株式会社サイバーエージェント アドテク本部 アドテクスタジオ内の活動です。
詳しくは、ゼミ『スマートデバイス向けアプリのマネタイズ研究と実践開発』まとめをご参照ください。

用意するもの

  • ジェイルブレイク済みのiOS端末
  • Cydiaがインストールされている

下記のドキュメントはCydiaを前提としています。

目的

Cycriptは、既存のアプリにコードを突っ込むことができるので、リリース後のアプリに対してもデバックに使えるかなと思っています。
このツールは、Objective-CJavaScriptのハイブリッドのツールらしく、ターミナルにObjective-Cのコードを入力するだけでそのアプリ内で実行することができるらしい。

目標

参加者全員が 適当なアプリのボタンやラベルの内容を外から変更する を達成する

Cycript入門

以下の操作について、ジェイルブレイク前提であり、自己責任でお願いします。

参考になったサイト

主なオペレーション

  • Cydiaを使う
  • Cycriptをインストールする
  • OpenSSHをインストールする
  • iPhoneMacからSSHでログインする
  • Cycriptでアプリを操作する
  • Process Injection
  • アプリの画面構成をハックする
  • ボタンの色やテキストをハックする
  • ボタンイベントをハックする

Cydiaを使う

CycriptやOpenSSHをインストールするのに使用します。僕の脱獄方法の場合です。 IMG_0001.PNG

Cycriptをインストールする

今回のお題でもあるこいつをインスールします。 IMG_0016.PNG

OpenSSHをインストールする

ついでにOpenSSHもインスールします。 IMG_0004.PNG

iPhoneSSHでログインする

自分のMacのターミナルから、iPhoneIPアドレスを指定してsshログインします。初期パスワードは、alpine です。

$ ssh root@[IPアドレス]
root@IPアドレス password:[alpine]
root#

Cycriptでアプリを操作する

操作したいアプリのプロセスをチェックし、cycriptで指定して起動する。
下記では、UBER を題材にすすめます。

重要 下記作業前にUBERをインストール&起動しておきます。

起動直後の画面はこんな感じ。 IMG_0011.PNG

Process Injection

cycript -pを使って、プロセスにアタッチします。

root# ps aux | grep UberClient
mobile 1660 0.0 4.4 815456 90912 ?? Us 6:49PM 0:02.64 /var/containers/Bundle/Application/E3330-CBE5-40AC-8365-66E075C6C04C/UberClient.app/UberClient
root# cycript -p 1660
cy#

アプリの画面構成をハックする

cy# UIApp.keyWindow.recursiveDescription()
@"....現在表示中の画面構成を再帰的に表示されます、結果はキャプチャのみで"

ダーッとでます スクリーンショット 2016-09-20 23.17.40.png

中央の UBER 画像をハックする

こんな感じで、オブジェクトを取得するには、画面構成からIDを探してインスタンスを生成したります。

cy# var imageView = new Instance(0x151101f30);
cy# var droidUrl = [NSURL URLWithString:@"https://andropp.jp/webapp/wp-content/uploads/2014/11/android-wallpaper5_2560x1600_1.jpg"];
cy# var droidData = [NSData dataWithContentsOfURL:droidUrl];
cy# var droidImage = [UIImage imageWithData:droidData];
cy# imageView.image = droidImage;


UBERイコン画像が消えて、droidくんになってもーたw

IMG_0012.PNG

登録ボタンをハックする

var signupButton = new Instance(0x14fe47730);
[signupButton setTitle:@"hogeeee" forState:UIControlStateNormal];


と入力すると 登録 という文字が.... IMG_0013.PNG ....hogeeee になってるw

ちなみに、登録ボタンを端末に触らずに押しちゃうには....

cy# [signupButton sendActionsForControlEvents:UIControlEventTouchUpInside];

これで、起動! IMG_0016.PNG

まとめ

iOS端末をジェイルブレイクしないといけないので、少し敷居が高い。
Cycriptを使ったハックは、既存アプリの研究を目的とした活用に向いてそう。
また、アプリ側にバックドアを意識した仕掛けを用意しておけば、強力なデバッグができそう(そんな仕掛け、怖くてアレだけど)。

iOS10でIDFAを取得できるか!?

オプトアウトした端末のIDFAは取得できない?

iOS10 アップデート以降、オプトアウトした端末のIDFAは取得できないといった情報が、巷でまことしかやに囁かれている。 僕自身の iOS10 に端末をアップデートし、検証を試みた。

検証しみてる

iOS9 まではユーザが自身の端末上でオプトアウトしても、IDFAの取得自体は可能だった。 しかし、 iOS10 アップデート(2016年9月14日 日本時間2時)以降、有効なIDFAが取得できない。 もう少し詳細に書くと、 文字列は取得できるが、一意のユーザーを表すものではない。 実際に、オプトアウトした後に取得した値は、00000000-0000-0000-0000-000000000000 というゼロパディングされた文字列が返ってきてた。

cf. ASIdentifierManager Overview 3.
Get the advertising identifier using the advertisingIdentifier property (note that when ad tracking is limited, the value of the advertising identifier is 00000000-0000-0000-0000-000000000000).

https://developer.apple.com/reference/adsupport/asidentifiermanager

iOS端末でオプトアウトするための方法

[設定] - [プライバシー] - [広告] - 「追跡型広告を制限」 をオンにする

まとめ

大抵の広告事業者は端末側でIDFAとオプトアウトフラグの両方を取得して、広告配信サーバへ投げているはず。 CV計測目的の場合、広告配信という目的の延長線上としてオプトアウトフラグの状態に関わらずIDFAを使用していると思われる。 たぶん、問題の焦点はこの世の中でオプトアウトしているユーザが何人いるのかによって、影響度合いが大きく変わるところだと思う。

Swift Advent Calendar 2014

13日目を担当しました。


Swift ハジメマシタ - Qiita

iOSの6日目に続き、今年2度目の当番日をクリアしました。
よし後は来週のAndroidでおしまいや!!

ちょうど? 注文していたSwift本が届き、これも何かの縁かな。

詳解 Swift

詳解 Swift


最近、疲れているのか

iOS Advent Calendar 2014

6日目を担当しました。

ネイティブアドのすゝめ(iOS) - Qiita


2年ぶりのAdvent Calendarですが、楽しめました。
次はSwiftAndroidの当番日までに準備しなきゃ!

僕が前の会社に入社したきっかけが、水野さんに会いに行こうと思ったからでした。
その水野さんが書いた本です!

Web API: The Good Parts

Web API: The Good Parts

↑の本を Web API のAdvent Calendarでウサ耳様がオススメしてました!