2013年6月21日金曜日

Gradle Wrapperを試す

GradleプロジェクトをGradle Wrapperとともに公開すると、プロジェクトの利用者の端末にあらかじめGradleがインストールされていなくても、Gradleでのビルドが可能になる(ただし、Javaはインストールされている必要がある)。具体的な手順は、以下の通り。

下記のbiuld.gradleを含むGradleプロジェクトがあるとする。

task hello << {
println 'hello'
}
task wrapper(type: Wrapper) {
gradleVersion = '1.6'
}
view raw build.gradle hosted with ❤ by GitHub
プロジェクトの公開者は、Graldeがインストールされている端末で、上記のwrapperタスクを実行する。wrapperタスクを実行すると、Gradle Wrapperの実体として以下のファイルが生成される。
gradlew
gradlew.bat
└─gradle
    └─wrapper
            gradle-wrapper.jar
            gradle-wrapper.properties

プロジェクトの公開者は、GradleプロジェクトをGradle Wrapperとともに公開する(例えば、Gitリポジトリとして公開するなら、build.gradleとともに上記のファイルもcommitし、リポジトリに含める)。

プロジェクトの利用者は上記のGradleプロジェクトを取得し(例えば、Gitリポジトリからcloneする)、gradleコマンドの代わりに、Gradleプロジェクト内に含まれているgradlewコマンドを使ってGradleのタスクを実行する。

例えば、gradlew helloを実行すると、Gradle Wrapper作成時に指定したバージョンのGradleが、ユーザのホームディレクトリ直下の.gradle/wrapper/distsフォルダにダウンロードされ(すでにダウンロードされている場合は、それが使用される)、そこに含まれるgradleコマンドを使ってhelloタスクが実行される。

Gradle Wrapperは上記のような仕組みで動作するため、ビルドに使用するGradleのバージョンを固定できるという利点もある。

関連リンク

2013年6月13日木曜日

diffとpatchの使い方

diffコマンドでパッチを作成する方法と、作成したパッチをpatchコマンドで適用する方法は、下記を参照。


なお個人的には、ディレクトリへのパッチ適用は
  • パッチを当てる時は、その親ディレクトリで作業
  • 親ディレクトリにパッチファイルを配置
  • patch -p1 -d src < hoge.20080201.diff
    • srcはパッチを当てるディレクトリ
 のほうが、しっくりきそう。

関連リンク

cucumber-jvm-groovyをGradleで試す

2013.06.13 追記:タイトルを誤って投稿していたため、先日投稿したものと同じ内容のものを再度アップします。

前提

 

手順


まず、以下のfeature (hello.feature) をsrc/test/resourceに配置する。なお、Rubyでは、featureはfeaturesフォルダに配置される。

Feature: Hello World
Scenario: Say hello
Given I have a hello app with "Howdy"
When I ask it to say hi
Then it should answer with "Howdy World"
view raw hello.feature hosted with ❤ by GitHub

さらに、以下のbuld.gradleを作成する。

apply plugin: 'java'
apply plugin: 'groovy'
apply plugin: 'eclipse'
//build stuff
sourceCompatibility = 1.6
targetCompatibility = 1.6
configurations {
cucumberRuntime {
extendsFrom testRuntime
}
}
dependencies {
// Groovy library for groovy building!
groovy 'org.codehaus.groovy:groovy-all:2.0.0-beta-2'
/*
In order to work around a really flagrant bug ( http://issues.gradle.org/browse/GRADLE-732 )
You have to create a configuration that includes the jar.archivePath (the jar.archivePath is created by the java plugin)
and give it the same name as the cucumberRuntime configuration, or name it something different and have the cucumberRuntime
configuration extend from it as well.
VERY ANNOYING BUG
*/
cucumberRuntime files("${jar.archivePath}")
testCompile 'junit:junit:4.10'
testCompile 'info.cukes:cucumber-junit:1.0.9'
testCompile 'info.cukes:cucumber-groovy:1.0.9'
}
repositories {
mavenCentral()
}
task cucumber() {
dependsOn assemble
doLast {
javaexec {
main = "cucumber.cli.Main"
classpath = configurations.cucumberRuntime
args = ['-f', 'pretty', '--glue', 'src/test/groovy', 'src/test/resources']
}
}
}
view raw build.gradle hosted with ❤ by GitHub

この時点で、gradle cucumberを実行した結果は、以下の通り。
$ gradle cucumber
:compileJava UP-TO-DATE
:compileGroovy UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:jar UP-TO-DATE
:assemble UP-TO-DATE
:cucumber
Feature: Hello World

  Scenario: Say hello                        # hello.feature:3
    Given I have a hello app with "Howdy"
    When I ask it to say hi
    Then it should answer with "Howdy World"


