PowerShellからウェブアプリテスト用のフレームワークWatiNを読み込んでウェブアプリのテストプログラムを書こうとしているのだが、これが一筋縄ではいかない。二重、三重の問題が立ちはだかる。
まずはWatiNをダウンロードしてWatiN.Core.dllをPowerShellに読み込む。そしてIEを立ち上げてURLに行くという単純な作業をしたいと思い、まずは下のようなコードを書いてみた。ちなみにこのスクリプトはTest.ps1というファイルに保存し、アセンブリが入っているbinフォルダに入れてある。
[System.Reflection.Assembly]::LoadFile((Join-Path (Get-Location) "\WatiN.Core.dll")) $ie = New-Object WatiN.Core.IE $ie.GoTo(http://www.devslife.com)
すると次のようなエラーが出る。
New-Object : Exception calling “.ctor” with “0” argument(s): “Could not load file or assembly ‘Interop.SHDocVw, Version
=1.1.0.0, Culture=neutral, PublicKeyToken=null’ or one of its dependencies. The system cannot find the file specified.”
At D:\Scripts\WatiN\bin\Test.ps1:2 char:17
+ $ie = New-Object <<<< WatiN.Core.IE
+ CategoryInfo : InvalidOperation: (:) [New-Object], MethodInvocationException
+ FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand
なるほど。PowerShell.exeが入っているフォルダ内(C:\Windows\System32\WindowsPowerShell\v1.0)にInteropアセンブリが入っていないからなのだ。Interop.SHDocVw.dllをPowerShell.exeと同じフォルダ内にコピーするか、再コンパイルをして厳密名をアセンブリにつけるかだがとりあえずPowerShell.exeと同じフォルダにInteropアセンブリをコピーすることにする。PowerShellコンソールを再起動して再びスクリプトを実行すると・・・
今度は下のようなエラーが・・・
New-Object : Exception calling “.ctor” with “0” argument(s): “The CurrentThread needs to have it’s ApartmentState set t
o ApartmentState.STA to be able to automate Internet Explorer.”
At D:\Scripts\WatiN\bin\Test.ps1:2 char:17
+ $ie = New-Object <<<< WatiN.Core.IE
+ CategoryInfo : InvalidOperation: (:) [New-Object], MethodInvocationException
+ FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand
て、手ごわすぎるぞ。でも上のエラーは完全にWatiNから意図的に投げ出されたものなのでちょっと希望の光が見えてきた。エラーによるとIEの自動化を行うにはスレッドがApartmentState.STAにセットされていなければいけないと。つまりPowerShellをApartment.STAにセットしなければいけないのか。そこでググってみるとPowerShellチームブログに到着。なんとカスタムアセンブリをこしらえてそれによってSTAにセットせよと。おっしゃあ、こうなったら意地でやってやる。
まずはPowerShellチームブログにあったカスタムCmdletをコンパイルしてそれをインストール。インストールの仕方はこのブログで一度紹介しているので参考にしていただきたい。インストールするとInvoke-Apartmentというコマンドレットが利用可能になる。それを使用してTest.ps1ファイル内のPowerShellスクリプトを実行するのだ。
Invoke-Apartment "STA" ([System.IO.File]::ReadAllText("Test.ps1"))
これを実行したらちゃんとIEが立ち上がってURLに行くことができたのだ。これでPowerShellからWatiNを使うことができる。
これは蛇足なのだが、上のコマンドでテキストファイルを読みだしているだけなのにどうしてGet-Contentコマンドを使わなかったというとGet-Contentが行ごとのObject配列を返してくるのでInvoke-Apartmentの二つ目のパラメータのString型と合わないために上のようにした。
あー苦労した。上のことを踏まえてなんとかもっと簡単にWatiNをPowerShellから使えるようにできないものだろうか。
これってどうしてもPowerShellでウェブアプリテストしたいという人には役立ちそうなので英語でも書いてみることにする。
コメント