22 Sep 2012, 22:20

C言語でのgcovカバレッジ計測結果をJenkinsで表示させる

C言語でのカバレッジ計測結果をJenkinsで表示させる方法について調べてみた。

2つの方法があるみたい。

  1. lcov + HTML Publisher plugin で出力

    Hudsonの使い方21 Hudsonでユニットテスト網羅率測定(C言語)

  2. gcovr + Coberturaプラグイン で

    Jenkinsでテストとカバレッジの結果をグラフ表示できるようにする

    Jenkins を iOS アプリ開発に導入してみた (gcov編)

今回は2番目の方法で試してみた。 流れとしては以下のとおり。

C言語のプロダクトコード

↓(gcov)

カバレッジデータ

↓(gcovrでCobertura形式のXML出力)

XMLカバレッジ結果

↓(Jenkins Cobertura Plugin)

Jenkinsて結果出力

C言語の定番カバレッジツール gcov でカバレッジを計測する

まずはC言語の定番カバレッジツール gcov でカバレッジを計測してみる。

Cygwinではデフォルトでgcovコマンドがある。

gcovを使うためには、コンパイルをするときに、以下のコンパイルオプションをつける必要がある。

-fprofile-arcs -ftest-coverage

Makefileをいじるときは、以下を追加すればよい。

CFLAGS += -fprofile-arcs -ftest-coverage
LDFLAGS += -fprofile-arcs

すると、.gcno というファイルができる。 実行ファイルを実行すると、.gcdaというファイルができる。

これが、カバレッジ計測結果データ。次に、これをXML形式に変換する。

gcovrでXML形式のカバレッジ結果を出力する

gcovrとは、gcovでの出力結果を編集して出力してくれるツール。

Jenkinsで結果を見るにはCoberturaと呼ばれるXMLフォーマットに変換する必要がある。

まずは、以下からダウンロードする。 公式のページはココPythonで記述されたコードなので、適切なことろに保存する。(/usr/local/bin/とか)

gcovr

コマンドラインからだと、以下のコマンドで取得

wget https://software.sandia.gov/trac/fast/export/2799/gcovr/trunk/scripts/gcovr

保存したら、実行権限を与える。

chmod u+x gcovr

gcovrは以下の形式で実行する。

gcovr --xml --output=(出力ファイル名).xml (ディレクトリ名)

サンプル

gcovr --xml --output=gcovr_result.xml src/  

これで、XMLファイルができた。次はこれをJenkinsで出力する。

Cobertura PluginでJenkins上でカバレッジ結果を見る

まずは、Cobertura PluginをJenkinsにインストールする。

[Jenkinsの管理] > [プラグインの管理] から Cobertura Pluginを選択して、インストール。

カバレッジ出力するための設定は、[設定] > [ビルド] で、gcovrのコマンドを追加する。

ちなみに、Windowsバッチコマンドだと以下のようなコマンドを追加したら動いた。 gcovrの前にpython2.6.exeを入れると動くが、 gcovrだけだったり、python gcovrだと動作しなかったりするのがナゾ。

python2.6.exe gcovr --xml --output=gcovr_result.xml src/

[ビルド後の処理] に [Cobertura カバレッジレポートの集計] という項目が追加されているので、選択。

Cobertura XMLレポート パターンという項目に、xmlファイル名を追加する。

(カスタムワークスペースを設定していない場合はパスも込で)

image

これで、ビルドを実行すればカバレッジが表示される。

カバレッジ表示結果

プロジェクト画面に[カバレッジレポート]という画面が現れる。

カバレッジはここで見ることができる。

image

22 Sep 2012, 01:02

JenkinsでGoogleTestのテスト結果を表示する方法を調べてみた。

GoogleTest(gtest)のテスト結果をJenkinsで表示する方法を調べてみた。

GoogleTestで出力されるXML出力結果はJUnitのフォーマット(junitreport Ant タスク)

にもとづいているため、Jenkinsに取り込んで解析することができるらしい。

GoogleTestのテスト結果をXML形式で出力する

テスト実行時に、以下のオプションとともに実行するとxML形式でテスト結果が出力される。 –gtest_output=xml:(ファイル名)がオプションだ。

[text](プログラム).exe 窶堵test_output=xml:(出力ファイル名).xml[/text]

こんな感じでXML出力される。


<testsuites tests="3" failures="0" disabled="0" errors="0" time="0.012" name="AllTests">
  <testsuite name="MockNumTest" tests="3" failures="0" disabled="0" errors="0" time="0.006">
    <testcase name="return1" status="run" time="0" classname="MockNumTest" />
    <testcase name="return2" status="run" time="0" classname="MockNumTest" />
    <testcase name="return3" status="run" time="0" classname="MockNumTest" />
  </testsuite>
</testsuites>

XML形式のテスト結果をJenkinsで表示する

次はjenkinsの設定。ジョブの設定画面を開く。

[プロジェクトの高度なオプション] > [カスタムワークスペースの使用]

