前回@なんかの特殊文字をエスケープするのに
Examples:を使用して対応した件の続き。
実はこのstoryをGivenStoriesとして実行したかったのに
Examples:はGivenStoriesで実行するとなぜかこける!
これまた困った。。。
|id|pass|
|xxx@domain.com|hogehoge|
Failed to run story scenario/xxx.story
java.lang.NullPointerException
at de.codecentric.jbehave.junit.monitoring.JUnitScenarioReporter.example(JUnitScenarioReporter.java:197)
at org.jbehave.core.reporters.DelegatingStoryReporter.example(DelegatingStoryReporter.java:91)
at org.jbehave.core.reporters.ConcurrentStoryReporter.example(ConcurrentStoryReporter.java:209)
at org.jbehave.core.embedder.StoryRunner.runScenariosParametrisedByExamples(StoryRunner.java:429)
at org.jbehave.core.embedder.StoryRunner.runCancellable(StoryRunner.java:303)
at org.jbehave.core.embedder.StoryRunner.run(StoryRunner.java:220)
at org.jbehave.core.embedder.StoryRunner.runGivenStories(StoryRunner.java:389)
at org.jbehave.core.embedder.StoryRunner.runCancellable(StoryRunner.java:272)
at org.jbehave.core.embedder.StoryRunner.run(StoryRunner.java:220)
at org.jbehave.core.embedder.StoryRunner.run(StoryRunner.java:181)
at org.jbehave.core.embedder.StoryManager$EnqueuedStory.call(StoryManager.java:235)
at org.jbehave.core.embedder.StoryManager$EnqueuedStory.call(StoryManager.java:207)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at com.google.common.util.concurrent.MoreExecutors$SameThreadExecutorService.execute(MoreExecutors.java:297)
at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:92)
at com.google.common.util.concurrent.AbstractListeningExecutorService.submit(AbstractListeningExecutorService.java:58)
at com.google.common.util.concurrent.AbstractListeningExecutorService.submit(AbstractListeningExecutorService.java:37)
at org.jbehave.core.embedder.StoryManager.submit(StoryManager.java:204)
at org.jbehave.core.embedder.StoryManager.runningStory(StoryManager.java:132)
at org.jbehave.core.embedder.StoryManager.filterRunning(StoryManager.java:116)
at org.jbehave.core.embedder.StoryManager.runningStoriesAsPaths(StoryManager.java:101)
at org.jbehave.core.embedder.StoryManager.runStories(StoryManager.java:78)
at org.jbehave.core.embedder.Embedder.runStoriesAsPaths(Embedder.java:203)
at de.codecentric.jbehave.junit.monitoring.JUnitReportingRunner.run(JUnitReportingRunner.java:78)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
というわけでいろいろ調べてみた
同じような問題抱えてる人がちょくちょくいるみたいで
以下のページでは回答として4.0bだと
「The JBehave-core 4.0-beta-9 seems to work just fine」
うまく動いてるように見えるよーとのこと。
http://stackoverflow.com/questions/25589963/jbehave-junit-runner-throwing-nullpointerexception
現在当方のJBehaveのバージョンは3.9.3。
とりあえずバージョン上げて試してみることに。
結果は以下の通り。
3.9.4⇒×(エラーは3.9.3と同じ)
4.0-beta-9⇒×(エラーの出方変わったな)
4.0-beta-10⇒×(上に同じ)
Failed to run story scenario/xxx.story
Example: {id=xxx@domain.com, pass=hogehoge}
Failed to run story scenario/xxx.story
org.jbehave.core.failures.UUIDExceptionWrapper: java.lang.NullPointerException
at org.jbehave.core.embedder.PerformableTree.perform(PerformableTree.java:366)
at org.jbehave.core.embedder.StoryManager$EnqueuedStory.call(StoryManager.java:265)
at org.jbehave.core.embedder.StoryManager$EnqueuedStory.call(StoryManager.java:241)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at com.google.common.util.concurrent.MoreExecutors$SameThreadExecutorService.execute(MoreExecutors.java:297)
at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:92)
at com.google.common.util.concurrent.AbstractListeningExecutorService.submit(AbstractListeningExecutorService.java:58)
at com.google.common.util.concurrent.AbstractListeningExecutorService.submit(AbstractListeningExecutorService.java:37)
at org.jbehave.core.embedder.StoryManager.submit(StoryManager.java:238)
at org.jbehave.core.embedder.StoryManager.runningStory(StoryManager.java:155)
at org.jbehave.core.embedder.StoryManager.filterRunning(StoryManager.java:139)
at org.jbehave.core.embedder.StoryManager.runningStories(StoryManager.java:131)
at org.jbehave.core.embedder.StoryManager.performStories(StoryManager.java:115)
at org.jbehave.core.embedder.StoryManager.runStories(StoryManager.java:102)
at org.jbehave.core.embedder.StoryManager.runStoriesAsPaths(StoryManager.java:81)
at org.jbehave.core.embedder.Embedder.runStoriesAsPaths(Embedder.java:204)
at de.codecentric.jbehave.junit.monitoring.JUnitReportingRunner.run(JUnitReportingRunner.java:78)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.lang.NullPointerException
at de.codecentric.jbehave.junit.monitoring.JUnitScenarioReporter.example(JUnitScenarioReporter.java:197)
at org.jbehave.core.reporters.DelegatingStoryReporter.example(DelegatingStoryReporter.java:91)
at org.jbehave.core.reporters.ConcurrentStoryReporter.example(ConcurrentStoryReporter.java:210)
at org.jbehave.core.embedder.PerformableTree$ExamplePerformableScenario.perform(PerformableTree.java:903)
at org.jbehave.core.embedder.PerformableTree$PerformableScenario.perform(PerformableTree.java:814)
at org.jbehave.core.embedder.PerformableTree$PerformableStory.performScenarios(PerformableTree.java:747)
at org.jbehave.core.embedder.PerformableTree$PerformableStory.perform(PerformableTree.java:726)
at org.jbehave.core.embedder.PerformableTree$PerformableStory.performGivenStories(PerformableTree.java:740)
at org.jbehave.core.embedder.PerformableTree$PerformableStory.perform(PerformableTree.java:725)
at org.jbehave.core.embedder.PerformableTree.performCancellable(PerformableTree.java:380)
at org.jbehave.core.embedder.PerformableTree.perform(PerformableTree.java:360)
... 23 more
うん、全く動きません。
それよりも釈然としないのが、何でNullPointerException???
でもパラメータ見る限りExamples自体は取れてる模様。
とりあえずエラーの起点になってるJUnitScenarioReporterを確認してみる。
L.198~
public void example(Map<String, String> arg0) {
logger.info("Example: {}", arg0);
stepDescriptions = nextExample.getChildren().iterator(); // nextExampleがnull
if (stepDescriptions.hasNext()) {
currentStep = stepDescriptions.next();
}
if (exampleDescriptions.hasNext()) {
nextExample = exampleDescriptions.next();
}
}
nullだったのはnextExample。じゃsetしている箇所はというと
L.128~
public void beforeScenario(String title) {
logger.info("Before Scenario: {}", title);
if (!givenStoryContext) { // ←え、何これ。
notifier.fireTestStarted(currentScenario);
ArrayList<Description> children = currentScenario.getChildren();
List<Description> examples = filterExamples(children);
if (!examples.isEmpty()) {
exampleDescriptions = examples.iterator();
if (exampleDescriptions.hasNext()) {
nextExample = exampleDescriptions.next(); // ここでsetなんだが…
}
}
if (children.size() > examples.size()) {
// in case of given stories, these steps are actually stories,
// for which events
// will be fired in beforeStory(..., true)
ArrayList<Description> steps = new ArrayList<Description>(
currentScenario.getChildren());
steps.removeAll(examples);
stepDescriptions = getAllDescendants(steps).iterator();
if (stepDescriptions.hasNext()) {
currentStep = stepDescriptions.next();
}
}
}
}
つまりgivenStoriesではExamplesの中身を展開しません、ってことですね。。。
これは憶測だけど、
GivenStoriesとメインのStoryでExamples設定が重複すると不都合があるから
GivenStories側は殺してるんじゃないかなーとか。
ここで二者択一を迫られる
①諦めてメインのstoryに書いちゃう
②別の方法を模索する
あ、嘘。もう一個あった。
③Examples以外の別のエスケープを模索する
今回は時間が無いため、①で対応することに。
時間をみてリファクトしてみよう。