2015年6月29日月曜日

iutest を NuGet パッケージにして公開しました

NuGet で公開しました。
パッケージインストールするだけで、すぐさま iutest を使ったテストが書けるようになりました!

パッケージ作成の備忘録
参考URL:
Past We Saw - 原文: Deep Dive into NuGet Native (Part One)
NuGet パッケージを作って公開する - しばやん雑記
Nuspec Reference

iutest の場合、インクルードオンリーなフレームワークですので、必要なのはヘッダーファイルとそのパスを通すための .targets ファイルです。
それらのファイルをパッケージングするようにした .nuspec を用意したら終わりです。

実際に書いたファイルは、以下で確認できます。
https://github.com/srz-zumix/iutest/tree/master/projects/nuget

ローカルでテスト
参考URL:
NuGet をオフラインで使用する - THE TRUTH IS OUT THERE - Site Home - MSDN Blogs

パッケージできたら、本番環境にデプロイするまえにテストしたいですよね。
NuGet のパッケージソースは、ローカルパスにも対応しています。
ツール > NuGet パッケージ マネージャー > パッケージ マネージャーの設定 > パッケージ ソース で追加することができます。


これで、ローカルパスを追加して、パッケージのインストールをすることができます。
社内向けとかプライベートなパッケージも置くことができますね。

Appveyor で自動デプロイ
参考URL:
AppVeyor で NuGet パッケージの作成とデプロイを自動化 | grabacr.nét

最初、この設定でやってみたのですが、どうやら .csproj の場合しかやってくれないっぽい。
ということで、この方法は諦め。

参考URL:
Appveyor でNuget Packageの発行を自動化する - 銀の光と碧い空

続いて、こちらを参考にして PowerShell でパッケージ作成をしました。
まず、ビルドスクリプトでパッケージを作成します。
$nuspecPath = "projects\nuget\iutest.nuspec"
Write-Output "Building NuGet package"
nuget pack $nuspecPath -OutputDirectory ".\"

iutest では、.nuspec ファイルのバージョンは手付でやるので、上書きとかはせず単純にパッケージ作成をしました。

次に Artifacts の設定でビルドで作成した .nupkg ファイルを成果物として保存します。
「DEPLOYMENT NAME」 には適当な名前を入れてください。あとで使います。


最後に、Delpoyment の設定をします。
Provider を NuGet に設定し、API Key を設定してください。
そして、その下の Artifact(s) のところに先ほど設定した 「DEPLOYMENT NAME」 を設定します。


というわけで

NuGet で公開されてます。
是非、使ってみて下さい

2015年6月22日月曜日

iutest v1.12.0 をリリースしました

C++ テスティングフレームワーク iutest v1.12.0 をリリースしました。
変更点は以下の通りです。

  • 追加
    • Matcher に MatchesRegex,ContainsRegex を追加
    • Matcher に ElementsAreArrayForward を追加
    • IUTEST_*_MATCHES_REGEXEQ,NE、IUTEST_*_CONTAINS_REGEXEQ,NE 追加
    • --iutest_filter=@filter.txt のようにファイルからフィルター指定できるように対応
    • quick_exit 対応
    • Visual Studio 2015 RC 対応
    • twilio 対応
    • Nuget パッケージ公開
  • 変更
    • IUTEST_PACKAGE v2 (多重定義制限の撤廃)
    • ElementsAreArray で要素数の一致チェックを行うように変更(以前までの ElementsAreArray は ElementsAreArrayForward に変更)
    • IUTEST_REPORT_SKIPPED を IUTEST_HAS_REPORT_SKIPPED に変更
  • 修正
    • IUTEST_MAKE_PEEP で関数ポインターの typedef をしなくてもいいように修正
    • バグ修正

今回は、正規表現 Matcher と Assertion の追加が大きな変更点です。
以前のバージョンから挙動を変更している部分もありますので、ご注意ください。


今回更新した機能の一部を紹介したいと思います。
正規表現アサーション
IUTEST(AssertionTest, MATCHES_REGEXEQ)
{
  const char test[] = "te0123st";
  IUTEST_ASSERT_MATCHES_REGEXEQ("te[0-9]*st", test);
}
アサーションとして追加したのは、以下の4つ
  • IUTEST_*_MATCHES_REGEXEQ
  • IUTEST_*_MATCHES_REGEXNE
  • IUTEST_*_CONTAINS_REGEXEQ
  • IUTEST_*_CONTAINS_REGEXNE
完全一致と部分一致それぞれ、EQとNE 2つずつです。
これらアサーションは拡張機能なので、Google Test モードでも使用できます。

また、アサーションとは別に正規表現 Matcher も追加しています。
こちらは、Google Mock 同等の MatchesRegex, ContainsRegex が使用できます。


