eyecatch
Wed, Jul 12, 2017

2017年夏、Selenium、ヘッドレスブラウザ

現在仕事でServiceNow上で動くアプリケーションを開発していて、それのブラウザテストをどうやろうかというのを少し考えたので、書き残しておく。 (adsbygoogle = window.adsbygoogle || []).push({}); ServiceNowとは 本題とほとんど関係ないけど、一応ServiceNowに簡単に触れる。 ServiceNowはITサービス管理のSaaS。 世界的にはITサービス管理のデファクトスタンダードとなっているが、日本ではこれから盛り上がりそうといった感じ。 アプリケーションを開発するプラットフォームとしての側面もあり、JavaScript(ブラウザ側とサーバ側両方)でServiceNowの機能を拡張し、他システムと連携させたり処理を自動化したりできる。 アプリケーションがServiceNowプラットフォームで動くので、テスト方法が悩ましい。 Automated Test Frameworkというテストフレームワークが提供されてはいるが、2017年1月にリリースされたばかりということもあるのか、機能がしょぼく、大したことはできない。 これが自前でブラウザテスト環境を作ろうと思った理由。 アプリケーションがJavaScriptなので、テストもJavaScriptで書きたい。 ブラウザテストとは ここでブラウザテストとは、稼働しているWebアプリケーションに、HTTPクライアントで接続して、レンダリングされたWebページを操作して実行する自動E2Eテストのこととする。 HTTPでWebコンテンツを取得して、HTML・CSSをパースしてレンダリングして、JavaScriptを実行するツール、つまりWebブラウザを何にするかというのと、それを自動で操作するのをどうするかというのと、テストどう書くのかということと、書いたテストをどう実行するかということと、テスト結果をどう集計してレポートするかといった辺りを考える必要がある。 Qiitaの記事「ブラウザテストツール総まとめ・2016年夏版」にブラウザテストのためのツールが色々載っている。 レイヤや目的が異なるツールがちょっとごっちゃになってる気がするけど。 SeleniumとかWebDriverとか ブラウザテストはWebDriver抜きでは語れないので、とりあえずそれについて書く。 それにはまずSeleniumについて語らなければなるまい。 ブラウザテスト創世記にはこうある。 神は「光あれ」と言われた。 するとSeleniumがあった。 神はその光を見て、良しとされた。 神はその光と闇とを分けられた。 神は光をSelenium RC (aka Selenium 1)と名づけ、 闇 をSelenium WebDriver (aka Selenium 2)と名づけられた。 (Seleniumの歴史をもっとちゃんと知りたければこの記事を読むべし。) 要は、今ブラウザテストと言ったらSelenium、Seleniumと言ったらSelenium WebDriverというわけだ。 Selenium WebDriverは、WebDriver APIでブラウザやDOMエレメントを操作するツール。 このAPIを実装したクライアントライブラリが各言語(Java、Ruby、Python、JavaScriptなど)で提供されていて、テストコードから利用できる。 APIの裏ではドライバなるものが暗躍していて、OSやブラウザのネイティブAPIを使ってブラウザを操作している。 このドライバはブラウザごと(Chrome、Firefox、IEなど)に用意されていて、その実装形式がドライバ毎に割と違っている。 例えばFirefox用のやつ(Firefox Driver)はFirefox のアドオンを使うし、Chrome用のやつ(ChromeDriver)は独立したネイティブアプリを介してブラウザを操作する。 ドライバは(基本的に)ブラウザと同じマシンにある必要があり、実行するテストコードとも(基本的に)同居している必要がある。 テストを実行するマシンとは別のマシンのブラウザでテストしたければSelenium Server (aka Selenium Standalone Server)を使う。 Selenium Serverはブラウザとドライバと同じマシンで動き、テストコードから送信されたブラウザ操作コマンドを受信してドライバに伝える、プロキシ的な働きをしてくれる。 Selenium Serverを使えば、クライアントライブラリが対応していないドライバでも利用できるというメリットもある。 Selenium Serverを使うと、オーバーヘッドはあるけどメリットが多いので、とりあえず使うようにしておけば間違いなさそう。 Selenium Serverが受け取るブラウザ操作コマンドは、HTTPでJSONデータとして送信される。 この辺りの通信は、もともとJsonWireProtocol (aka
eyecatch
Sat, Jun 10, 2017

git rebaseを図解する

この記事を読んだ、またはGitのオブジェクトモデルを理解していることを前提に、Gitの git rebase というコマンドについて説明する。 このコマンドは、コミット履歴を改変できるGit特有のコマンドで、分かり辛いGitコマンドの中でも最も分かり辛い部類のものだ。 Gitの最後の関門と言えよう。 けど、それだけに使いこなせばとても便利なものでもある。 (adsbygoogle = window.adsbygoogle || []).push({}); git rebaseがもつたった一つの機能 git rebaseにはいろんなオプションがあって、ちょっと調べただけだと、コミットを移動する機能とコミットを修正する機能の二つがあるように見えるかもしれないが、実際は単一の機能しかないシンプルなコマンドだ。 その機能とは、指定した範囲のコミットが含む変更を、別に指定したコミットのコードベースに適用するというもの。 コマンドの基本形は次のようなものだ。 $ git rebase --onto master dev bugfix このコマンドは、bugfixから辿れるコミット群から、devから辿れるコミット群を除いたコミット群が含む変更を、masterのコードベースに適用する。 と書いても分からないので図解する。 このスライドを見ると、git rebaseに指定した3つのブランチのそれぞれの使われ方が分かるはず。 git rebase --onto master dev bugfixが実行する処理をもっと正確に言うと、 bugfixをcheckoutして(i.e. HEADをbugfixにして)、 dev..HEADのコミット群が含む変更を、それぞれ仮領域にパッチとして保存して、 git reset --hard masterして、 仮領域に保存した変更を、HEADが指すコミットのコードベースにひとつひとつ順番に適用する。 上記コマンドでbugfixのところを省略すると、ステップ1のcheckoutが省略される。 言い換えると、上記コマンドは次の二つのコマンドに分解できる。 $ git checkout bugfix $ git rebase --onto master dev さらに、--onto masterを省略すると、ステップ3のreset先が変わり、devになる。 このときのコマンドの形は、 $ git rebase dev という見慣れたものになるが、これが最初に挙げた基本形の省略形だと認識しておくと応用が利く。 以下にgit rebase devの動きを細かめに図解する。 インタラクティブモード 前節のスライドに書いたパッチの適用をカスタマイズできるのがインタラクティブモードで、これは-iオプションで有効にできる。 インタラクティブモードを使うと、パッチをスキップしたり、順番を変えたり、まとめたり、分割したり、編集したりでき、またパッチとパッチの間に任意のコマンドを実行でき、例えばパッチごとにユニットテストを実行できたりする。 インタラクティブモードの使い方についてはググればたくさん出てくるのでここには書かない。
eyecatch
Tue, Apr 4, 2017

ElasticsearchでNNMiのログを見てみた

NNMiログをFilebeatで集めてLogstashで構造化してElasticsearchに入れてelasticsearch-headで見てみたけど、ログ量が少なかったせいかあんまり恩恵が感じられなかった話。 (adsbygoogle = window.adsbygoogle || []).push({}); Elasticsearchとは ElasticsearchはElastic社が開発しているElastic Stack(旧ELK Stack)というオープンソースなデータ収集分析ツール群のコア製品。 内部でLuceneを使っていて、そのためJava製。 「分散型RESTful検索/分析エンジン」と自称しているが、スキーマレスでNoSQLなドキュメント指向分散データベース管理システムとも見れる。 Elasticsearchインスタンスはノードと呼ばれ、単一または複数のノードによるシステムはクラスタと呼ばれる。 同一ネットワークに複数のノードを立ち上げると自動で相互検出してクラスタを構成してくれ、そこにデータを入れると自動で冗長化して分散配置してくれるので、堅牢でレジリエントでスケーラブルなシステムが簡単に構築できる。 Elasticsearchが管理するデータの最小単位はドキュメントと呼ばれ、これはひとつのJSONオブジェクトで、RDBにおける行にあたる。 つまり、JSONオブジェクトの各フィールドがRDBにおける列にあたる。 同種のドキュメントの集まりはインデックスと呼ばれ、これはRDBにおけるテーブルにあたる。 テーブルのスキーマにあたるものはマッピングと呼ばれ、ドキュメントのフィールドの型情報(e.g. string, integer)などを含み、Elasticsearchが自動で生成してくれる。(指定もできる、というかすべきらしい。) インデックス内ではさらにタイプという属性でドキュメントをカテゴライズできる、が、マニュアルからはタイプはあまり使ってほしくない雰囲気が感じられる。 因みに、インデックスがRDBのデータベースでタイプがRDBのテーブルと説明されることもあるが、これは古いたとえで、公式が間違いだったとしているので忘れてあげたい。 インデックスは分散処理のために分割でき、分割した各部分はシャードと呼ばれる。 シャードを冗長化のためにコピーしたものはレプリカシャードと呼ばれ、レプリカシャードにより成るインデックスはレプリカと呼ばれる。 デフォルトでは、ひとつのインデックスは5つのシャードに分割され、1つのレプリカが作成される。 インターフェースはREST APIだけ。 REST APIに検索したいドキュメントを投げると、ドキュメントのフィールド毎に自動で形態素解析とかして転置インデックス作って保管してくれる。 検索もJSONで表現したクエリをREST APIに投げることで結果をJSONで受け取ることができる。 検索は転置インデックスや分散処理のおかげで速く、またスコアリングによってより適切な結果が得られるようになっている。 今回使ったのはv5.2.1。 Logstashとは LogstashはElastic Stackに含まれる製品で、データ収集エンジンであり、データの受け取り、解析/加工、出力の三つの機能を持つリアルタイムパイプラインを構成する。 この三つの機能はそれぞれインプットプラグイン、フィルタプラグイン、アウトプットプラグインで提供されていて、プラグインの組み合わせにより様々なパイプラインを構成できる。 インプットプラグインは単位データ(一回分のログなど)を受け取り、タイムスタンプなどのメタデータを付けたりパースしたりしてイベントを生成し、パイプラインに流す。 フィルタプラグインはインプットプラグインからイベントを受け取り、設定されたルールに従って情報を拡充したり変更したり構造化したり秘匿情報を消したりしてアウトプットプラグインに渡す。 アウトプットプラグインは指定されたディスク上のパスやデータベースやアプリやサービスにイベントを書き込んだり送信したりする。 名前の通りもともとログ収集ツールだったが、今では様々なデータに対応していて、テキストログファイルの他にsyslog、HTTPリクエストやJDBCなんかの入力を受けることもできる。 Ruby(とJava)で書かれている。 今回使ったのはv5.2.2で、プラグインは以下を使った。 インプット: beats 3.1.12: Beats(後述)からデータを受け取るプラグイン。LumberjackというElastic社が開発しているプロトコルを使い、TCPネットワーク上でデータを受信する。 フィルタ: grok 3.3.1: 正規表現でパターンマッチして非構造化データを構造化するプラグイン。ログ解析の定番で、例えば、ログからタイムスタンプ、クラス名、ログメッセージを抽出したりする。組み込みのパターンが120個くらいあり、Apache HTTP Serverやsyslogのログであれば自分で正規表現を書く必要はない。 アウトプット: elasticsearch 6.2.6: Elasticsearchにイベントをポストするプラグイン。 Beatsとは BeatsもElastic Stackに含まれる製品で、データを採取してLogstashやElasticsearchに送信する製品群の総称。 libbeatというGoのライブラリを使って作られていて、以下のようなものがある。 Filebeat: ログファイルからログを取得する。 Heartbeat: リモートサービスをpingして生死監視する。 Metricbeat: OSとその上のサービスやアプリから稼動情報を取得する。 Packetbeat: パケットキャプチャしてネットワークのトラフィックを監視する。 Winlogbeat: Windowsのイベントログを取得する。 今回使ったのはFilebeat 5.2.2。 Filebeatは指定したログファイルを監視し、変更を検知してリアルタイムにログを送信してくれる。 FilebeatとLogstashが仲良くやってくれて、バッファがあふれるなどすることによるログの損失が起きないようにしてくれるらしい。 Logstashが単位データを受け取るので、ログファイルからひとつひとつのログを切り出すのはFilebeatの責務。 一行一ログなら何も考えなくていいけど、大抵複数行のログがあるのでなんとかする必要がある。 elasticsearch-headとは elasticsearch-headは3rdパーティ製(個人製?)のElasticsearchのWeb UI。 ElasticsearchのUIはREST APIしかないのでこういうものを使わないと辛い。 ElasticsearchのGUIとしてはElastic StackのKibanaが有名だけど、これは大量のログから統計的な情報を見るのに便利そうなものであって、今回やりたかった障害原因調査のためにログを細かく追うのには向いてなさそうだったので使わなかった。 実験環境 今回は単にログがどんな感じに見えるか試したかっただけなので、全部ローカルで動かして、ローカルに置いた静的なログファイルを読むだけ。 環境はWindows 7のノートPC。 ログファイルはC:\Users\Kaito\Desktop\logs\においたnnm-trace.logとnnm-trace.log.1。 これらはNNMiのメインログで、JULで出力されたもの。 NNMiは無料のコミュニティエディションのv10.00をVMのCentOSに適当に入れて採った。 ログはだいたい以下の様な一行のもの。 2017-03-15 19:09:55.896 INFO [com.hp.ov.nms.spi.common.deployment.deployers.ExtensionServicesDeployer] (Thread-2) Deploying arris-device 2017-03-15 19:09:55.923 WARNING [com.hp.ov.nms.topo.spi.server.concurrent.NmsTimerTaskImpl] (NmsWorkManager Scheduler) Skipping task execution because previous execution has not completed: [email protected] 2017-03-15 19:09:56.120 INFO [com.hp.ov.nms.disco.spi.DiscoExtensionNotificationListener] (Thread-2) Disco deployed mapping rules: META-INF/disco/rules/cards/ArrisCard.xml たまに複数行のものがある。 2017-03-15 19:13:30.872 INFO [com.hp.ov.nms.trapd.narrowfilter.NarrowTrapAnalysis] (pool-1-thread-18) ***** Hosted Object Trap Rate Report ***** Hosted object trap storm detection and suppression stage started: Wed Mar 15, 2017 19:09:00.746 PM.
eyecatch
Sun, Mar 5, 2017

Firedrop(プライベートベータ)が全く期待外れだった件

Firedropという現在開発中のサービスがある。 WebサイトのデザインをAIがサポートしてくれるサービスだ。 2016年夏のニュースを見たとき、AIがテキストコンテンツを解析してサイトを自動構成してくれ、さらにA/Bテストなどを自動でやってサイトを継続的に改善すると言う衝撃的なふれこみだったので、即座にアーリーアクセスに登録した。 それからしばらく忘れていたが、3月2日にプライベートベータへの招待メールが来たので早速試してみたら、かなりのスモールスタートをしたようで全く期待外れだった。 (adsbygoogle = window.adsbygoogle || []).push({}); Firedrop(プライベートベータ)の機能 Firedrop(プライベートベータ)では、SachaというAIがWebサイトの構築をサポートしてくれる。 こいつが実のところほとんど知性を感じない単なるチャットボットで、なるほどこれは見事な人工無脳だと感心してしまうほどだ。 Firedropのアカウントを作るとまず、Sachaとチャットしながらサイトの概要(タイトル、概要、画像など)を教えることになる。 するとSachaがざっくりとシングルページのサイトを作ってくれるので、それをまたSachaとのチャットで調整したりコンテンツ追加したりする。 チャットと言っても、基本はこちらは5,6個ある選択肢の中からセリフを選ぶサウンドノベル方式で、一応任意の文章も入力できるがあいさつするくらいしか使い道がない。 追加コンテンツはテキストと画像を渡すと自動でレイアウトしてくれるが、すごくいい感じにしてくれるというわけでもないし、むしろ画像が見切れたりするし、細かい調整はできないので、妥協できるレイアウトになるまでチェンジを繰り返すデリヘル方式を採ることになる。 デリヘルなんて利用したことないけど。 画像は自分でアップロードもできるけどFiredropが提供しているものもあって、後者のやつはSachaにキーワードを伝えるとそれっぽい画像を探してくれるあたりに唯一知性を感じる。 デザインができたらSachaに頼むとfiredrop.meドメインで公開してくれる。 (FiredropのUIのスクリーンショットを載せようかと思ったけど、プライベートベータの規約を読んだ感じだめそうだったので載せない。) 実際に作ってみた 今回実際にFiredropでGoslingsのサイトを作ってみて、できたのがこれ。 ひどい。 そもそも当初のテキストコンテンツを解析してサイトを自動構成というコンセプトはどこへ行ったのか。 GoslingsのReadmeを入力したらシャレオツなサイトをささっと作ってくれるイメージだったんだけど。 まだまだ開発中の機能がたくさんあるそうなので、GAまでにはもうちょっとなんとかなるんだろう。 あまり期待はしない。