にチェックを入れて、テスト出力ファイルのディレクトリの指定。

[ビルド]を選択して、ビルドを実行するための方法を選択。

ここでは、Windowsバッチコマンドで実行する。

[text]

cd “C:\Users\hogehoge\Dropbox\src\mock_study”

make clean

make

target.exe –gtest_output=”xml:test_result.xml”

[/text]

Windowsバッチコマンドがでmakeができないときは、

WindowsサービスでJenkinsを立ち上げるのをやめるとよい。

参考:WindowsバッチファイルをJenkinsで起動したらネットにアクセスできないツꀀ

[ビルド後の処理] > [JUnitテスト結果の集計]を選択。テスト結果ファイル名を入力。

image

テスト出力結果

こんな感じで出力された。

image

参考リンク

GoogleTest – 上級ガイド – XMLレポート

19 Sep 2012, 23:32

速聴自動化!UWSCで速聴変換をオートメーションしてみる

前回の続き。

クラウド速聴!フリーソフト『Lilith』でNHKニュースを3倍速で聴いてみる。

NHKニュースの速聴変換はルーチンワークなので、速聴変換を自動化してみた。

以下のサイトを参考にしました。

マウス、キーボードの自動操作: 高速再生ニュースの薦め

 

 

 

 

使用したのは、UWSCというフリーソフト。PC操作を記録して、再生できるソフトだ。

UWSC 窶錀 Vector

前回のエントリで紹介した一連の操作を、記録機能で記録して、マクロとして保存。

あとは、それを実行すると、自動で速聴変換済みの音声ファイルが

クラウド上にアップロードされる。

17 Sep 2012, 11:54

はてブ新着記事をタグ指定サムネイルつきの抜粋で表示する

はてなブックマークの新着記事をタグ指定のRSSで取得する方法を調べてみた。

まずはURLで取得してみる

以下の形式で取得できる。

http://b.hatena.ne.jp/t/(タグ)?sort=hot&threshold=1&mode=rss

ボイント1: &threshold=(数字)で、収集するはてブの数を指定できる。

ボイント2: (タグ)の名前はパーセントエンコード(URLエンコード)でのUTF-8で書かないと認識されない。

変換したいパスをそのままChromeのURLに貼り付けたら変換された。

このサイトで変換できるみたい。

URLエンコード・デコードフォームツꀀ

具体例

例えば、睡眠のタグがついたはてブで、3フォロー以上はこんな感じだ。

http://b.hatena.ne.jp/t/%E7%9D%A1%E7%9C%A0?sort=hot&threshold=3&mode=rss

取得したRSSを記事に表示する

次は、取得したRSSをWEBページに表示する。

wordpressを使えば、カンタンに表示できた。参考にしたのは、以下のサイト。

複数外部RSSフィードをWordPressで表示 | 簡単ホームページ作成支援-Detaramehp


 

 

set_cache_duration(1800);
    $rss->init(); 
    $maxitems = $rss->get_item_quantity(3); 
    $rss_items = $rss->get_items(0, $maxitems); 
    date_default_timezone_set('Asia/Tokyo');
endif;
?>


No items.</dt>'; else foreach ( $rss_items as $item ) : ?>
get_feed()->get_title(); ?>
get_title(); ?>
(get_date("Y-n-j H:i:s"); ?>)

set_cache_duration(1800);

$rss->init();

$maxitems = $rss->get_item_quantity(3);

$rss_items = $rss->get_items(0, $maxitems);

date_default_timezone_set(‘Asia/Tokyo’);

endif;

?>

<archives/hp if ($maxitems == 0) echo ‘

No items.

‘;

else

foreach ( $rss_items as $item ) : ?>

get_feed()->get_title(); ?>

set_cache_duration(1800); $rss->init(); $maxitems = $rss->get_item_quantity(20); $rss_items = $rss->get_items(0, $maxitems); date_default_timezone_set('Asia/Tokyo'); endif; ?>

No items.</dt>'; else foreach ( $rss_items as $item ) : ?>
get_title(); ?>
get_description()), 0, 100); ?> ・・・ 続きを読む (get_date("Y-n-j H:i:s"); ?>)

<archives/hp include_once(ABSPATH . WPINC . ‘/feed.php’); $rss = fetch_feed(array( ‘http://b.hatena.ne.jp/t/%E7%9D%A1%E7%9C%A0?sort=hot&#038;threshold=3&#038;mode=rss'

)); if (!is_wp_error( $rss ) ) : $rss->set_cache_duration(1800);

$rss->init();

$maxitems = $rss->get_item_quantity(3);

$rss_items = $rss->get_items(0, $maxitems);

date_default_timezone_set(‘Asia/Tokyo’);

endif;

?>

<archives/hp if ($maxitems == 0) echo ‘

No items.

‘;

else

foreach ( $rss_items as $item ) : ?>

get_permalink(); ?>’ target=”_blank”>

get_title(); ?>


 

 

wordpressだとカンタンだぁ。