ファイルからのフィルター指定
--iutest_filter=@filepath
のように、@ を付けてパス指定をすることでファイルからフィルターの指定をできるようにしました。
コマンドライン引数には、長さの上限があるのでとても長いフィルターを指定したい場合に役立ちそうです。
また、CI 環境でテストの推移によってフィルターを変える、というような使い方もできそうですね。


IUTEST_PACKAGE v2 (多重定義制限の撤廃)
最後は地味な修正ですが、IUTEST_PACKAGE の制限を撤廃しました。
これまで、IUTEST_PACKAGE は一つのパッケージに付き、一箇所でしか使用できませんでした。
なので、以下のようにヘッダーファイルで IUTEST_PACKAGE(pkg1) をしたら、ソースファイルでは普通に namespace pkg1 と書く必要がありました。

// ヘッダー
IUTEST_PACKAGE(pkg1)
{
}

// ソース
namespace pkg1
{
}

こらが、v1.12.0 以降からはすべて IUTEST_PACKAGE(pkg1) のように統一した書式で書けるようになります。
// ソースでもヘッダーでも
IUTEST_PACKAGE(pkg1)
{
}




今回はこれで以上となります。
Twilio 対応、NuGet 対応については、別途ブログに書いてますので、そちらを参照してください。
ブログズミ: Twilio を使ってみた - その5

NuGet は次週。それでは。


2015年6月16日火曜日

[C++] Private な関数のテスト

本記事で扱うテスティングフレームワーク
Google Test
iutest (Google Test ライクなヘッダーオンリーテスティングフレームワーク)

C++ でテスト書いていると問題になるのが、private なメンバー関数をどうテストするか、です。
成功法としては、テストクラスを friend することです。
間違っても #define private public などとしてはいけません。

friend
Google Test の場合、テストクラスを friend する FRIEND_TEST マクロが用意されています。
また、テストフィクスチャクラスに対して friend 宣言すれば、そのテストケースではアクセス可能になります。

参照: GoogleTestでprivateメンバ関数をテストする | Geospatial屋
詳しいことは参照先を見ていただくとして、簡単に使い方を例として示します。

例1: FRIEND_TEST
// テスト対象クラス
class Hoge
{
   FRIEND_TEST(HogeTest, A); // TEST(HogeTest, A) から見えるようにする
   FRIEND_TEST(HogeTest, B); // TEST(HogeTest, B) から見えるようにする
private:
   int GetA() { return 1; }
   int GetB() { return 2; }
};

// テスト
TEST(HogeTest, A)
{
   Hoge hoge;
   ASSERT_EQ(1, hoge.GetA());
}
TEST(HogeTest, B)
{
   Hoge hoge;
   ASSERT_EQ(2, hoge.GetB());
}
テスト毎に FRIEND_TEST しないといけないので、ちょっと面倒ではありますが private メンバーにアクセスできるようになります。
例では書きませんでしたが、テストフィクスチャを使った場合(TEST_F)でも使用できます。
(※ 型付けテストでは使用できません。)

例2: friend TestFixture
2番目の方法は、テストフィクスチャクラスを friend する方法です。
// テスト対象クラス
class Hoge
{
   friend class HogeTest; // HogeTest フィクスチャーに対して friend
private:
   int GetA() { return 1; }
   int GetB() { return 2; }
};

// テスト
class HogeTest : public ::iutest::Test 
{
protected:
    Hoge hoge;
    // アクセサを書く
    int GetA() { return hoge.GetA(); }
    int GetB() { return hoge.GetB(); }
};
TEST_F(HogeTest, A)
{
    ASSERT_EQ(1, GetA());
}
TEST_F(HogeTest, B)
{
    ASSERT_EQ(2, GetB());
}
テストフィクスチャが必要になるので、TEST(Hoge, A) のようなテストには使えませんが、
FRIEND_TEST の時とは違ってテストケースすべてに対してアクセスを許可することができるので、使い勝手は良いです。

ただ、テストフィクスチャクラスでアクセサを書く必要があります。これは Google Test がテスト毎にテストフィクスチャを継承したクラスを定義しているからです。
とはいえ、一度テストフィクスチャを定義してしまえば使い回しが可能ですし、テストコード側の変更だけでテストを追加できるのが、この方法のメリットでしょう。

iutest でも、もちろん上記方法が使えます。

Google Test の問題
Google Test が用意している FRIEND_TEST マクロは、型付けテストには使えません
template<typename T> をつければいいだけなので、以下のようにマクロを追加すれば OK です。

#define FRIEND_TYPED_TEST template<typename T>FRIEND_TEST

iutest は、FRIEND_TYPED_TEST に対応済みです。

