検索
リンク
タグ
ASP.NET
.NET
ASP.NET MVC
F#
Visual Studio
Azure
ASP.NET Core
ライトニングトーク
Plone
Selenium
AJAX
C#
jQuery
SQL Server
ADO.NET Entity Framework
JavaScript
WebMatrix
EFCore
LINQ
Fizz-Buzz
カテゴリ
最新の記事
最新のコメント
記事ランキング
最新のトラックバック
以前の記事
2024年 03月 2024年 02月 2024年 01月 2023年 12月 2023年 11月 2023年 10月 2023年 09月 2023年 08月 2023年 07月 2023年 06月 2023年 05月 2023年 04月 2023年 03月 2023年 02月 2023年 01月 2022年 12月 2022年 11月 2022年 10月 2022年 09月 2022年 08月 2022年 07月 2022年 06月 2022年 05月 2022年 04月 2022年 03月 2022年 02月 2022年 01月 2021年 12月 2021年 11月 2021年 10月 2021年 09月 2021年 08月 2021年 07月 2021年 06月 2021年 05月 2021年 04月 2021年 03月 2021年 02月 2021年 01月 2020年 12月 2020年 11月 2020年 10月 2020年 09月 2020年 08月 2020年 07月 2020年 06月 2020年 05月 2020年 04月 2020年 03月 2020年 02月 2020年 01月 2019年 12月 2019年 11月 2019年 10月 2019年 09月 2019年 08月 2019年 07月 2019年 06月 2019年 05月 2019年 04月 2019年 03月 2019年 02月 2019年 01月 2018年 12月 2018年 11月 2018年 10月 2018年 09月 2018年 08月 2018年 07月 2018年 06月 2018年 05月 2018年 04月 2018年 03月 2018年 02月 2018年 01月 2017年 12月 2017年 11月 2017年 10月 2017年 09月 2017年 08月 2017年 07月 2017年 06月 2017年 05月 2017年 04月 2017年 02月 2017年 01月 2016年 12月 2016年 11月 2016年 10月 2016年 09月 2016年 08月 2016年 07月 2016年 06月 2016年 05月 2016年 04月 2016年 03月 2016年 02月 2016年 01月 2015年 12月 2015年 11月 2015年 10月 2015年 09月 2015年 08月 2015年 07月 2015年 05月 2015年 04月 2015年 03月 2015年 02月 2015年 01月 2014年 12月 2014年 11月 2014年 10月 2014年 09月 2014年 08月 2014年 06月 2014年 04月 2014年 03月 2014年 02月 2014年 01月 2013年 12月 2013年 10月 2013年 09月 2013年 08月 2013年 07月 2013年 06月 2013年 05月 2013年 04月 2013年 03月 2013年 02月 2013年 01月 2012年 12月 2012年 11月 2012年 10月 2012年 09月 2012年 08月 2012年 07月 2012年 06月 2012年 05月 2012年 04月 2012年 03月 2012年 02月 2012年 01月 2011年 12月 2011年 11月 2011年 10月 2011年 09月 2011年 08月 2011年 07月 2011年 06月 2011年 05月 2011年 04月 2011年 03月 2011年 02月 2011年 01月 2010年 12月 2010年 11月 2010年 10月 2010年 09月 2010年 08月 2010年 07月 2010年 06月 2010年 05月 2010年 04月 2010年 03月 2010年 02月 2010年 01月 2009年 12月 2009年 10月 2009年 09月 2009年 07月 2009年 06月 2009年 05月 2009年 04月 2009年 03月 2009年 02月 2009年 01月 2008年 12月 2008年 11月 2008年 10月 2008年 09月 2008年 08月 2008年 07月 2008年 06月 2008年 05月 2008年 04月 2008年 03月 2008年 02月 2008年 01月 2007年 12月 2007年 11月 2007年 04月 2007年 03月 2007年 02月 2007年 01月 2006年 11月 2006年 10月 2006年 09月 2006年 08月 2006年 07月 |
2013年 12月 17日
※本稿は Selenium Advent Calendar 2013 の投稿記事です。
起Selenium は言わずと知れた(?)、Webアプリケーションに対する自動化テストを実現するための様々なソフトウェア群。 とくにここでは、各種OS・各種プログラミング言語からWebブラウザを "自動操縦" する、一般に Selenium WebDriver と呼ばれる機能に焦点を当てた話題をとりあげる。 さてその Selenium。 実際の業務において、C# で記述した品質検査用プログラムが Web ブラウザを自動操縦するところで活用している。 承そんなある日、とある不具合にぶちあたった。自動化テスト対象のとある Web アプリにおいて、しかるべき操作の結果、ある HTML 要素に対して CSS による背景画像が設定されたかどうかを点検するコードを実装していた。 具体的には、以下のようなコードで background-image CSS属性を取得し、その設定値(文字列)が「url("http://host/image.png")」であることをチェックしていた。 var val = webDriverところが、この自動化テスト、ブラウザとして IE と FIrefox を使ったときには正しくパスするのに、 Google Chrome を使ったときはテストが失敗してしまう のだ。 しかし改めて手動で操作してみてブラウザ上の表示を人の目で見てみるぶんには、Chrome でも正しく背景画像が表示されているように見える。 にもかかわらず、自動化テストコードは、Chrome で実行した場合に限り、「そんな背景画像は設定されていない」と判定されてしまうのだ。 転待てよと思い直し、まずはブラウザに備え付けの F12 開発者ツールウィンドウを広げて、コンソール上から点検してみることにした。そこで各ブラウザで以下の JavaScript を走らせてみたのだ。 $("#target").css("background-image")するとなんということか、結果として返ってくる CSS スタイル文字列に相違があったのだ。 Chrome では以下のような文字列となっていた。 url(http://host/image.png)しかし IE と Firefox では以下のように 画像の URL がダブルクォーテーションで囲われていた のだ。 url("http://host/image.png")自分が書いたテストコードは、IE で実行しながら完成したものであったため、それで IE と Firefox のときは成功し、しかしダブルクォーテーションを含まずに返す Chrome の場合は、ダブルクォーテーションを含む期待値と完全一致はしないため、不一致によるテスト失敗となっていたわけだ。 結ということで、幸い、原因が究明できたため、background-image CSS 属性の値を検証するときは、正規表現ベースで値を確認しつつ、ダブルクォーテーションをなしに正規化してから一致比較するよう、テストコードの実装を改善した。var m = Regex.Match(val, @"^url\(""?(? #
by developer-adjust
| 2013-12-17 21:06
| Selenium
|
Comments(0)
2013年 12月 15日
※本稿は PowerShell Advent Calendar 2013 / 15日目の参加記事です。
PowerShell Advent Calendar にかれこれ3回も参加しておいて言うのもなんだが、実を言うと、長年、PowerShell は食わず嫌いだった。 しかし Windows OS の世代交代も進み、Windows OS に標準で PowerShell がインストールされるようになったなどの各種事情により、社内の IT インフラの自動化に、渋々と PowerShell の使用を推進し始めた。 社内 IT インフラ関連の作業を自動化するにあたって、いわゆる "スクリプティング" 言語の需要は以前からあった。 ビルドが要らず、ソースとビルド済みバイナリの二重管理が不要なスクリプティング言語は、小さな作業の自動化をガンガン推し進めるにあたって、大変やりやすい。 にもかかわらず PowerShell を敬遠していたのは、コード補完、いわゆる "インテリセンス" が備わったエディタ環境がなかったためだった。 それで F# スクリプトなどを活用していた歴史がある。 しかしそれも今は昔。 いざ覚悟を決めて現代の PowerShell を使ってみると... バリバリにインテリセンスが効く ではないか。 おかげさまで、今はすっかり PowerShell が大好きになってしまった :) 凄いと思ったインテリセンス その1PowerShell では、拡張子 .ps1 のファイルに PowerShell のコードを書いておくことで、その .ps1 ファイル名を指定することで実行できる。例えばテキストエディタで下記の内容を保存した foo.ps1 があるとすると、 echo "bar"PowerShell コンソールで「.\foo」と入力して Enter すれば、foo.ps1 が読み込み・実行され、コンソールに「bar」と表示される。 Windows OS/MS-DOS における古き良きバッチファイル (.bat) と同じようなものだ。 さてところで、PowerShell は近代のシェル環境・スクリプティング言語にふさわしく(?)、その .ps1 ファイルにおいてどのようなコマンドラインスイッチを受け付けるかを、.ps1 ファイルの冒頭で宣言できる。 具体的には param という構文を使う。 こんな感じ。 # foo.ps1冒頭の param 構文によって foo.ps1 は -Upper スイッチを持つことが宣言されている。 これにより、 >.\fooを実行すれば「bar」が、 >.\foo -Upperを実行すれば「BAR」がコンソールに表示される。 とまぁ、ここまでは PowerShell によるコマンドラインスイッチの解析の仕組みの話。 ここからが本題。 ここで、PowerShell コンソールで「.\foo」とまで入力して、半角スペース、ハイフンとまでタイプし、そこで Tab を打鍵すると... 「-Upper」と補完されるではないか! ちゃんと .ps1 ファイルの内容を先読みして、Tab 補完してくれるのだ。 上記の例ではスイッチがひとつだけだが、いくつもスイッチがある場合は、Tab キーを続けて打鍵することで候補が順繰り次々表示される。 また、PowerShell の純粋なコンソールではなく、「PowerShell ISE」という PowerShell 専用の「統合開発環境」みたいなツールにおけるコマンドウィンドウからだと、ハイフンを押した時点で、いわゆる "インテリセンス" として候補が GUI としてリスト表示される。 このように自作のシェルスクリプトファイルについても、コマンドラインスイッチの Tab 補完・インテリセンスが機能するのは大変便利だ。 自作のシェルスクリプトとはいえ、本数が結構増えてきたため、いちいちコマンドラインスイッチに何があるか覚えていられない。 なのでこの機能は大変便利である。 さすがの F# スクリプトでもここまでの芸当はできない。 凄いと思ったインテリセンス その2小さな作業の自動化のひとつに、Microsoft Word の自動化なども行っている。PowerShell から、COM、昔でいうところの ActiveX Automation 経由で MS Word を "自動操縦" して、自動化を果たすわけだ。 ちなみに、COM との相互運用は PowerShell に限らず、Windows OS 上で動作する様々な処理系で可能だ。 C# や C++、VB は然り、F# でもちろんのこと、さらには Windows 版の Ruby や Python にだってできる。 しかし PowerShell における COM との相互運用は、Tab 補完・インテリセンスの面においてほかの処理系とは一味違う。 ここでは PowerShell コンソール上で直接作業するのではなく、PowerShell ISE 上での話とする。 まず、Microsoft Word を COM 経由で起動する PowerShell コードは下記だ。 $msword = New-Object -Com "Word.Application"上記を PowerShell ISE のスクリプトエディタ(コマンドウィンドウではなく)に入力したとしよう。 ここで次の行で「$msword.」とドットまで打つと... まだ何も起きない。 上記コードで文字列で Microsoft Word の COM 世界における "ID" を指定していることからもお察しいただけるとおり、これはレイトバインディング(遅延バインディング、実行時解決)なのである。 基本原理として、ソースコード上に記されたメソッド名やプロパティ名を文字列として IDispacth.Invoke するだけなのだ。 (正確には DISPID を問い合わせて...という話になるのだが割愛) なので、インテリセンスが効かなくても無理はない。 ...と思いきや。 PowerShell ISE では、F8 キーによって、キャレットがある行や、選択範囲をコマンドウィンドウ上で実行することができる。 ということで、「$mswword = ...」の行を F8 でいったん実行してしまう。 代償(?)として、実際に Micorosft Word が起動されるのだが、その見返りに、なんと、 インテリセンスが機能し始めるのだ! コード上だけでは型情報を取りようのない遅延バインディングなコードでも、実際に PowerShell ISE 内で部分実行して、そのオブジェクトインスタンスが実体化すれば、そのオブジェクトに対して持ってるメンバを問い合わせして、インテリセンスを表示できる、という仕掛けなのだろう。 しかも PowerSell ISE が提供してくれるこのインテリセンス、 ツールチップで引数や戻り値の情報も表示 される。 このおかげで、Microsoft Office 系アプリの COM 経由での自動操縦を記述するには、F8 による部分実行しながら PowerShell コードを書き進めれば、ほかのドキュメント類を参照することなく多少うろ覚えであってもどんどん書き進められる。 まとめということで。その昔、PowerShell v1 をいじって「学習コストをかけたくない自分には、インテリセンスのない処理系は体にあわない」と思い込んでいた。 ところが、現代の PowerShell は下手な動的言語よりインテリセンスバリバリなので、これを活用しない手はないと思う次第であった。 #
by developer-adjust
| 2013-12-15 12:39
| その他IT系
|
Comments(0)
2013年 12月 10日
※本稿は Selenium Advent Calendar 2013 の投稿記事です。
起Selenium は言わずと知れた(?)、Webアプリケーションに対する自動化テストを実現するための様々なソフトウェア群。 とくにここでは、各種OS・各種プログラミング言語からWebブラウザを "自動操縦" する、一般に Selenium WebDriver と呼ばれる機能に焦点を当てた話題をとりあげる。 さてその Selenium。 実際の業務において、C# で記述した品質検査用プログラムが Web ブラウザを自動操縦するところで活用している。 承そんなある日、とある不具合にぶちあたった。自分の開発マシン上では正常に動作する Selenium 利用による自動化テストシナリオが、品質検査担当者の環境ではなぜか失敗するのだ。 ログを確認すると、シナリオの途中で "Webページ上のあるボタンをクリックせよ" というステップがあるのだが、そのボタンクリックが動作していないことがわかった。 自分の開発マシンでは正しくクリックされるのに、品質検査担当者による模擬環境ではクリックされない。 Selenium WebDriver による Web ページ上の要素のクリックなんぞは、あまりに基礎的な機能なだけに、どんな不具合が一体あるというのか想像も難しくしばし途方に暮れた。 転と、ふと品質検査担当の模擬環境とで佇んでいるブラウザの様子に目を留めると...クリック対象のボタンが、見えてはいるのだが、 半分くらいスクロール領域外にはみ出していた のだ。 解像度が異なる自分の開発環境では、そのボタンは、きっちりクライアント領域内にすべて収まっていた。 まさか、まさか、 たった半分ほどスクロールアウトしていることが原因 なのか? ということで、クリック処理を次のように書き換えてみた。 var element = webDriver.FindElement(By.Id(idOfElementToClick));LocationOnScreenOnceScrolledIntoView プロパティを "参照" しているところがミソ。 LocationOnScreenOnceScrolledIntoView プロパティを参照することにより、対象の要素をスクロール領域内にまでスクロール位置を進めたうえで、その座標が取得できる。 要素の座標には興味はないが、 対象要素を確実にスクロール域内まで引き込んでくれる のが狙い。 そのうえで要素のクリックを実行するわけだ。 結結果、問題のボタンクリックが確実に動作するようになった。 なお、今回遭遇したこの問題は、すべてのブラウザに対して発生するかどうかは不明。 自分が掌握している限りでは、IE8 では発生していた。 いずれにせよ、これで誰の環境でも、以前より安定して Selenium による自動化テストが実行されるようになった。 #
by developer-adjust
| 2013-12-10 00:07
| Selenium
|
Comments(0)
2013年 12月 05日
※本稿は One ASP.NET Advent Calendar 2013 / 5日目の参加記事です。
ASP.NET の Minify & Bundle 機能ASP.NET MVC にまつわる話。Minify & Bundle とは?ASP.NET MVC4 から、JavaScript および CSS の Minify & Bundle 機能が提供されるようになった。Minify 機能は、JavaScript や CSS を、ブラウザが解釈/実行するにあたっては不要な空白や改行を削ったり、変数名や関数名を短い名前に付け替えたりして、そのファイルサイズを小さく削減する機能。 Bundle 機能は複数の JavaScript や CSS を一つのファイルのように見せて、1回の HTTP 要求でひとまとめにブラウザに返す機能である。 こうすることで、少ない通信量と通信手順で JavaScript や CSS をブラウザに渡すことができ、速度向上が見込めるというわけだ。 Minify や Bundle を実践するには、事前に Minify や Bundle を行うツールがいろいろ流通している。 別段、ASP.NET MVC4 を待つ必要はない。 しかし ASP.NET MVC4 が提供する Minify & Bundle 機能は、実行時にそれら処理を行うという点で大変便利だ。 実行時に動的に Minify & Bundle する ASP.NETそもそも「Minify & Bundle する」という明示的な作業が要らない。統合開発環境などが提供する機能によって、.css ファイルの保存と同時に Minify された .css を自動生成される便利環境も目にする(Visual Studio Pro以上の拡張機能にもあったりする)。 しかし オリジナルの .css ファイルと Minify 版の .css ファイルの双方をバージョン管理に追加する手間と煩雑さは変わらないことであろう。 さらには、開発/デバッグ中はオリジナル版を、リリース環境では Minify & Bundle 版を参照するようにするには、「事前に Minify & Bundle を実施」方式ではなかなかつらいものがあるのではないだろうか。 ASP.NET MVC4 による Minify & Bundle 機能は、これらの課題を解決してくれる。 やり方次のような JavaScript、foo.js とbar.js があったとしよう。※コードを読み解く必要はない。分量と雰囲気が掴めればOK。 // foo.js // bar.jsこれを Minify & Bundle するには以下の手順となる。 まず、ASP.NET Web アプリケーションが起動するタイミングで1回でいいので、 - どういったファイルを Minify & Bundle するのか、 - 及びどういう URL でその Minify & Bundle されたリソースを参照するのか、 を ASP.NET の Minify & Bundle 機構に登録する。 具体的には、Global.asax.cs で定義される Application クラスの Start イベントコールバック ( App_Start メソッド ) 内で以下のように実装すればよい。 BundleTable.Bundles.Add(次にこうして Minify & Bundle されたリソースを参照したい Razor ビュー (.cshtml) では、先に Minify & Bundle 機構に登録した URL を引数に指定して、System.Web.Optimizatio.Scripts クラスの Render メソッドを呼び出して、script タグを生成すればよい。 @Scripts.Render("~/bundles/foobar") そうすると、まず一般的な開発環境で実行すると、@Scripts.Render("~/bundles/foobar") と記述された箇所は、下記のとおりなんの変哲もない2つの script タグとして出力される。<script src="/Scripts/foo.js"></script>ここで web.config 中の compilation セクションの debug=true の設定を debug=flase に書き換えて再実行すると、@Scripts.Render("~/bundles/foobar") の出力が以下のように、単一の script タグに変化する。 <script src="/bundles/foobar?v=S0oL9G83-ZH6naQPl4k7q0..."></script>この URL による GET 要求の応答内容は以下のとおり、 foo.js と bar.js の中身がくっついた、かつ、 不要な空白と改行が除去され可能なかぎり変数名が短縮された JavaScript コードが返されるのだ。 var message=message||{};(function(n){n.foo="Foo1"})(message);message=message||{},※コードを読み解く必要はない。先のオリジナルの foo.js, bar.js からの変化が掴めればOK。 Minify & Bundle 結果をオフラインキャッシュするさてこのように大変便利な Minify & Bunlde 機能。これを、HTML5 の オフラインモードに応用することも可能だ。 HTML5 オフライン対応にあたっては、まず、cache.manifest という URL に対して、ネットワーク接続がなくてもあらかじめブラウザのキャッシュ内に取り込みしておいて使えるようにしておきたいリソース ( .js や .css や HTML ページやそのほか HTTP 経由で取り寄せる諸々 ) を所定の書式で列記したテキストを返すようにしておく。 そしてオフライン対応させたい HTML ページの html 要素に、manifest 属性として cache.manifest を指定しておく。 <html manifest="cache.manifest">詳細は割愛するが、これら処置に加えて、オンライン/オフラインの検出とオフラインキャッシュの鮮度チェック & 更新を行う若干の JavaScript コードを加えればオフライン対応の Web アプリができあがる。 そして、この cache.manifest に、Minify & Bundle された JavaScript や CSS を指定することもできるのだ。 そのためには、cache.manifest を ASP.NET の仕組みにて動的に返すようにする必要がある。 cache.manifest を ASP.NET MVC のビューで生成するもっとまともなやり方がきっとあると思うのだが、自分が実現できたやり方を以下に記す。まず、ASP.NET Web アプリケーション起動時のルーティング登録にもうひとつルーティングを付け加えて、"cache.manifest" という URL が要求されたら、所定の MVC コントローラ/アクションが呼び出されるようにしてみた。 routes.MapRoute(さて普通は、cache.manifest などという URL は静的ファイルハンドラによって処理しようとされ、ファイルとしては実在しないので HTTP 404 Not Found になってしまう。 そこでこの要求を ASP.NET のパイプラインに確実に流し込むよう、web.config に以下の記述を付け加える。 <system.webServer>次に、cache.manifest への HTTP 要求で呼び出される MVC コントローラ/アクションだが、こちらは実質何もしていない。 単にビューの描画を返すだけだ。 public class HomeController : Controller 肝心なのはこのアクションの結果返される Razor ビュー。 AppManifest.cshtml になるわけだが、この Razor ビュー内で、System.Web.Optimization.Scripts クラスの Url メソッドを使うのだ。 CACHE MANIFEST ※ Scripts.Render メソッドではない。Render メソッドだと、HTML5オフラインキャッシュマニフェストとしては余計な "<script>" タグにくるまれた文字列が返されるため。 こうすることで cache.manifest への要求で返されるコンテンツは、 CACHE MANIFESTとなり、foo.js と bar.js が Minify & Bundle されたコンテンツを要求し、オフラインキャッシュに収録するようになるわけだ。 オフライン対応Webアプリ開発で本領発揮するASP.NET!オフラインキャッシュはキャッシュ最優先!さて HTML5 のオフラインキャッシュだが、cache.manifest で指定されキャッシュされたリソースは、たとえネットワークがオンラインであっても再読み込みされない。そう、再読み込みされないのだ。 Ctrl + F5 によるスーパーリロードも無駄である。 例えば、cache.manifest が以下のように記述されていたとして、 CACHE MANIFESTこのマニフェストを含む Web ページをいちどロードしキャッシュ取り込みに成功したとする。 するとその後は、foo.js および bar.js を変更しても、ネットワークのオンライン/オンラインにかかわらず、決して再読み込みされずに、キャッシュされているコンテンツが使われてしまうのだ。 再読み込みのためには cache.manifest を更新するではどうすれば、サーバー側で変更された foo.js, bar.js をブラウザに再読み込みさせるかというと、cache.manifest の内容を変更する必要があるのだ。※尚、実際には、ブラウザ側 JavaScript にて、ネットワークがオンラインのときは明示的に cache.manifest が新しくなっていないかチェックする処理を予め実装しておく必要がある。 本質的には、foo.js の変更を反映する目的のためには、cache.manifest を書き換えることに意味は無い。 只々、キャッシュを破棄して再読み込みしてもらわんが為だけに、cache.manifest を何とか変更する必要が発生するのだ。 他所で見かけた手法は、cache.manifest 中に、 CACHE MANIFESTみたいなコメント行 ( cache.manifest では行頭が # から始まる行はコメントとみなされる ) を加えておき、foo.js を変更したら、この Etag 部分の英数字の羅列を違う羅列に書き換える、というものだ。 しかしだ。 こんな手法は、とりわけ開発中は面倒この上ない。 加えて、バージョン管理システムに、本質的でない、cache.manifest の変更履歴が commit されてしまう。 それ、ASP.NET MVC が解決してくれます!その点、ASP.NET MVC の Miify & Bundle の仕組みは大丈夫。先ほどの例でいくと、foo.js と bar.js を Minify & Bundle した内容を返す URL は MANIFESTとなる(@Scripts.Url("~/bundles/foobar") の出力結果)わけだが、ここで joo.js なり bar.js なりを書き換えると、上記 URL のクエリ文字列部分が変化するのだ (下記)。 CACHE MANIFESTすなわち、 foo.js の変更にともなって、cache.manifest が自動的に書き換わる わけだ。 このように ASP.NET MVC の Minify & Bundle 機能を経由して、cache.manifest でオフラインキャッシュ指定しておけば、 HTML5 オフライン対応した Web アプリ開発も超楽ちん なのである。 ...でも少しハマった orz実を言うと、上記までの手順を丁寧に再現するだけではまだうまくいかない。Content-Type 応答ヘッダの指定cache.manifest への HTTP 要求に対する応答では、Content-type 応答ヘッダが text/cache-manifest である必要がある。そこで、AppManifest.cshtml 中に C# コードブロックを書き加えて、以下のように ContentType 応答ヘッダを明示的に指定してやる必要がある。 .ContentType = "text/cache-manifest"; レイアウトページの不使用、だが謎の空行が...!さらに、たいていの ASP.NET MVC アプリケーションでは、_ViewStart.cshtml 等によって「レイアウト」ページが既定で指定されているはずだ。cache.manifest ではレイアウトページの自動適用はいい迷惑なので、これを断ち切る必要がある。 最初は AppManifest .cshtml に以下のように書き加え、レイアウトページは使わないようにしてみた。 @{ ところが、である。 どうしてか、こうして実装した cache.manifest の第1行目に空行が入ってしまうのだ。 cache.manifest の仕様として第1行目は "CACHE MANIFEST" ではじまることと規定されている。 そのため、無用な空行が第1行目に存在していると、ブラウザ側で "parse error" などと console に出力されて、マニフェストとして読み込んでくれないのである。 専用のレイアウトページを用意してとりあえず回避原因を深く追いかけていないのでなぜ空行が入ってしまうのかわかっていない。とりあえずの回避として、AppManifest 専用にレイアウトページ「AppManifest_Layout.cshtml」を作成した。 CACHE MANIFESTで、ApManifest.cshtml はこうである。 @{なんだか若干こんがらがりそうな構成になってしまった。 しかしとりあえずこれで謎の空行は発生しなくなり、無事、期待どおりの動作となった。 cache.manifest への応答を返す実装がどうにもスマートではないので、ASP.NET の達人に添削していただき、よりよい解を求めたいところではある。 実際のソースコード事例一式とりあえずこの実装で HTML5 オフラインを利用している事例として、"Turtle Graphics Do It!" を挙げておく。ソースコードは GutHub で公開中。 https://github.com/jsakamoto/turtle-graphics-do-it このブログ記事では割愛してしまった、オフライン/オンライン状態の検出と、オンライン時のキャッシュマニフェストの更新チェックの JavaScript 実装も、上記ソースコードから調べることができる。 以上、One ASP.NET Advent Calendar 2013、5日目用の投稿である。 明日は、驚異の「全部オレ(orワタシ) Advent Calendar」を実践中の強者達の一人、@miso_soup3 さんの番である。 #
by developer-adjust
| 2013-12-05 08:04
| .NET
|
Comments(0)
2013年 12月 03日
Selenium Advent Calendar 2013 への投稿。
Selenium は言わずと知れた(?)、Webアプリケーションに対する自動化テストを実現するための様々なソフトウェア群。 とくにここでは、各種OS・各種プログラミング言語からWebブラウザを "自動操縦" する、一般に Selenium WebDriver と呼ばれる機能に焦点を当てた話題をとりあげる。 さてその Selenium。 実際の業務において、C# で記述した品質検査用プログラムが Web ブラウザを自動操縦するところで活用している。 そんなある日、とある不具合にぶちあたった。 自分の開発マシン上では正常に動作する Selenium 利用による自動化テストシナリオが、品質検査担当者の環境ではなぜか失敗するのだ。 ログを確認すると、シナリオの途中で "Webページ上のあるボタンをクリックせよ" というステップがあるのだが、そのボタンクリックが動作していないことがわかった。 自分の開発マシンでは正しくクリックされるのに、品質検査担当者による模擬環境ではクリックされない。 Selenium WebDriver による Web ページ上の要素のクリックなんぞは、あまりに基礎的な機能なだけに、どんな不具合が一体あるというのか想像も難しくしばし途方に暮れた。 と、ふと品質検査担当の模擬環境で佇んでいるブラウザのステータスバーに目を留めると... ... ズーム倍率が 105% になっている! 人間が見た目には、ズーム倍率が 105% になっても、ページが拡大表示されているとはなかなか気づけない。 だがしかし、もしかしてこれが原因で、要素のクリックに失敗しているのではないかと推測し、ズーム倍率を 100% にリセットして自動化テストシナリオを実行したところ... 無事成功した! ということで、以後、指定の URL にナビゲーションする際は、以下のコード (C#) によってキーボードからの「Ctrl + 0」押下をエミュレートし、ブラウザのズーム倍率を 100% にリセットする処理を常に実行するようにした。 webDriver これで誰の環境でも、以前より安定して Selenium による自動化テストが実行されるようになった。 #
by developer-adjust
| 2013-12-03 08:04
| Selenium
|
Comments(0)
|
ファン申請 |
||