15 Sep 2012, 01:19

電子書籍の英語学習に衝撃!EnglishJournalの『uListening』に感動した!

追記 2013年3月31日 :
なんとEnglishJournalの電子書籍は2013年3月で終わってしまったらしい。これからはEnglishJournalをわざわざ裁断してiPadに入れなければいけないかと思うと悲しい(泣)

※『ENGLISH JOURNAL』電子版は2013年3月号をもって、販売を停止させていただきます。ご愛読ありがとうございました。http://www.alc.co.jp/elearning/app/ulis/

アルク社の英語学習用の雑誌、EnglishJournal(EJ)を購読しはじめてから、3年目。

おととしは、1000時間ヒアリングマラソンに参加して、スタートで石につまずいた。
この2年間でTOEICの点数が150点下がり、妹にも弟にも点数を抜かされて、
さらには会社のお昼休みにTOEICの勉強をしてたりすると、
『英語できるだーすごいねー』というパワーハラスメントを受けて、
心が痛む今日この頃です。

今までは、定期購読をしていたので、
月に一度送られてくる雑誌を裁断機とScanSnapでPDF化して、
iPadに入れて電車の中で勉強していた。
今回、定期購読の期限が切れたことでようやく足かせが外され、
EnglishJournalの電子書籍版を購入してみた。

スマートフォン用アブリ『uListening』でEJが電子書籍で読める!

EnglishJournalの電子書籍は、iPhone/iPadアプリ 『uListening』から購入できる。
口コミや評価はカスタマーレビューを。

個人的には、EnglishJournalが電子書籍化されているだけで、とても嬉しい。
なにしろ、今までは毎月20分かけて雑誌を裁断機でバラバラにしてScanしていた手間が、
省けるのだから。

しかも、EnglishJournalは一ヶ月読んだらほとんど読み返さないから、
捨てるのも大変だった。電子書籍なら、場所も取らないのでよし!

EJは人気映画俳優を結構インタビュー記事に取り上げることが多いので、
映画を見たあとにEJの過去記事を探したりしたけれど、これがまた大変だった。
電子書籍ならば、すぐに検索できる!

以下、心のなかで『パネエ!』とこっそり叫んだ機能を列挙してみる。

  • iPhone/iPadの両方で閲覧・リスニング可能!
  • テキストをクリックした場所からリスニング可能!
  • 調べたい単語は『英辞郎』で検索・単語帳登録可能!
  • リスニング時間計測可能!
  • リピート機能で聞き取りにくい単語を繰り返しチェック可能!

iPhone/iPadの両方で閲覧・リスニング可能!

iTsuneで購入するため、iPhone/iPadの両方でダウンロードが可能だ。
スキマ時間のリスニングはiPhoneで、スペースに余裕のなる電車内ならばiPadで、
という使い分けができることが嬉しい。

今までは、雑誌に付属していたCDをiPodに入れ直していたが、
その手間も省けて、とても効率的だ。

IMG_1770

ダウンロードすると、こんな感じで『リスニングツール』と『ブックビューア』の2種類が現れる。リスニングツールはリスニングに特化したテキスト。ブックビューアが、EJを電子書籍したものといった感じだ。

iPhoneでブックビューアを読もうとすると、字が小さくてなかなかきついものを感じた。

テキストをクリックした場所からリスニング可能!

IMG_1773

リスニングツールで、リスニング用テキストをタッチすると、
タッチした場所からリスニングを開始することができる。

今までは、テキストで聞き直したい場所があったら、
iPodをクルクル回して該当箇所に飛んでいたのだが、
そんな行為は今となってはサルのようだ。

調べたい単語は『英辞郎』で検索・単語帳登録可能!

IMG_1774

分からない単語が出てきた時、
iPhoneアプリ『英辞郎 on the WEB for iPhone』で調べることができる。

英辞郎 on the WEB for iPhone

『英辞郎 on the WEB for iPhone』には単語登録機能がついているので、
調べて復習したい時は、このアプリで単語帳をカンタンに作成できるのだ。

中学生の頃、100円ショップで暗記カードを買ってきて、
一枚一枚カードを作成していた行為が、今となっては原始人のようだ。

リスニング時間計測可能!

IMG_1771

リスニング時間を計測する機能もついている。
ヒアリングマラソンをしていたときは、一日のリスニング時間を別アプリで計測していたが、
これがなかなか面倒だった。一元管理できるのが嬉しい。
これと、ヒアリングマラソンのWeb画面が連携すれば便利なのに。

 <a href="http://px.a8.net/svt/ejp?a8mat=1ZZMRF+28DLRE+2NA+1THGTT&a8ejpredirect=http%3A%2F%2Fshop.alc.co.jp%2Faffiliate%3Fcnom%3Da8net%26code%3Ds00000000343010%26afurl%3Dhttp%3A%2F%2Fshop.alc.co.jp%2Fcourse%2FH4%2F" target="_blank"><br /><img border="0" alt="" src="http://www25.a8.net/svt/bgt?aid=120915195135&wid=004&eno=01&mid=s00000000343010178000&mc=1" /></a>   

