compilationTimeoutがデフォルト値として、5分になっているからでした。
公開されているWebのドキュメントは古いので、設定できる内容はソースを確認した方がよいです。
余談ですが、compileThreadsというJSPをコンパイルする時のスレッド数を設定するものもありました。
とりあえず2にしてみたところ、時間が半分程度になりました。
ビルドするマシンパワーに余裕があるのであれば、うまく調整するとよいと思います。
Maven plugin to do JSP Compliation
2017年7月29日土曜日
2015年4月26日日曜日
fluent-logger-javaについていくつかのこと。
GitHub fluent/fluent-logger-java
バージョンは、0.3.1です。
org.fluentd.logger.FluentLoggerFactory#getLogger(String, String, int, int, int, Reconnector)
そこで、org.fluentd.logger.sender.Senderインターフェースを実装したクラスを以下のように設定することで、
デフォルトのorg.fluentd.logger.sender.RawSocketSenderから変更できます。
諸事情でFluentdにログを送信できない場合、このクラスに切り替えるようなロジックを実装するといった利用が考えられます。
org.fluentd.logger.sender.ExponentialDelayReconnector
指数関数的に遅延しながら再接続を試みる物のようです。
これとは別に、org.fluentd.logger.sender.Reconnectorインターフェースを実装することで、
独自の動作を実装できます。
以下のメソッドを利用することで、独自の動作をさせることができます。
org.fluentd.loggerFluentLogger#getLogger(String, String, int, int, int, Reconnector)
バージョンは、0.3.1です。
Fluentdに送信する実装を変更できる。
ファクトリークラス内が下記のようになっています。org.fluentd.logger.FluentLoggerFactory#getLogger(String, String, int, int, int, Reconnector)
Properties props = System.getProperties();
if (!props.containsKey(Config.FLUENT_SENDER_CLASS)) {
// create default sender object
sender = new RawSocketSender(host, port, timeout, bufferCapacity, reconnector);
} else {
String senderClassName = props.getProperty(Config.FLUENT_SENDER_CLASS);
try {
sender = createSenderInstance(senderClassName, new Object[] { host, port, timeout, bufferCapacity });
} catch (Exception e) {
throw new RuntimeException(e);
}
}
そこで、org.fluentd.logger.sender.Senderインターフェースを実装したクラスを以下のように設定することで、
デフォルトのorg.fluentd.logger.sender.RawSocketSenderから変更できます。
System.setProperty(Config.FLUENT_SENDER_CLASS, "com.example.HogeSender")
他にも、org.fluentd.logger.sender.NullSenderというクラスは、空振りする動作をします。諸事情でFluentdにログを送信できない場合、このクラスに切り替えるようなロジックを実装するといった利用が考えられます。
再接続方法を変更できる。
デフォルトの実装は、org.fluentd.logger.sender.ExponentialDelayReconnector
指数関数的に遅延しながら再接続を試みる物のようです。
これとは別に、org.fluentd.logger.sender.Reconnectorインターフェースを実装することで、
独自の動作を実装できます。
以下のメソッドを利用することで、独自の動作をさせることができます。
org.fluentd.loggerFluentLogger#getLogger(String, String, int, int, int, Reconnector)
2015年4月25日土曜日
JUnit3を利用するDBUnitで、ExcelのXLSX形式に対応する。
諸般の事情で、JUnit4系にできないので、
主なライブラリ構成は以下の通りになりました。
下記に記載がある通り、対応します。
JUnit - ふなWiki - xlsx をデータとして利用する
DBUnitでXLSXを扱うように変更する場合、POIの公式に記載してある通りに対応すればOKです。
Apache POI - Upgrading to POI 3.5, including converting existing HSSF Usermodel code to SS Usermodel (for XSSF and HSSF)
自前で対応した後、DBUnitが正式に対応したので、以下をパッチすれば良いと思います。
試してはいないですが、パッと見た感じだと私が対応した内容と同じ感じでした。
dbUnit / Git / Commit [c6a6ba] Apache POI liblary version up from "3.2-FINAL" to "3.11".
ついでに、読み込んだExcelの日時がズレてしまう問題に対応します。
以下のブログに言及がありますが、独自でXLSX対応しちゃうついでに、こちらもコードを直しちゃいます。
山下寛人オフィシャルブログ - DBUnit Excelロード時の時刻データ
対応する箇所は、以下の通りです。
org.dbunit.dataset.excel.XlsTable
とりあえず、これで問題なくテストできています。
主なライブラリ構成は以下の通りになりました。
- JUnit3.8.2
- DBUnit2.4.9
- POI3.7
下記に記載がある通り、対応します。
JUnit - ふなWiki - xlsx をデータとして利用する
DBUnitでXLSXを扱うように変更する場合、POIの公式に記載してある通りに対応すればOKです。
Apache POI - Upgrading to POI 3.5, including converting existing HSSF Usermodel code to SS Usermodel (for XSSF and HSSF)
自前で対応した後、DBUnitが正式に対応したので、以下をパッチすれば良いと思います。
試してはいないですが、パッと見た感じだと私が対応した内容と同じ感じでした。
dbUnit / Git / Commit [c6a6ba] Apache POI liblary version up from "3.2-FINAL" to "3.11".
ついでに、読み込んだExcelの日時がズレてしまう問題に対応します。
以下のブログに言及がありますが、独自でXLSX対応しちゃうついでに、こちらもコードを直しちゃいます。
山下寛人オフィシャルブログ - DBUnit Excelロード時の時刻データ
対応する箇所は、以下の通りです。
org.dbunit.dataset.excel.XlsTable
protected Object getDateValue(Cell cell)
{
logger.debug("getDateValue(cell={}) - start", cell);
double numericValue = cell.getNumericCellValue();
Date date = DateUtil.getJavaDate(numericValue);
// Add the timezone offset again because it was subtracted automatically by Apache-POI (we need UTC)
long tzOffset = TimeZone.getDefault().getOffset(date.getTime());// この行をコメントアウトする。
date = new Date(date.getTime() + tzOffset); // この行をコメントアウトする。
return new Long(date.getTime());
//TODO use a calendar for XLS Date objects when it is supported better by POI
// HSSFCellStyle style = cell.getCellStyle();
// HSSFDataFormatter formatter = new HSSFDataFormatter();
// Format f = formatter.createFormat(cell);
// String formatted = fomatter.formatCellValue(cell);
//System.out.println("###"+formatted);
// Date dateValue = cell.getDateCellValue();
}とりあえず、これで問題なくテストできています。
2014年6月21日土曜日
JavaでjQueryで扱うIDをエスケープする
Webアプリケーションフレームワークの都合上、動的に生成されるIDをjQueryで処理する必要があり、
そのIDを予めjQueryでも扱えるようエスケープした状態のIDを作成する必要がありました。
そこで、以下のようなユーティリティークラスを作成しました。
jQueryのエスケープに関しては、下記にあります。
jQuery API Documentation Category: Selectors
テストコード
そのIDを予めjQueryでも扱えるようエスケープした状態のIDを作成する必要がありました。
そこで、以下のようなユーティリティークラスを作成しました。
jQueryのエスケープに関しては、下記にあります。
jQuery API Documentation Category: Selectors
package util;
/**
* jQueryユーティリティー
* @author @michigawi
*/
public final class JQueryUtil {
/** エスケープ対象文字 */
private static final char[] META_CHARACTERS = new char[]{' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '.', '/', ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '^', '`', '{', '|', '}', '~'};
/** jQueryのエスケープ文字 */
private static final String ESCAPE_META = "\\\\";
/**
* エスケープします。
* http://api.jquery.com/category/selectors/
* @param target ターゲットの文字
* @return エスケープ後の文字列
*/
public static final String escape(String target) {
if (target == null) {
return null;
}
StringBuilder escaped = new StringBuilder(target.length() * 2);
for (char character : target.toCharArray()) {
if (findEscapeTarget(character)) {
escaped.append(ESCAPE_META);
}
escaped.append(character);
}
return escaped.toString();
}
/**
* 文字列がエスケープ対象か判別します。
* @param target ターゲットの文字
* @return エスケープ対象の場合、true
*/
private static boolean findEscapeTarget(char target) {
for (char meta : META_CHARACTERS) {
if (target == meta) {
return true;
}
}
return false;
}
}
テストコード
package util;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import org.junit.Test;
/**
* {@link util.JQueryUtilTest}のテスト
* @author @michigawi
*/
public class JQueryUtilTest {
@Test
public void 半角スペースをエスケープする() {
assertThat(JQueryUtil.escape("jQuery selector"), is("jQuery\\\\ selector"));
}
@Test
public void 半角エクスクラメーションマークをエスケープする() {
assertThat(JQueryUtil.escape("jQuery!selector"), is("jQuery\\\\!selector"));
}
@Test
public void ダブルクウォートをエスケープする() {
assertThat(JQueryUtil.escape("jQuery\"selector"), is("jQuery\\\\\"selector"));
}
@Test
public void シャープをエスケープする() {
assertThat(JQueryUtil.escape("jQuery#selector"), is("jQuery\\\\#selector"));
}
@Test
public void ダラーをエスケープする() {
assertThat(JQueryUtil.escape("jQuery$selector"), is("jQuery\\\\$selector"));
}
@Test
public void パーセントをエスケープする() {
assertThat(JQueryUtil.escape("jQuery%selector"), is("jQuery\\\\%selector"));
}
@Test
public void アンドをエスケープする() {
assertThat(JQueryUtil.escape("jQuery&selector"), is("jQuery\\\\&selector"));
}
@Test
public void シングルクォートをエスケープする() {
assertThat(JQueryUtil.escape("jQuery'selector"), is("jQuery\\\\'selector"));
}
@Test
public void 左丸カッコをエスケープする() {
assertThat(JQueryUtil.escape("jQuery(selector"), is("jQuery\\\\(selector"));
}
@Test
public void 右丸カッコをエスケープする() {
assertThat(JQueryUtil.escape("jQuery)selector"), is("jQuery\\\\)selector"));
}
@Test
public void アスタリスクをエスケープする() {
assertThat(JQueryUtil.escape("jQuery*selector"), is("jQuery\\\\*selector"));
}
@Test
public void プラスをエスケープする() {
assertThat(JQueryUtil.escape("jQuery+selector"), is("jQuery\\\\+selector"));
}
@Test
public void カンマをエスケープする() {
assertThat(JQueryUtil.escape("jQuery,selector"), is("jQuery\\\\,selector"));
}
@Test
public void ピリオドをエスケープする() {
assertThat(JQueryUtil.escape("jQuery.selector"), is("jQuery\\\\.selector"));
}
@Test
public void スラッシュをエスケープする() {
assertThat(JQueryUtil.escape("jQuery/selector"), is("jQuery\\\\/selector"));
}
@Test
public void コロンをエスケープする() {
assertThat(JQueryUtil.escape("jQuery:selector"), is("jQuery\\\\:selector"));
}
@Test
public void セミコロンをエスケープする() {
assertThat(JQueryUtil.escape("jQuery;selector"), is("jQuery\\\\;selector"));
}
@Test
public void 小なり記号をエスケープする() {
assertThat(JQueryUtil.escape("jQueryselector"), is("jQuery\\\\>;selector"));
}
@Test
public void クエッションをエスケープする() {
assertThat(JQueryUtil.escape("jQuery?selector"), is("jQuery\\\\?selector"));
}
@Test
public void アットマークをエスケープする() {
assertThat(JQueryUtil.escape("jQuery@selector"), is("jQuery\\\\@selector"));
}
@Test
public void 左大カッコをエスケープする() {
assertThat(JQueryUtil.escape("jQuery[selector"), is("jQuery\\\\[selector"));
}
@Test
public void バックスラッシュをエスケープする() {
assertThat(JQueryUtil.escape("jQuery\\selector"), is("jQuery\\\\\\selector"));
}
@Test
public void 右大カッコをエスケープする() {
assertThat(JQueryUtil.escape("jQuery]selector"), is("jQuery\\\\]selector"));
}
@Test
public void キャレットをエスケープする() {
assertThat(JQueryUtil.escape("jQuery^selector"), is("jQuery\\\\^selector"));
}
@Test
public void グレイヴアクセントをエスケープする() {
assertThat(JQueryUtil.escape("jQuery`selector"), is("jQuery\\\\`selector"));
}
@Test
public void 左中カッコをエスケープする() {
assertThat(JQueryUtil.escape("jQuery{selector"), is("jQuery\\\\{selector"));
}
@Test
public void 縦線をエスケープする() {
assertThat(JQueryUtil.escape("jQuery|selector"), is("jQuery\\\\|selector"));
}
@Test
public void 右中カッコをエスケープする() {
assertThat(JQueryUtil.escape("jQuery}selector"), is("jQuery\\\\}selector"));
}
@Test
public void チルダをエスケープする() {
assertThat(JQueryUtil.escape("jQuery~selector"), is("jQuery\\\\~selector"));
}
}
2014年3月15日土曜日
Copy Paste Detector(CPD)の解析結果をHTMLにする。
CPDで解析した結果はそのままでは見難いので、
antのタスクで解析からHTML出力まで行います。
HTMLにする際、XSLTテンプレートがPMDに含まれているので、
それを利用します。
ディレクトリ構成は以下の通りです。
以下は、antのbuild.xmlファイルです。
batファイルは、以下のように記述します。
HTMLは以下のような感じになります。

antのタスクで解析からHTML出力まで行います。
HTMLにする際、XSLTテンプレートがPMDに含まれているので、
それを利用します。
ディレクトリ構成は以下の通りです。
/
/pmd-bin-5.1.0/
/commons-net-3.3-src/
/apache-ant-1.8.4/
build.xml
cpdExec.bat
以下は、antのbuild.xmlファイルです。
<?xml version="1.0" encoding="UTF-8"?>
<project name="CPD" default="analysis" basedir=".">
<path id="cpd.lib">
<fileset dir="./pmd-bin-5.1.0/lib">
<include name="*.jar"/>
</fileset>
</path>
<taskdef name="cpd" classpathref="cpd.lib" classname="net.sourceforge.pmd.cpd.CPDTask"/>
<target name="analysis">
<antcall target="cpd" />
<antcall target="xslt" />
</target>
<target name="cpd">
<cpd encoding="UTF-8" minimumTokenCount="100" format="xml" language="java" outputFile="cpd.xml">
<fileset dir="./commons-net-3.3-src/src/main/java">
<include name="**/*.java"/>
</fileset>
</cpd>
</target>
<target name="xslt">
<xslt in="cpd.xml" style="./pmd-bin-5.1.0/etc/xslt/cpdhtml.xslt" out="cpd.html" />
</target>
</project>
batファイルは、以下のように記述します。
setlocal
set JAVA_HOME=%ProgramFiles%\Java\jdk1.7.0_51
set ANT_HOME=./apache-ant-1.8.4
"%ANT_HOME%\bin\ant.bat"
pause
HTMLは以下のような感じになります。

Copy Paste Detector(CPD)でソースコードの重複(コピペ)を発見する。
様々なプログラミング言語を解析するPMDにあるCPDを利用します。
以下は、ディレクトリ構成です。
今回は、Apache CommonsのNetコンポーネントを解析に利用しました。
以下のようにbatファイルを記述します。
実行する際、解析結果をファイルに保存する為、標準出力をリダイレクトします。
以下は、ディレクトリ構成です。
/
/pmd-bin-5.1.0/
/commons-net-3.3-src/
cpdExec.bat
今回は、Apache CommonsのNetコンポーネントを解析に利用しました。
以下のようにbatファイルを記述します。
setlocal
set JAVA_HOME=%ProgramFiles%\Java\jdk1.7.0_51
set CLASSPATH=./pmd-bin-5.1.0/lib/ant-1.8.1.jar;./pmd-bin-5.1.0/lib/ant-launcher-1.8.1.jar;./pmd-bin-5.1.0/lib/ant-testutil-1.7.1.jar;./pmd-bin-5.1.0/lib/asm-5.0_BETA.jar;./pmd-bin-5.1.0/lib/commons-io-2.2.jar;./pmd-bin-5.1.0/lib/commons-lang3-3.1.jar;./pmd-bin-5.1.0/lib/dom4j-1.6.1.jar;./pmd-bin-5.1.0/lib/javacc-5.0.jar;./pmd-bin-5.1.0/lib/jaxen-1.1.1.jar;./pmd-bin-5.1.0/lib/jcommander-1.27.jar;./pmd-bin-5.1.0/lib/jdom-1.0.jar;./pmd-bin-5.1.0/lib/junit-4.4.jar;./pmd-bin-5.1.0/lib/pmd-5.1.0.jar;./pmd-bin-5.1.0/lib/rhino-1.7R3.jar;./pmd-bin-5.1.0/lib/saxon-9.1.0.8-dom.jar;./pmd-bin-5.1.0/lib/saxon-9.1.0.8.jar;./pmd-bin-5.1.0/lib/xercesImpl-2.9.1.jar;./pmd-bin-5.1.0/lib/xml-apis-1.3.02.jar;./pmd-bin-5.1.0/lib/xmlParserAPIs-2.6.2.jar;./pmd-bin-5.1.0/lib/xom-1.0.jar
"%JAVA_HOME%\bin\java.exe" -Xmx512m net.sourceforge.pmd.cpd.CPD --minimum-tokens 100 --files ./commons-net-3.3-src/src/main/java --encoding utf-8 --format xml
pause
実行する際、解析結果をファイルに保存する為、標準出力をリダイレクトします。
cpdExec.bat > cpd.xml
2014年1月3日金曜日
CodeIQ MAGAZINE「現在時刻が関わるテストから、テスト容易性設計を学ぶ」を解いてみた
CodeIQ MAGAZINE これであなたもテスト駆動開発マスター!?和田卓人さんがテスト駆動開発問題を解答コード使いながら解説します~現在時刻が関わるテストから、テスト容易性設計を学ぶ #tdd
読んでみたら、参加言語とアプローチの内訳に、Javaで「現在時刻を引数で渡す」アプローチがなかったので、書いてみました。
以下は実装です。
様々なアプローチがあるんだなぁと思いました。
読んでみたら、参加言語とアプローチの内訳に、Javaで「現在時刻を引数で渡す」アプローチがなかったので、書いてみました。
以下は実装です。
package tdd;
import java.util.Calendar;
import java.util.Date;
/**
* 挨拶をするクラスです。
* @author michigawi
*/
public class Greeter {
/**
* 挨拶します。
* @param date 日時
* @return 挨拶
*/
public String greet(Date date) {
Calendar cal = Calendar.getInstance();
cal.setTime(date);
int hour = cal.get(Calendar.HOUR_OF_DAY);
int minute = cal.get(Calendar.MINUTE);
int second = cal.get(Calendar.SECOND);
for (Greeting greeting : Greeting.values()) {
if (greeting.valid(hour, minute, second)) {
return greeting.getGreeting();
}
}
return null;
}
/**
* 挨拶です。
* @author michigawi
*/
private enum Greeting {
/** 朝 */
MORNING("おはようございます") {
@Override
public boolean valid(int hour, int minute, int second) {
if (hour >= 5 && (hour <= 11 && minute <= 59 && second <= 59)) {
return true;
}
return false;
}
}
/** 日中 */
, AFTERNOON("こんにちは") {
@Override
public boolean valid(int hour, int minute, int second) {
if (hour >= 12 && (hour <= 17 && minute <= 59 && second <= 59)) {
return true;
}
return false;
}
}
/** 夜 */
, NIGHT("こんばんは") {
@Override
public boolean valid(int hour, int minute, int second) {
if (hour >= 18 && (hour <= 23 && minute <= 59 && second <= 59)) {
return true;
}
if (hour >= 0 && (hour <= 4 && minute <= 59 && second <= 59)) {
return true;
}
return false;
}
};
/** 挨拶するか */
public abstract boolean valid(int hour, int minute, int second);
/** 挨拶 */
private String greeting;
/**
* コンストラクタです。
* @param greeting
*/
Greeting(String greeting) {
this.greeting = greeting;
}
/**
* 挨拶を返します。
* @return 挨拶
*/
public String getGreeting() {
return greeting;
}
}
}
最後にテストです。
package tdd;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import java.util.Calendar;
import org.junit.Before;
import org.junit.Test;
/**
* {@link tdd.Greeter}のテストです。
* @author michigawi
*/
public class GreeterTest {
/** テスト対象のクラス */
private Greeter greeter;
/** カレンダー */
private Calendar calendar;
/**
* setup.
*/
@Before
public void setUp() {
greeter = new Greeter();
calendar = Calendar.getInstance();
calendar.clear();
calendar.set(2014, Calendar.JANUARY, 3);
}
/**
* Test method for {@link tdd.Greeter#greet(java.util.Date)}.
*/
@Test
public void 午前0時ジャストはこんばんは() {
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
assertThat("", greeter.greet(calendar.getTime()), is("こんばんは"));
}
/**
* Test method for {@link tdd.Greeter#greet(java.util.Date)}.
*/
@Test
public void 午前5時より前はこんばんは() {
calendar.set(Calendar.HOUR_OF_DAY, 4);
calendar.set(Calendar.MINUTE, 59);
calendar.set(Calendar.SECOND, 59);
assertThat("", greeter.greet(calendar.getTime()), is("こんばんは"));
}
/**
* Test method for {@link tdd.Greeter#greet(java.util.Date)}.
*/
@Test
public void 午前5時ジャストはおはようございます() {
calendar.set(Calendar.HOUR_OF_DAY, 5);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
assertThat("", greeter.greet(calendar.getTime()), is("おはようございます"));
}
/**
* Test method for {@link tdd.Greeter#greet(java.util.Date)}.
*/
@Test
public void 正午の前はおはようございます() {
calendar.set(Calendar.HOUR_OF_DAY, 11);
calendar.set(Calendar.MINUTE, 59);
calendar.set(Calendar.SECOND, 59);
assertThat("", greeter.greet(calendar.getTime()), is("おはようございます"));
}
/**
* Test method for {@link tdd.Greeter#greet(java.util.Date)}.
*/
@Test
public void 正午はこんにちは() {
calendar.set(Calendar.HOUR_OF_DAY, 12);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
assertThat("", greeter.greet(calendar.getTime()), is("こんにちは"));
}
/**
* Test method for {@link tdd.Greeter#greet(java.util.Date)}.
*/
@Test
public void 午後6時より前はこんにちは() {
calendar.set(Calendar.HOUR_OF_DAY, 17);
calendar.set(Calendar.MINUTE, 59);
calendar.set(Calendar.SECOND, 59);
assertThat("", greeter.greet(calendar.getTime()), is("こんにちは"));
}
/**
* Test method for {@link tdd.Greeter#greet(java.util.Date)}.
*/
@Test
public void 午後6時ジャストはこんばんは() {
calendar.set(Calendar.HOUR_OF_DAY, 18);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
assertThat("", greeter.greet(calendar.getTime()), is("こんばんは"));
}
/**
* Test method for {@link tdd.Greeter#greet(java.util.Date)}.
*/
@Test
public void _24時はこんばんは() {
calendar.set(Calendar.HOUR_OF_DAY, 24);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
assertThat("", greeter.greet(calendar.getTime()), is("こんばんは"));
}
}
様々なアプローチがあるんだなぁと思いました。
2012年7月2日月曜日
2012年3月29日木曜日
64bit版Windows7でSeleniumを使ったInternet Explorerのスクリーンショットを撮る
Seleniumでは実行したテストのスクリーンショットを撮ることができます。
IEのスクリーンショットを撮る場合は、下記のDLLを手順に従いインストールします。
snapsIE - Free, Open-Source, Scriptable Screen Capture Utility for IE
ここでレジストリに登録する際、regsvr32.exe を実行するのですが、記載されてある通りに実行するとエラーになります。
そこで、下記のサイトを確認すると、64bit版Windowsには2つのバージョンが存在しているとのことです。
Microsoftサポート Regsvr32 の使用法とエラー メッセージについて
DLLは32bit環境を想定しているので、32bit版の regsvr32.exe を使って実行します。
これで登録できると思います。
テストケースには下記のような感じで実装します。
作成される画像の形式は、PNGです。
Temporaryディレクトリ内にPNGファイルが作成されるので、リネームする形で任意の場所に移動させます。
自動化された単体テストレベルのエビデンスを撮るなら、これで十分だと個人的には思います。
以下は、Javadocです。
org.openqa.selenium.TakesScreenshot
org.openqa.selenium.OutputType
Javadocを眺めていたら、com.thoughtworks.selenium.ScreenshotListenerなんてのもありますねぇ。TestNG用みたいだけど便利そうです。
IEのスクリーンショットを撮る場合は、下記のDLLを手順に従いインストールします。
snapsIE - Free, Open-Source, Scriptable Screen Capture Utility for IE
ここでレジストリに登録する際、regsvr32.exe を実行するのですが、記載されてある通りに実行するとエラーになります。
そこで、下記のサイトを確認すると、64bit版Windowsには2つのバージョンが存在しているとのことです。
Microsoftサポート Regsvr32 の使用法とエラー メッセージについて
DLLは32bit環境を想定しているので、32bit版の regsvr32.exe を使って実行します。
%systemroot%\SysWoW64\regsvr32.exe Snapsie.dll
これで登録できると思います。
テストケースには下記のような感じで実装します。
File screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
File dest = new File("C:\\tmp\\hoge.png");
screenshot.renameTo(dest);
作成される画像の形式は、PNGです。
Temporaryディレクトリ内にPNGファイルが作成されるので、リネームする形で任意の場所に移動させます。
自動化された単体テストレベルのエビデンスを撮るなら、これで十分だと個人的には思います。
以下は、Javadocです。
org.openqa.selenium.TakesScreenshot
org.openqa.selenium.OutputType
Javadocを眺めていたら、com.thoughtworks.selenium.ScreenshotListenerなんてのもありますねぇ。TestNG用みたいだけど便利そうです。
2012年3月20日火曜日
Javaの列挙型(enum)を使う
使おうと思った時に、いつも忘れるのでメモ。
7ステップで理解するJavaでの列挙型/enum使用法
【Step 5】列挙型を使って日本語でも各月の名前を表示
import java.util.EnumMap;
public class Test {
private static EnumMap statusMap;
public static void main(String[] args) {
statusMap = new EnumMap(Status.class);
int i = 0;
for (Status status : Status.values()) {
statusMap.put(status, Integer.valueOf(++i));
}
for (Integer status : statusMap.values()) {
System.out.println(status.intValue());
}
}
private enum Status {
STATUS1
, STATUS2
}
}
7ステップで理解するJavaでの列挙型/enum使用法
【Step 5】列挙型を使って日本語でも各月の名前を表示
ラベル:
Java
2011年6月11日土曜日
EclipseでAndroidのデバッグをする時にDebug certificate expiredというエラーが出る時の解決方法
久しぶりにやったらエラーでデバッグできない状態になったので、そのメモ。
android developers
Signing Your Applications
実行するコマンドはこんな感じ。Javaのkeytoolというやつを使う。
.androidにあるdebug.keystoreを削除して、前述のコマンドを実行するとこんな感じ。
パスワードは、Signing in Debug Modeに記載されている通り入力する。
エラーの出ているEclipseのプロジェクトをCleanするとエラーがなくなって、デバッグが実行可能になる。
android developers
Signing Your Applications
実行するコマンドはこんな感じ。Javaのkeytoolというやつを使う。
"C:\Program Files\Java\jdk1.6.0_26\bin\keytool.exe" -genkey -v -keystore debug.keystore -alias androiddebugkey -keyalg RSA -validity 10000 -dname "CN=Android Debug,O=Android,C=US"
.androidにあるdebug.keystoreを削除して、前述のコマンドを実行するとこんな感じ。
パスワードは、Signing in Debug Modeに記載されている通り入力する。
C:\Users\<ユーザアカウント名>\.android>"C:\Program Files\Java\jdk1.6.0_26\bin\keytool.exe" -genkey -v -keystore debug.keystore -alias androiddebugkey -keyalg RSA -validity 10000 -dname "CN=Android Debug,O=Android,C=US"
キーストアのパスワードを入力してください:
新規パスワードを再入力してください:
10,000 日間有効な 1,024 ビットの RSA の鍵ペアと自己署名型証明書 (SHA1withRSA) を生成しています
ディレクトリ名: CN=Android Debug, O=Android, C=US
<androiddebugkey> の鍵パスワードを入力してください。
(キーストアのパスワードと同じ場合は RETURN を押してください):
[debug.keystore を格納中]
C:\Users\<ユーザアカウント名>\.android>
エラーの出ているEclipseのプロジェクトをCleanするとエラーがなくなって、デバッグが実行可能になる。
2010年9月18日土曜日
Google App Engine for JavaとSlim3でデフォルトのTimeZoneを指定する。その2
何とか実装を楽にしようというか、
POJOを目指して今だ試行錯誤中という感じ。
前回のweb.xmlと下記のコードで動作を確認してみた。
IndexController.java
JSPは割愛。
リクエストスコープにセットした変数をそのまま表示するとこんな感じ。

同じような事をしたい人がいて、比嘉さんが案を提示しています。
Google Group Google App Engine for Java
Set the Timezone
あとはやっぱり自前で用意しちゃうとか。
BLUEBERRY STREAM
LocaleとかTimeZoneとか その2
Slim3使ってるなら大人しくorg.slim3.util.DateUtil使っとけって感じな気がしてきた。
POJOを目指して今だ試行錯誤中という感じ。
前回のweb.xmlと下記のコードで動作を確認してみた。
IndexController.java
package test.controller;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.slim3.controller.Controller;
import org.slim3.controller.Navigation;
import org.slim3.util.DateUtil;
import org.slim3.util.TimeZoneLocator;
public class IndexController extends Controller {
@Override
public Navigation run() throws Exception {
requestScope("timeZone", TimeZoneLocator.get().getID());
Date date = new Date();
String pattern = "yyyy/MM/dd HH:mm:ss zZ";
requestScope("now1", DateUtil.toString(date, pattern));
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
requestScope("now2", sdf.format(date));
return forward("index.jsp");
}
}
JSPは割愛。
リクエストスコープにセットした変数をそのまま表示するとこんな感じ。

同じような事をしたい人がいて、比嘉さんが案を提示しています。
Google Group Google App Engine for Java
Set the Timezone
あとはやっぱり自前で用意しちゃうとか。
BLUEBERRY STREAM
LocaleとかTimeZoneとか その2
Slim3使ってるなら大人しくorg.slim3.util.DateUtil使っとけって感じな気がしてきた。
2010年9月16日木曜日
Google App Engine for JavaとSlim3でデフォルトのTimeZoneを指定する
日時を処理しようとするとデフォルトはUTC。
Slim3のTimezoneアプリのデモで試しました。

そこでweb.xmlに下記のように追加。
するとデフォルトが日本時間になりました。
めでたしめでたし。

Slim3のTimezoneアプリのデモで試しました。

そこでweb.xmlに下記のように追加。
javax.servlet.jsp.jstl.fmt.timeZone Asia/Tokyo
するとデフォルトが日本時間になりました。
めでたしめでたし。

登録:
投稿 (Atom)