プロダクトコードに変更を加えない方法
さて、friend を使った方法は、プロダクトコード側に friend 宣言をする必要がありました。
その程度の記述は大したことないかもしれませんが、やはりプロダクトコードを1行も変えずにアクセスできたら便利ですよね。
(テスト名を書かないといけないのも個人的には面倒だなと思います。)

iutest では非侵入的に private メンバーにアクセスする方法を提供しています。


// テスト対象クラス
class Hoge
{
private:
   int GetA() { return 1; }
   int GetB() { return 2; }
};

typedef int (Hoge::* HogePrivateFunc)(); // iutest v1.12.0 からは typedef 不要になります
IUTEST_MAKE_PEEP(HogePrivateFunc, Hoge, GetA);
IUTEST_MAKE_PEEP(HogePrivateFunc, Hoge, GetB);

// テスト
IUTEST(HogeTest, A)
{
   Hoge hoge;
   IUTEST_ASSERT_EQ(1, IUTEST_PEEP_GET(hoge, Hoge, GetA)());
}
IUTEST(HogeTest, B)
{
   Hoge hoge;
   IUTEST_ASSERT_EQ(1, IUTEST_PEEP_GET(hoge, Hoge, GetB)());
}

なんか記述量増えてるし、マクロやばそうと思われる方もいると思いますが、
この方法であれば、完全にプロダクトコードを汚すことなく private なメンバーのテストが書けます。

private メンバーにアクセスする方法は、こちらで紹介されている方法を使いました。
privateメンバに外部から非侵入的にアクセスする - redboltzの日記 (archive)
 (追記: Wayback Machine にアーカイブが残っていた)

いや~凄いですね。
さて、来週に iutest v1.12.0 のリリースを予定してます。
正規表現アサーションの他、いろいろ更新されてますのでよろしくお願いします。

2015年6月8日月曜日

Twilio を使ってみた - その5

「Twilio を使ってみた」シリーズ5回目です。
これまでは"電話"を扱ってきましたが、今回は SMS を使ってみたいと思います。

SMS はトライアルアカウントでは使えません。
残念です。が、私はかなり前にトライアルアカウントが切れたため、アップグレードしてます。
ブログズミ: Twilio の無料トライアル期間が終了
せっかく使えるようになったのだから~、というわけで今回は SMS をやります。

REST API
前回に引き続き、RESET API を使います。
SMS を送る API は、こちら。
Twilio Cloud Communications - APIs for Voice, VoIP, and Text Messaging

以下は、サンプルのソースコードです。
# Download the Python helper library from twilio.com/docs/python/install
from twilio.rest import TwilioRestClient
 
# Your Account Sid and Auth Token from twilio.com/user/account
account_sid = "AC5ef8732a3c49700934481addd5ce1659"
auth_token  = "{{ auth_token }}"
client = TwilioRestClient(account_sid, auth_token)
 
