LoginSignup
0
0

More than 5 years have passed since last update.

JBehaveのGivenStoriesでExamples:の顛末

Posted at

前回@なんかの特殊文字をエスケープするのに
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を確認してみる。

JUnitScenarioReporter.java

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している箇所はというと

JUnitScenarioReporter.java

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以外の別のエスケープを模索する

今回は時間が無いため、①で対応することに。
時間をみてリファクトしてみよう。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0