リピート機能で聞き取りにくい単語を繰り返しチェック可能!

聞き取りにくい箇所はリピート機能を使えば、そのフレーズだけを繰り返しリスニングすることができる。

以前の自分は、聞き取れない文には青ペンで印をつけて、後で聞きなおしていた。
勉強するのはほとんど(満員)電車の中なので、この作業は想像を絶する辛さだった。
また、電車の中でペンを持っている行為はとてもダサかった。
これで、女性との出会いを何度のがしたことやら(えっ?)

最後に

今までめんどくさく感じていた行為を大幅に効率化できそうな気がしてならない。
これで、TOEICの点数もうなぎのぼりになってほしい。

英語学習の技術の進歩は本当にスゴイと思う。
これから15年後の中学生たちは、いったいどんなふうに英語を勉強するのだろうか?

ちなみに自分は、電子辞書を買ってもらうまでは、
英和辞書のジーニアスを毎日カバンに入れて学校に言ってた結果、肩と腰を痛めた。

12 Sep 2012, 22:47

iRemoconとMMDAgentでマクロと音声認識!初音ミクにおはようしてもらう。

iRemoconが音声認識、マクロに対応!スマホで家電を音声制御できる。

iReomconが10月から音声認識と、マクロに対応するみたい。

スマホから音声で家電を制御できるようになる。

プレスリリースの事例でも紹介されていたけど、『いってきます』をトリガに、クーラーやエアコン、テレビや照明、PC、その他電気機器を全て電源OFFにできる。

Androidのみということで、iPhoneユーザのあたしとしては、

iPhoneの対応を待ち望んでいます!!

2012年09月11日 日本初!グラモ、スマホで一般家電を“音声”制御 ~『iRemocon』ユーザー向けに10月上旬リリース、利用料無料。節電にも ブレスリリース

グラモ

 

現実世界をプログラミングできるなんて、魔法みたい(゜ 0 ゜)/

個人的には、マクロを使って現実世界をプログラミングできることに、感動してる。

マクロを組むということは、

パソコン作業で面倒なルーチンワークを自動化するということだ。

それは、パソコンのなかだけに閉じられたものでしたが、

iRemoconの登場によって、誰でもカンタンに現実世界をマクロで自動化できる。

現実世界をプログラミングできるなんて、スゴイことだ。

しかも、音声認識でITを操れるなんて、もはや魔法を身につけたようなもの。

iRemoconとMMDAgentとTeratermを組み合わせて、音声制御を先取り

依然記事にしたけれど、iRemoconとMMDAgent、Teratermマクロを使うことで、

iRemoconに追加予定の機能は実現できる。

iRemoconでミクミクにしてやんよ。

MMDAgentは音声認識、音声合成をするためのソフト。

しかも、モデルに初音ミクを使うことができる。

Teratermマクロは、iRemoconへ通信してコマンドを実行するドライバ。

これを組み合わせて、音声制御を先取りしてみた。

iRemoconとMMDAgentでミクにいってらっしゃいしてもらう