message = client.messages.create(body="Jenny please?! I love you <3 data-blogger-escaped-from_="+14158141829" data-blogger-escaped-media_url="http://www.example.com/hearts.png" data-blogger-escaped-message.sid="" data-blogger-escaped-pre="" data-blogger-escaped-print="" data-blogger-escaped-to="+15558675309">
電話と掛けるときとの違いは、messages.create を使うとこと url 指定ではなく送信したいメッセージを body に直書きするとこです。 あとは、media_rul の指定もできますが今回は扱いません。
SMS の制限

https://twilio.kddi-web.com/function/sms/
050番号ではSMSをご利用になれません。電話番号購入メニューから「アメリカ」の電話番号をご購入の上、ご利用ください(現在、SMS サービスはアメリカ番号のみでの提供です)。
というわけで、050 番号では SMS を使えないので、電話番号を購入しました。
電話番号の購入
電話番号の購入を開くと、まず最初に電話番号の検索ページが出ます。


今回は、SMS を使うのが目的なので、 United States を選びます。
条件に SMS を指定して、検索。


番号がたくさん出てくるので、好きな番号を選んで購入ボタンを押します。
以下のような画面が出るので、「Buy This Number」を押して購入は完了です。


これで、SMS が使える電話番号を手に入れられました。

実装
早速、iutest の twilio 連携ツールに組込みました。
https://github.com/srz-zumix/iutest https://github.com/srz-zumix/iutest/blob/master/tools/twilio/iutwilio.py
sms オプションを使ってテスト結果を SMS で通知できます。


2015年6月1日月曜日

[Jenkins] Groovy でマトリックス生成

追記: この記事には誤りがあります。詳細は記事末尾の追記をご覧ください。

Jenkins のマトリックス構成ジョブでマトリックスをもっと柔軟に作成したいことってありませんか?

例えば、特定のラベルが付いている すべてのスレーブ でテストを実行したい場合、該当するスレーブで軸を作ることになります。
ラベルで軸を作ると、1つのマトリックスしかできないので1回のビルドで実行されるスレーブも1つで、しかもどのスレーブが選ばれるかもわかりません。


欲しいのはこれじゃないです。
目的は、1回のビルドで該当するスレーブすべてで実行することです。
正攻法だと、該当するスレーブを自分で判断して登録していくことになると思います。

該当スレーブが少なければいいのですが、
たくさんあったり、スレーブの設定がよく変わったりする場合は、とてもメンドクサイです。
そこで、GroovyAxis plugin を使いましょう!

GroovyAxis
GroovyAxis plugin ではその名の通り、Groovy script でマトリックスの軸を設定できます。

まずは、プラグインマネージャーからインストールをしてください。
インストールするとマトリックス構成プロジェクトの設定の「軸の追加」に、「GroovyAxis」が追加されます。


これを選ぶと下のような設定が追加されるので、「Groovy Expression」に Groovy を記述します。


サンプル
基本
GroovyAxis のルールとして、配列を return する必要があります。そして、その配列要素が軸になります。
まずは、簡単なサンプルで動作を確認してみましょう。
def result = []
(1..3).each {
   result += "Axis"+it
}
return result
上記スクリプトを Groovy Expression に記入してください。
その下の「Test the Groovy script」ボタンで実行結果を確認できますので、保存する前に確認しておくとよいでしょう。

保存すると、以下のように Axis1,Axis2,Axis3 の3つのマトリックスができます。


すべてのスレーブ
冒頭の目的を達するには、スレーブの情報を知る必要があります。
まずは、スレーブを列挙し、それをマトリックス化します。
def result = []
def jenkins = hudson.model.Hudson.instance
def slaves = jenkins.slaves
slaves.each {
    result += it.getSelfLabel().getName()
}
return result

特定のラベルがあるスレーブ
次に、ラベルを参照し、目的のラベルがあったらマトリックス化します。
def result = []
def jenkins = hudson.model.Hudson.instance
def slaves = jenkins.slaves
slaves.each { slave ->
    slave.getAssignedLabels().find {
        if( it.getName() == "vs2015" ) {
            result += slave.getSelfLabel().getName()
            return true
        }
    }
}
return result

これで、冒頭の目的が達成出来ました。
Groovy script からは色んな情報を参照できるので、他にも面白い使い方ができると思います。
是非、試してみてください。

さらに便利に…
さてこのマトリックですが、スレーブのラベルを付け替えたり、スレーブを増減させた時に、自動で追従させたいと思いませんか?

できたらいいですねー・・・



・・・すみません。わかりません。
今のところ、「設定ページを開いて保存をする」というのを手作業でやる必要があります。
誰か方法を知っていたら教えてくださいm(__)m


追記
意図したスレーブで実行されてませんでした!!
大変申し訳ありませんでした

どうやら、スレーブの軸ではなく、ユーザー定義の軸と同じ挙動のようで、スレーブ軸の設定として Groovy Axis は使えませんでした。
こちらも、解決策がないかもう少し調べてみます。

追記2 - 回避策
根本的な解決とはいかないが、回避策を書いておきます。

組み合わせフィルターを使う


  1. スレーブ軸を追加し、可能性のあるスレーブをすべてチェックする
  2. 組み合わせフィルターを有効にする
  3. フィルターの式を「label==label2」のように、スレーブ軸名==GroovyAxis名とする
設定は以上です。


余分なマトリックスができてしまいますが、目的は達成できます。
(見た目がかなり悪いですが、対象外のスレーブは未実行になってます。)

Matrix Groovy Execution Strategy Plugin を使う
Matrix Groovy Execution Strategy Plugin は、GroovyAxis Plugin とは違い、組み合わせフィルターのところで Groovy script が使えます。


  1. スレーブ軸を追加し、可能性のあるスレーブをすべてチェックする
  2. 組み合わせフィルターを有効にする
  3. 実行方法を「Groovy Script Matrix Executor Storategy」に変更
  4. Groovy Script に以下のようなスクリプトを記述

def list = []
def slaves = jenkins.slaves
slaves.each { slave ->
    slave.getAssignedLabels().find {
        if( it.getName() == "vs2015" ) {
            list += slave.getSelfLabel().getName()
            return true
        }
    }
}

combinations.each {
    if( list.find { l -> it.label == l } ) {
         result[it.label] = result[it.label] ?: []
         result[it.label] << it
    }
}

execution.listener.logger.println result

return result


ビルド結果はこんな感じです。フィルターよりもすっきりしましたね。
また、この方法であればスレーブの設定が変わった場合にも追従が可能です。

とりあえず、今回は Matrix Groovy Execution Strategy Plugin を使った方法を採用したいと思います。