クラシックASPのコーディング考慮点 その4
ASPとWSHの関数の共用
ASPでは、「<%」と「%>」で囲んでコードを記述し、「#include」(SSI)で共通関数が記載されているファイルをインクルードして使うことが多い。
こうしてしまうと、WSHで同じ機能の関数を使いたい場合に、vbsのファイルにコピペして組み込むなど再利用するのに手間がかかってしまう。
やはり、WSHでも簡単に使えるように同じファイルをインクルードして使いたい。
こういう場合は、拡張子wsfでxml形式で記述すれば、ほかのファイルを取り込むことができる。
wsfファイルの書き方(WSH)
sample.wsf
<?xml version="1.0" encoding="utf-8"?> <job id="sample"> <script language="VBScript" src="sample.inc"></script> <script language="VBScript"> <![CDATA[ Option Explicit Dim s s = Foo("paramter") WScript.Echo s ]]> </script> </job>
sample.inc
Function Foo(sPara) Foo = "Foo called. Parameter:" & sPara End Function
インクルード方式の変更(<% %> から <script server=server>タグへ)
インクルードしたいファイルに、<% %>が使用されているので、これを取り除く必要がある。 そのため、共通関数から<% %>を取り除き、ASPのインクルードする方式を、SSIから <script language="VBScript" runat="server"> に変更する。
変更前ASP (SSI版)
<%@ LANGUAGE=VBScript %> <!-- #include file="../common/inc/common.inc" --> <% Dim s s = "テスト" %> <html> <!-- 省略 --> </html>
変更後ASP (script runat=server)
<%@ LANGUAGE=VBScript %> <script language="VBScript" src="../common/inc/common_vbs.inc" runat="server"></script> <% Dim s s = "テスト" %> <html> <!-- 省略 --> </html>
script runat=serverに変更するときの注意点
<% %>とscriptタグの関数定義の順番違う。
scriptタグに変更してわかったが、<% %>に定義されている関数のほうが先に処理される。
例えば、「Function Foo()」という関数がASP側の<% %>の中(①)とscriptタグでインクルードするファイル(②)の両方に定義がある場合、②のほうが有効になる。
単体テスト方法 (ScriptUnit)
scriptタグによる関数を別ファイルに定義することができたので、別ファイルに定義した関数の単体テストがしやすくなる。
JUnitのようなUnit Testフレームワークとして、VBScript(JScript)用にScriptUnitがあったのでこれを使ってみる。
ScriptUnit:http://xt1.org/scriptunit/
ScriptUnitのコマンドライン
scriptunit /Q フォルダもしくはファイル名 /log results.xml
/Q: GUIを表示しない
/log: xml形式のログを出力。指定しておかないと結果がわからない。
戻り値:Test NGのものがあっても、「errorlevel」は0だった。grepするなどしてエラーがあるかのチェックが必要。
フォルダを指定したとき、指定フォルダ配下のvbsファイルが処理対象となる。サブフォルダは対象とならなかった。
テスト対象
「Test」で始まる関数。大文字小文字区別なし。
サンプル
Sub setup() 'テストごとの初期処理 'assert.trace "setup" End Sub Sub teardown() 'テストごとの終了処理 'assert.trace "teardown" End Sub Sub TestSample1() Dim s s = "111" assert.Equals s, "111", "111 expected" End Sub Sub TestNothing() Dim o Set o = Nothing Assert.IsNothing o 'Nothingのテスト End Sub Sub TestSomething() Dim o Set o = CreateObject("Scripting.Dictionary") Assert.IsSomething o 'オブジェクトのテスト End Sub Sub TestErrRaise() Dim x ' エラー発生のテスト。 ' 事前にエラーメッセージの一部をExpectErrorで設定しておく。 'assert.ExpectError "0 で除算しました。" assert.ExpectError " で除算しました" x = 1 / 0 Assert.Error "ここに来たらおかしい。" End Sub
2015/09/12 追記
ScriptUnitの制限・注意事項
- WScriptオブジェクトが使えない。
- wsfが使えない。
単体のvbsファイルしか使えないので、aspのUnitTestには不向き。
2015/09/14 追記
vbslibというライブラリがあり、こちらのほうが目的に合致している。
関連
- ASPのエラーハンドリング、グローバル変数の集約、処理テンプレート化
http://umejan.hatenablog.com/entry/2015/08/08/234631 - ASPの入力値の復元、javascriptのエスケープ処理
http://umejan.hatenablog.com/entry/2015/08/09/123859 - ASPでのログ出力方法
http://umejan.hatenablog.com/entry/2015/08/27/011503 - vbscriptの単体テスト(unit test)
http://umejan.hatenablog.com/entry/2015/09/14/203940