[http://www.youtube.com/embed/lpUV6RUzvFw]

TTLマクロ

[text]

include “C:\Users\Administrator\DROPBOX\SRC\HAL1000\MACRO\COM\INIT.TTL”

mpause 300

;すべての電気をけす

include “C:\Users\Administrator\DROPBOX\SRC\HAL1000\MACRO\COM\ALLLIGHTSOFF.TTL”

mpause 300

; エアコン消す

sendln ‘*is;313’

; パソコン消す

exec ‘C:\Users\Administrator\Dropbox\src\HAL1000\macro\shutdown_now.bat’ ‘HIDE’

include “C:\Users\Administrator\DROPBOX\SRC\HAL1000\MACRO\COM\END.TTL”

[/text]

初音ミクにいってらっしゃいを言われると、よし、今日もがんばろうとおもう。

そんなことでは、いつになっても結婚できない気がする。

おかえりなさい(ここだけ別の声?! GoogleTTS )

TTLマクロ

[text]

include “C:\Users\Administrator\Dropbox\src\HAL1000\macro\com\init.ttl”

;声

exec ‘C:\Program Files (x86)\Windows Media Player\wmplayer.exe C:\Users\Administrator\Dropbox\src\HAL1000\voice\ComeBack.mp3’ ‘hide’

; 時刻を取得

gettime timestr “%H”

; 文字列を数字に変換

str2int timenum timestr

; 時間帯によって直接照明と間接照明を分ける

if timenum < 18 then

; 直接照明

sendln ‘*is;83’

else

; 間接照明

sendln ‘*is;81’

mpause 300

sendln ‘*is;91’

mpause 300

sendln ‘*is;89’

endif

include “C:\Users\Administrator\Dropbox\src\HAL1000\macro\com\end.ttl”

[/text]

ここでは、玄関にWEBカメラを設置してモーションセンサのソフトを利用して、

ドアの開閉を監視している。(動体検知ソフト Msako

モーションを感知したら、マクロを実行するという仕組み。

今は会社の寮に住んでいるのだが、

たまに大家さんが、自分が会社にいる間に部屋に入ってくることがある。

そのうち、防犯カメラでモーションを検出したら、

壁からゴキジェットを噴射できないか計画中・・・(゜△゜)/

iRemoconとMMDAgentでミクにおやすみなさいしてもらう

TTLマクロ

[text]

include “C:\Users\Administrator\Dropbox\src\HAL1000\macro\com\init.ttl”

pause 5

; 電気を消す

sendln ‘*is;82’

mpause 300

sendln ‘*is;84’

mpause 300

sendln ‘*is;97’

; ブルーLEDライトをつける

mpause 300

sendln ‘*is;91’

mpause 300

sendln ‘*is;86’

;安眠用BGMを流す

exec ‘C:\Program Files (x86)\Windows Media Player\wmplayer.exe C:\Users\Administrator\Dropbox\src\HAL1000\sound/SleepModeBGM1.wav’ ‘maximize’

include “C:\Users\Administrator\Dropbox\src\HAL1000\macro\com\end.ttl”

; ShutDown after 30minutes

; 30分経過

pause 1500

include “C:\Users\Administrator\Dropbox\src\HAL1000\macro\com\init.ttl”

; LED消す。

sendln ‘*is;97’

mpause 300

;AirCon Off

sendln ‘*is;313’

include “C:\Users\Administrator\Dropbox\src\HAL1000\macro\com\end.ttl”

[/text]

部屋を青くできるLED間接照明で、海の中にいる気分(/_-)

そのうちリモコン制御のアロマディフューザーでラベンダーの香りを出そうと計画中。

(いい商品がみつからない!今は手動でアロマディフューザーをつかってる)

流れているのは、Youtubeで落としてきた安眠用の音楽。

余談だが一番の愛用曲は、究極の眠れるCD。これは本当にオススメ!ネれる!

iRemoconとMMDAgentでミクにおはようしてもらう

TTLマクロ

[text]

include “C:\Users\Administrator\Dropbox\src\HAL1000\macro\com\init.ttl”

;AirCon On

sendln ‘*is;312’

; ディズニーのエレクトリカルパレード

exec ‘C:\Program Files (x86)\iTunes\iTunes.exe C:\Users\Administrator\Dropbox\src\HAL1000\sound\MorningModeBGM1.wav’

mpause 7000

;電気つける

sendln ‘*is;83’

mpause 300

; ボリュームをどんどん大きくしていく

for i 1 20

sendln ‘*is;56’

sendln ‘*is;56’

pause 1

next

include “C:\Users\Administrator\Dropbox\src\HAL1000\macro\com\end.ttl”

[/text]

電気がパソコンから制御できるので、

初ボーナスで購入した光目覚ましはドブに捨てた。

ミッキーのエレクトリカルパレードの音楽は、

朝から最大音量まで大きくしていくので、隣の住人はさぞ迷惑だろうぞ。

ちなみに、この動画って、

朝じゃなくて夜中じゃね?ってツッコミがあるかもしれない。

MMDAgentの.fstでの定義はこんな感じにしてる。

[text]

1 3 RECOG_EVENT_STOP|ミク SYNTH_START|mei|mei_voice_normal|はい。

3 261 RECOG_EVENT_STOP|ただいま C:\Users\Administrator\Dropbox\src\MMDAgent\Macro\ComeBack.ttl

261 300SYNTH_START|mei|mei_voice_normal|おかえりなさい。

3 262 RECOG_EVENT_STOP|おやすみ EXECUTE|C:\Users\Administrator\Dropbox\src\MMDAgent\Macro\SleepMode.ttl

262 300SYNTH_START|mei|mei_voice_normal|おやすみなさい。

3 263 RECOG_EVENT_STOP|いってきます EXECUTE|C:\Users\Administrator\Dropbox\src\MMDAgent\Macro\itterashai.ttl 263 300SYNTH_START|mei|mei_voice_normal|いってらっしゃい。

300 2 SYNTH_EVENT_STOP|mei

[/text]

 

11 Sep 2012, 22:32

C言語でGoogleMockをLink-Time Substitutionしてみた

前回の続き。

前回までが、関数ポインタを使った置換でGoogleMockを使っていたが、 別の方法で。

Makefileを書き換えて、リンク時に置換してしまう。(リンク時置換 link-time Substitution)

C言語でテストをするときに、関数をダミー関数と置き換えたいことがある。

関数がテストしたいファイルと同じ場所にある場合は、

関数ポインタをつかって置換することができる。

しかし、関数がテストしたいファイルと別の場所にあるときは、

ファイルごと置換してしまうことができる。

ダミー関数はもともと置き換えたい関数と同関数名として、

テストしたいファイルとは別のファイルに定義しておく。

コンパイルをかけるときに、Makefileを置き換えたい関数が定義してあるファイルをコンパイル対象から外してしまい、その代わりに、ダミー関数が定義してあるファイルを追加する。

こうすることによって、プロダクトコードに手を加えずに、

コンパイル時に関数をダミー関数を置き換えることができる。

これを、Link-time-Substitutionという。

というわけで、このテクニックを使って、

ブロダクトコードにモックを強引にねじ込んでテストした。

sample.c(プロダクトコード)

[c]

#include “sample.h”

int get_ret(void)

{

int num = 0;

int ret;

NUM dummy;

RET dummy2;

dummy.num = 2;

dummy.count = 3;

/**N 数をライブラリより取得 */

num = get_num(&dummy, &dummy2);

/**N 結果によって分岐 */

if( num == 1 ) {

ret = 10;

}

else if( num == 2 ){

ret = 20;

}

else {

ret = 30;

}

return ret;

}

[/c]

sample.h

[c]

#ifndef SAMPLE_H_

#define SAMPLE_H_

#include “numlib.h”

int get_ret(void);

#endif /* SAMPLE_H_ */

[/c]

numlib.c(置き換えたい関数)

[c]

int get_num()

{

return rand();

}

[/c]

numlib.h(置き換えたい関数のヘッダファイル)

[c]

typedef struct NUM

{

int num;

int count;

}NUM;

typedef struct RET

{

int ret;

int count;

}RET;

int get_num(NUM *num, RET *ret);

[/c]

gmock_test.cpp(テストコード)

[c]

extern “C”

{

#include “sample.h”

int get_num(NUM *num, RET *ret);

}

#include “gtest/gtest.h” /**N GoogleTest インクルード */

#include “gmock/gmock.h” /**N GoogleMock インクルード */

using ::testing::Return;

using ::testing::_;

using ::testing::Eq;

/**N モッククラス */

class MockNum

{

public:

MOCK_METHOD2(get_num2, int(int num, int count) );

} mock;

/**N テスト */

class MockNumTest : public ::testing::Test

{

public:

virtual void SetUp()

{

}

virtual void TearDown()

{

}

};

int get_num(NUM *num, RET *ret)

{

return mock.get_num2(num->num, num->count);

}

TEST_F(MockNumTest, return1)

{

EXPECT_CALL(mock, get_num2(_,_) ).WillOnce(Return(1));

EXPECT_EQ(10, get_ret() );

}

TEST_F(MockNumTest, return2)

{

EXPECT_CALL(mock, get_num2(2,3) ).WillOnce(Return(2));

EXPECT_EQ(20, get_ret() );

}

TEST_F(MockNumTest, return3)

{

EXPECT_CALL(mock, get_num2(Eq(2),Eq(3)) ).WillOnce(Return(3));

EXPECT_EQ(30, get_ret() );

}

[/c]

 

C言語からC++での関数が使えるように、C++のコードではextern “C”をつかう。

extern “C”

{

#include “sample.h”

int get_num(NUM *num, RET *ret);

}

たいていの場合、Mockで置き換えたい関数は、他人のコードなので、

ファイルが独立していることが多い。

関数ポインタを使う方法よりも、こっちのほうがよくつかったりする。

10 Sep 2012, 11:53

GoogleMockのモックメゾッドにC言語の構造体ポインタを渡してみた

今日は体調不良のため、定時退社というなの早退をして、

家に帰ってきた瞬間に治ったので、ブログを更新してみる。

今の開発だと、制御用のメモリを構造体ポインタの形でやり取りすることが多い。

構造体ポインタをGoogleMockの モックメゾッド(MOCK_METHODx)にわたすと、

コンパイルが通らない。悩んだ上げく、以下の方法でできた。

Mockオブジェクトの中で、構造体をメンバごとに分解して、渡してやる

MOCK_METHODに渡すときには、構造体のメンバごとに引数に渡してやればいいだけ。

[C]

typedef struct hogehoge {

int x;

int y;

}HOGE;

[/C]

なので、構造体の場合は、

MOCK_METHOD0(hoge);

だとエラーするので、

MOCK_METHOD2(hoge->x, hoge->y);

と分解すればよい。

前回エントリのサンブルソースを少し改造

sample.c

[C]

#include “sample.h”

int get_ret(void)

{

int num = 0;

int ret;

NUM dummy;

dummy.num = 2;

dummy.count = 3;

/**N 数をライブラリより取得 */

num = get_num(&dummy);

/**N 結果によって分岐 */

if( num == 1 ) {

ret = 10;

}

else if( num == 2 ){

ret = 20;

}

else {

ret = 30;

}

return ret;

}

[/C]

numlib.h

[C]

typedef struct NUM

{

int num;

int count;

}NUM;

#ifdef __cplusplus

extern “C” {

#endif

extern int(*get_num)(NUM *num);

[/C]

gmock_test.cpp

[C]

extern “C”

{

#include “sample.h”

}

#include “gtest/gtest.h” /**N GoogleTest インクルード */

#include “gmock/gmock.h” /**N GoogleMock インクルード */

using ::testing::Return;

using ::testing::_;

using ::testing::Eq;

/**N モッククラス */

class MockNum

{

public:

MOCK_METHOD2(get_num2, int(int num, int count) );

} mock;

int Mockget_num(NUM *num)

{

return mock.get_num2(num->num, num->count);

}

/**N get_num 実体 */

int (*get_num)(NUM *num);

/**N テスト */

class MockNumTest : public ::testing::Test

{

int (*savedget_num)(NUM *num);

virtual void SetUp()

{

savedget_num = get_num;

get_num = Mockget_num;

}

virtual void TearDown()

{

get_num = savedget_num;

}

};

TEST_F(MockNumTest, return1)

{

EXPECT_CALL(mock, get_num2(_,_) )

.WillOnce(Return(1));

EXPECT_EQ(10, get_ret() );

}

TEST_F(MockNumTest, return2)

{

EXPECT_CALL(mock, get_num2(2,3) ).WillOnce(Return(2));

EXPECT_EQ(20, get_ret() );

}

TEST_F(MockNumTest, return3)

{

EXPECT_CALL(mock, get_num2(Eq(2),Eq(3)) ).WillOnce(Return(3));

EXPECT_EQ(30, get_ret() );

}

[/C]

09 Sep 2012, 07:42

WindowsバッチファイルをJenkinsで起動したらネットにアクセスできない

Selenium RCの起動をWindowsのバッチファイルにして、Jenkinsから起動したら、

Firefoxを立ち上げたところで処理が止まってしまう。

05:55:02.690 INFO – Preparing Firefox profile…

05:55:04.964 INFO – Launching Firefox…

05:55:06.985 INFO – Checking Resource aliases

Jenkinsを介さずに、Windowsのコマンドプロンプトからならば、

処理が停滞しないので、さらにわけが分からない。

どうやら、Jenkinsからではインターネットにアクセスできないようだ。

処理が停滞するのは、URLのopenがタイムアイトしているから。

JenkinsはWindowsのサービスとして起動している。

そして、Windowsのサービスからインターネットにアクセスしようとして、

ファイアウォールに引っかかっているようだ(という推測)。

[コントロールパネル]>[管理ツール]>[サービス]

からJenkinsのプロパティを開いて、

[ログオン]タブの『デスクトップとの対話をサービスに許可』

を選択すると、サービスが起動している画面に移動でき、

停滞している画面を見ることができる。

image

image

メッセージの表示を選択すれば、Firefoxが停滞している様子が見える。

この課題を解決するには、ネットワーク設定をいじる必要がありそうだけれど、

よくわからなかった。

Slaveノードを作成して、Windowsサービスとして登録せずに起動する

自分がたどりついた方法は、Slaveノードを作成して、

そいつはWindowsサービスとしては登録しないまま、ネットにアクセスさせる方法。

まずは、

[Jenkinsの管理] > [ノードの管理]> [新規ノードの作成]からノード作成。

このとき、

詳しくは参考ページを参照。

Jenkinsスレーブの作成と設定 -ムーチョのメモ帳
https://wiki.jenkins-ci.org/display/JA/Step+by+step+guide+to+set+up+master+and+slave+machines

作成したノードをブラウザ上から立ちあげると、こんな窓が出てくる。

image

この状態で、Seleniumパッチを実行すると、問題なくネットへアクセスできた。

 

JenkinsをWindowsサービスとして立ちあげない

昨日のエントリの続き。

寝て起きたら、もっとカンタンな(当たり前な?)方法を思いついた。

JenkinsがWindowsのスタートアップでサービスとして起動することが問題なので、

サービスを無効にしてしまえばよい。

[コントロールパネル]>[管理ツール]>[サービス]

からJenkinsのプロパティを開いて、サービスを停止する。

停止したら、コマンドラインから、Jenkinsを手動で立ち上げなおす。

cd ”C:\xxxxxx\Jenkins”

java -jar jankins.war

すると、しばらくしてJenkinsがWindowsのサービスとしてではなく

立ちあがるので、この状態ならばネットにつなげた。

08 Sep 2012, 10:10

GoogleMockをC言語で使う方法をハックしてみた

今、仕事ではテスト工程なので、

C言語で書いたソースにたいしてGoogleTestを使ってウラウラとテストを書きまくっている。

このロジックに対してはどうやってテストを書けばいいかを考えるのが楽しい。

モック関数を書きまくっている結果微妙な工程遅延を起こし、

マニュアルテスト組から、したり顔をされていたりする。;(´o`

GoogleTestには兄貴分のGoogleMockがいるのだが、

こいつがC言語で使えないかどうか、調べてみた。

GoogleMockとは

GoogleMockとは、C++用のモックオブジェクト作成ツール。

モックオブジェクトを使うことによって、

関数からの戻り値を自分でかってに書き換えたり,

テストしたい関数に渡された引数の値をしらべることができる。

普通ならば、テスト用の関数を自作して、調べなければいけないが、

これをGoogleMockを使うことによって、自作する関数を少なくできる。

ダウンロードはココから:GoogleMock

C++でのつかいかたはここから:Google Mock ドキュメント日本語訳

テスト対象コード

数を取得するライブラリを呼び出して、その結果から分岐するコードをテストする。

sample.c

[c]

#include “sample.h”

int get_ret(void)

{

int num = 0;

int ret;

/**N 数をライブラリより取得 */

num = get_num();

/**N 結果によって分岐 */

if( num == 1 ) {

ret = 10;

}

else if( num == 2 ){

ret = 20;

}

else {

ret = 30;

}

return ret;

}

[/c]

numlib.c

[c]

#include “numlib.h”

#include

int get_num()

{

return rand();

}

[/c]

get_num()の戻り値をテストを実行するたびに変更できれ便利だなー。

そんなことが、GoogleMockを使えばできてしまう。

GoogleMock導入結果

まずは、導入結果から。sample.cには手を入れない。

numlib.c

[c]

#include “numlib.h”

#include

int get_numImpl()

{

return rand();

}

int (*get_num)(void) = get_numImpl;

[/c]

numlib.h

[c]

#ifndef NUMLIB_H_

#define NUMLIB_H_

#ifdef __cplusplus

extern “C” {

#endif

extern int (*get_num)(void);

#ifdef __cplusplus

}

#endif

#endif /* NUMLIB_H_ */

[/c]

gmock_test.cpp

[cpp]

extern “C”

{

#include “sample.h”

}

#include “gtest/gtest.h” /**N GoogleTest インクルード */

#include “gmock/gmock.h” /**N GoogleMock インクルード */

using ::testing::Return;

/**N モッククラス */

class MockNum

{

public:

MOCK_METHOD0(get_num, int() );

} mock;

int Mockget_num(void)

{

return mock.get_num();

}

/**N get_num 実体 */

int (*get_num)(void);

/**N テスト */

class MockNumTest : public ::testing::Test

{

int (*savedget_num)();

virtual void SetUp()

{

savedget_num = get_num;

get_num = Mockget_num;

}

virtual void TearDown()

{

get_num = savedget_num;

}

};

TEST_F(MockNumTest, return1)

{

EXPECT_CALL(mock, get_num() ).WillOnce(Return(1));

EXPECT_EQ(10, get_ret() );

}

TEST_F(MockNumTest, return2)

{

EXPECT_CALL(mock, get_num() ).WillOnce(Return(2));

EXPECT_EQ(20, get_ret() );

}

TEST_F(MockNumTest, return3)

{

EXPECT_CALL(mock, get_num() ).WillOnce(Return(3));

EXPECT_EQ(30, get_ret() );

}

[/cpp]

テストコードではget_numからの戻り値がそれぞれ1,2,3が帰ってきた場合の、

処理分岐をテストしている。

GoogleMock導入のポイント

GoogleMcokをC言語で導入するためのポイントは2つ。

extern “C” で CとC++のソースをつなぐ

numlib.hは、C言語(sample.c)とC++(gmock_test.cpp)の

異なる言語のファイルからインクルードされるため、

インクルードのためのおまじないをかく。

[c]

#ifdef __cplusplus

extern “C” {

#endif

extern int (*get_num)(void);

#ifdef __cplusplus

}

#endif

[/c]

__cplusplusマクロは、C++で開発しているときにだけ定義される。

C++でコンパイルをかけるときだけ、C++で定義されたget_numをC言語でも

コンパイルできる extern “C” が適応される。

関数ポインタでget_numをモック関数に置き換える

関数ポインタをつかうことで、プロダクトコードには手を加えなくても、

実際のインタフェースをモックオブジェクトのインタフェースを置換することができる。

テストを実行する際に、一時的に関数ポインタをテスト用の関数で上書きする。

[cpp]

class MockNumTest : public ::testing::Test

{

int (*savedget_num)();

virtual void SetUp()

{

savedget_num = get_num;

get_num = Mockget_num;

}

virtual void TearDown()

{

get_num = savedget_num;

}

};

[/cpp]

また、プロダクトコード、テストコードの両方でget_numをインクルードしたいため、

ヘッダファイルでextern宣言している。

最後に

実は、GoogleMockをGoogleTestで使う方法は1年以上前から調べていたのだが、

ようやくわかったので、記事にしてみた。参考にしたのは以下のQ&A。

https://groups.google.com/forum/?fromgroups=#!searchin/googlemock/C$20language/googlemock/CVdeuQ0e6OI/HOYyoNA7uIAJ

これで毎日が定時退社だ!!(^ ○ ^)!/

追記

Cygwin環境で、g++-4.exeを使ってコンパイルすると、コンパイルは通るが、

g++-3.exeだと、コンパイルエラーする。

3.xと4.xでなにが異なるのかわからないけれど、

とりあえずコンパイル通らなかったら、g++-3.exeをg++.exeに置換する必要あり。