uzullaがブログ

uzullaがブログです。

低レベのマクラーもエクセルマクロをユニットテストするやで

エクセルとかよくわからない!(挨拶)


業務PCの9割にははいってそうなエクセルのマクロですが、私みたいな所にも、たまに「○○集計するマクロかいてよ」とか、「前任者が行方不明になったこのマクロをちょっと修正したいんだけど」というオーダーがきます。
いわれてググりながら書く程度のマクラーなので、正直VBSとか普段全然かかないしわからない。Redimってワードがこわい*1


という無意味な低レベ、アピールからはじめさせていただきます!

さて、テストしたい

「uzullaさん、あのね、この○年前に保守した集計処理マクロにクレームついてるの」
「マジですか、まったくもう覚えてないですけど…、とりあえずどこがおかしいんですか?」
「先方から正誤表がきたので、送ります」
「オオゥ…(XXXX行ある)」


「見たはずの要求仕様書に見覚えがないくらい過去のマクロや…、えー、これ本当にこんなにバグって…ないぞ?」
「あれ、これ仕様書の通りでは?」


しかし、このリストされた全部を手動で正誤確認してたら夏がおわってまう…。
しかも、今回がんばってこなしても、また4年後に「違うのでは?」とかいわれて、あれ、デジャヴ?、というエンドレスサマー感もでかねない。


ということで即答するために自動テストしたい。

ユニットテストの意味は?

まあ、今回どうしてもユニットテストである意味は正直無い感。
そもそもユニットテストできるほどユニット化されてないマクロです。
しかしなにも考えず「ユニットテストしたいやで!」って気軽に書いたら本当にあるみたいだった、世の中はすごい。

まずTwitterでVBAUnitをsongmuさんに紹介いただいて、しらべたら「ウッ、これは結構つらいやつでは…」と躊躇していたら、

ここの所お世話になっている@matarillo さんから http://d.hatena.ne.jp/miau/20110301/1298935505 を紹介いただき、都合3種類くらいツールを知る。

大変ありがとうございました。

3種の神器紹介

詳細は各ライブラリ自体や、上の紹介URLを見ていただくとして、個人的な感想です。

VBAUnit

http://sourceforge.net/projects/vbaunit/
基本的にOSやExcel側になにもインストールせず、ライブラリのクラスファイル群をエクセルマクロとしてロードしたらつかえる。
ただ、先方に返すときにいちいち剥がす手間を考えるとなやましい。ざっとしらべた感じ結構めんどうそうで、ちょっと古い。

xlUnit

http://www.blog.methodsinexcel.co.uk/2010/03/30/unit-testing-excel-vba-xlunit-demo/
エクセルにアドオンインストールしてつかう。
非常に細かな制御や結果レポート作成ができるようなのだが、説明動画をみるかぎり、テストとテストされるワークブックを別にもつなど、設計や思想を理解するのに時間がかかりそうだった。
ガンガンテストする人ならこれがよさそうだが、自分はもっとイージーなものを求めていたので後回しに。*2

VB Lite Unit

http://sourceforge.net/projects/vb-lite-unit/
インストール必要で、配布されているDLLを、皆おなじみregsvr32で登録したらつかえる。
参照可能なライブラリファイルにVBLiteUnitが追加されるので、参照(インポート)すると、テスト用の既定クラスがつかえるようになり、それを継承してテストのクラスを書く。

イミディエイトウインドウでダイアログ起動するとか、みたことないやり方だが、実行結果画面が実にそれらしいし、グリーンバーがでるあたりがなんか親しみがもてましたので、一番手っ取りばやそうなこれにしました。

VB Lite Unitでとりあえず、目指せグリーンバー!