You can implement missing steps with the snippets below:

Given(~'^I have a hello app with "([^"]*)"$') { String arg1 ->
    // Express the Regexp above with the code you wish you had
    throw new PendingException()
}

When(~'^I ask it to say hi$') { ->
    // Express the Regexp above with the code you wish you had
    throw new PendingException()
}

Then(~'^it should answer with "([^"]*)"$') { String arg1 ->
    // Express the Regexp above with the code you wish you had
    throw new PendingException()
}


BUILD SUCCESSFUL

Total time: 2.39 secs

上記出力の後半に出力されているテンプレートをもとに、以下のsetp definition (HelloSteps.groovy) を作成し、src/test/groogyに配置する。なお、Rubyでは、step definitionはfeatures/step_definitionsフォルダに配置される。

import cucumber.runtime.PendingException
this.metaClass.mixin(cucumber.runtime.groovy.Hooks)
this.metaClass.mixin(cucumber.runtime.groovy.EN)
Given(~'^I have a hello app with "([^"]*)"$') { String arg1 ->
// Express the Regexp above with the code you wish you had
throw new PendingException()
}
When(~'^I ask it to say hi$') { ->
// Express the Regexp above with the code you wish you had
throw new PendingException()
}
Then(~'^it should answer with "([^"]*)"$') { String arg1 ->
// Express the Regexp above with the code you wish you had
throw new PendingException()
}

3,4行目でCucmberから呼び出されるメソッドをmixinしている。これを忘れると、Cucumber実行時に必要なメソッドが見つからず、groovy.lang.MissingMethodExceptionが発生してしまうので注意。

再度gradle cucumberタスクを実行すると、cucumber.runtime.PendingExceptionが発生する。これは、step definitionからthrowされているPendingExpectionそのものであり、まだstep definitionが実装されていないことを表している。

ここから、通常はTDD的な手法でstep definitionとテスト対象の機能を実装していくのだが、今回そのあたりの手順は省略。最終的なstep definitionは以下の通り。

this.metaClass.mixin(cucumber.runtime.groovy.Hooks)
this.metaClass.mixin(cucumber.runtime.groovy.EN)
Given(~'^I have a hello app with "([^"]*)"$') { String arg1 ->
hello = new Hello(arg1)
}
When(~'^I ask it to say hi$') { ->
hi = hello.sayHi();
}
Then(~'^it should answer with "([^"]*)"$') { String arg1 ->
assert arg1 == hi
}

なお、step definition内では、コンテキストが共有される。例えば、上記では、Givenメソッドで定義したhelloインスタンス(5行目)をWhenメソッド内で参照(9行目)している。

テスト対象の機能を実装したHelloクラスは、以下の通り。このファイルは、src/main/groogyに配置する。

public class Hello {
String greeting;
public Hello(String greeting){
this.greeting = greeting
}
public String sayHi() {
return greeting + " World";
}
}
view raw Hello.groovy hosted with ❤ by GitHub

再度gradle cucumberタスクを実行する。
$ gradle cucumber
:compileJava UP-TO-DATE
:compileGroovy UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:jar UP-TO-DATE
:assemble UP-TO-DATE
:cucumber
Feature: Hello World

  Scenario: Say hello                        # hello.feature:3
    Given I have a hello app with "Howdy"    # HelloSteps.groovy:13
   Given I have a hello app with "Howdy"
   # HelloSteps.groovy:13
    When I ask it to say hi                  # HelloSteps.groovy:17
   When I ask it to say hi                  # HelloSteps.groovy:17
    Then it should answer with "Howdy World" # HelloSteps.groovy:21


BUILD SUCCESSFUL

Total time: 2.734 secs

Cucumberで定義したテストが、無事パスしたことが確認できる。

 

感想


Ruby版のCucumberと同様にcucumber-jvm-groovyが動作することが確認できた。ただ、実際に使用するとなると、featureをどう記述するかは、なかなか難しそう。このあたりは、Use Case Descriptionと同様の難しさがあるように思う。

 

関連リンク

2013年6月12日水曜日

cucumber-eclipse

cucumber-eclipseは、Cucumberのfeatureファイルを編集するためのEclipse Plugin。


featureファイルのシンタックスハイライト、ソース?整形および保存時の構文チェックが可能。シンプルだが、意外に便利。

2013年6月10日月曜日

Word2007形式のファイルをWord2000形式に変換する

Word2007形式のファイルをWord2000形式に変換するVB Scriptは下記を参照。


上記サイトのスクリプト中で、myDocument.SaveAs FolderName & “\” & FS.GetBaseName(FileName) & “.doc”,0の末尾のゼロはファイル形式を表している模様。詳細は下記を参照。


この数字を替えることで、ほかのファイル形式への変換も可能なはず。