ちなみに、試した環境はWindows 2000 + Office 2000です。2000パワーズ
「お前なんで2013年も下期にな(略」ごめんなさい、これが先方環境らしいので、これでやらないといけないんです許してください。

インストールについて

http://sourceforge.net/projects/vb-lite-unit/
DownloadしたZipを解凍して、適当な場所に設置し

C:\Documents and Settings\Administrator>regsvr32 "c:\program files\vb-lite-unit-1.2.5-binary\vbliteunit.dll"

などとすればインストールは完了です。*3

とりあえず起動

適当に新規ブックを作成して、メニューのツール>マクロ>Visual Basic Editorでエディタを起動。
エディタのメニューのツール>参照設定でダイアログをひらき、「VbLiteUnit」を選択します。
これがなかったら上のDLL登録ミスってるでしょう。

とりあえずテストクラスを書く

0から書くのはつらいので、とりあえずテンプレ使うのが幸せになるでしょう。
https://gist.github.com/kawakawa/4199931
こちらのGistが私が参考にしたテンプレです、有用です。
http://kawakawa2000.jugem.jp/?eid=22
こちらで解説、xlmでも配布されていました。


まずエディタ左上のプロジェクトペインにて、右クリ>挿入>クラスモジュールで空のクラスを作ります。
新しくできたクラスモジュールをダブルクリックしてひらき、左下のプロパティペインにて、オブジェクト名を適当にします。ここではmyNumTestとしておきます。

あとはテンプレをこのクラスにペーストします。
ペーストしたら、テンプレにある「'自テストClass名を記載」の行の「ClassTest」をmyNumTestに書き換えます。

とりあえずAssertを書く

「'ここにテスト処理記載」
の所にassert文を書きます。
なんもかんがえないで頭わるい感じですが

AssertEqual 1, 1, "first"

と記述します。(「その2」以降はとりあえず消しました)


ここまででテストを実行する用意ができました

とりあえず実行

イミディエイトペインを開きます。
メニュー>表示>イミディエイトウインドウを選択すると、下部にイミディエイトというペインがひらきます。
ここはCtrl+Gでもオープンできます。


イミディエイトに

RunTests New myNumTest

といれて、「その行末で」Enterします。
すると即時評価されて、ウインドウがひらき、結果が表示されます。やった!
みたらEscで消せるので、楽ですね。

あとはまあ適当に…

適当にテストケースを追記したり、こわれたアサートをつっこんだりすれば、大体わかるかんじですね、特に普通のエクセルマクロと違う所はなさそう。

雑感

あとは、当然このクラスにずらずらと書くとすぐにデブお化けコードになりますので、好きにぶったぎったり、外部クラスや関数に書き出ししていけばよいのではないでしょうか。


まあー、今回触るマクロは私以外もいじるらしいので、勝手にリファクタして怒られたくもなく、あくまでテストランナーと、テストコードを外にきりわけたいがためにつかう感じです。ああ〜便利だ!でもそれはユニットテストとはいわないのでは!(正論)
まあなんかユニットテストっていっとけばオシャレ感ありますのでいいんじゃないですかね(適当)


というか、私はVBSでOOPができると知らなくて*4わりとエッって感じでしたね、継承とかできんの、すごい、Implementとかはじめてみたぞ。しかしプロパティのところにクラス名書くの斬新だな…。


皆さんもエクセルマクロ書く事あるでしょう、お役に立てば幸いです。
私は、できるだけCSVで保存しなおして、Perlで処理したいですね!(切実)

テストといえば?ルビー文化ですよね!

もう飽きてきたんですけど、宣伝です。

http://sugamasao.hatenablog.com/entry/2013/08/11/121217
知り合いがすばらしげなルッビーの本をかきましたので、エクセルでバグ票をまわすようなお仕事をしている人(俺だ)もしていない人も、是非どうぞ。

*1:いまどき可変長じゃないだと…(可変長もあるらしいけど)

*2:どうでもいいけど、Outlookもテストできるぜなどとあり、なんだそりゃそんな所でガンガンマクロを書く業務があるのか…と恐怖を感じたりした

*3:「アドミン垢で操作すんなボケ」、ごもっともでございます

*4:クラスモジュールって見てはいたけど、そのクラスだと思ってなかった