JBehave
  1. JBehave
  2. JBEHAVE-921

Share immutable state between steps

    Details

    • Type: Improvement Improvement
    • Status: Open Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: None
    • Fix Version/s: 4.x
    • Component/s: Core
    • Labels:
      None
    • Number of attachments :
      0

      Description

      In keeping with a more functional design (to prevent global mutable state) it would be nice to be able have some sort of "test context" shared between steps automatically by the test framework.

      I imagine it working something like this:

      @Given("we have a cat")
      public void firstStep(TestContext testContext)

      { ImmutableCat cat = new ImmutableCat("Felix"); testContext.put("cat", cat); }

      @When("the cat is fed")
      public void secondStep(TestContext testContext)

      { ImmutableCat cat = testContext.get("cat"); ImmutableFood food = new Food("Whiskers", FoodType.Dry); ImmutableCat happyCat = cat.feed(food) // Makes cat happy testContext.replace("cat", happyCat); testContext.put("food", food); }

      @Then("the cat is happy")
      public void thirdStep(TestContext testContext)

      { ImmutableCat cat = testContext.get("cat"); assert(cat.getFeels == Feels.Happy, "Why didn't you feed the Cat?"); }

      @Then("the cat ate dry food")
      public void fourthStep(TestContext testContext)

      { ImmutableFood food = testContext.get("food"); assert(food.getFoodType == FoodType.Dry, "The Kitty only likes dry food"); }

      Basically as the steps are called the test context builds up the state of the world from the previous step, and passes it to the next step. It would be nice if this happened automatically if, for example, any of the steps have a "TextContext" paramater defined.

      By doing this it would avoid the need for global mutable state that can cause side effects between steps.

      Please leave comments if you have any other questions. Feed your kitties.

      Thanks.

        Activity

        Hide
        Mauro Talevi added a comment -

        An interesting proposition. For me the real interest would be to share state between steps classes, rather than steps in the same class (which of course this approach would also allow).

        I'll earmark it for 4.0

        Show
        Mauro Talevi added a comment - An interesting proposition. For me the real interest would be to share state between steps classes, rather than steps in the same class (which of course this approach would also allow). I'll earmark it for 4.0
        Mauro Talevi made changes -
        Field Original Value New Value
        Fix Version/s 4.x [ 18279 ]
        Hide
        Sebastian Sickelmann added a comment - - edited

        I am not sure if it's the same goal. But i just wanted to start discussion on ScenarioScoped Injections with Guice and JBehave. I created a prototype at https://github.com/picpromusic/jbehave-core/tree/GuiceScenarioScope .
        If my idea is not applicable to this, answer to my comment and i will post it seperatly on the mailing list.

        I created a small example for the story above at https://github.com/picpromusic/jbehave-core/blob/GuiceScenarioScope/examples/guice/src/main/java/org/jbehave/examples/core/guice/jb921/JBEHAVE_921.java

        Show
        Sebastian Sickelmann added a comment - - edited I am not sure if it's the same goal. But i just wanted to start discussion on ScenarioScoped Injections with Guice and JBehave. I created a prototype at https://github.com/picpromusic/jbehave-core/tree/GuiceScenarioScope . If my idea is not applicable to this, answer to my comment and i will post it seperatly on the mailing list. I created a small example for the story above at https://github.com/picpromusic/jbehave-core/blob/GuiceScenarioScope/examples/guice/src/main/java/org/jbehave/examples/core/guice/jb921/JBEHAVE_921.java
        Hide
        Barrie McGuire added a comment -

        Hi Sebastian, thanks for the example!

        I can see what you're trying to acheive but in this particular case I don't think it's relevant. The main goal of having a TestContext is to avoid mutable global state, which can be altered externally and therefore is not guaranteed to be how you left it at any given time. Your example still relies on a global mutable variable, albiet instantiated by a DI framework.

        The idea here is that each step should only ever see the state of the world when the previous step has finished - with no possibility of anything else ever affecting it.

        Good luck with your prototype! Thanks.

        Show
        Barrie McGuire added a comment - Hi Sebastian, thanks for the example! I can see what you're trying to acheive but in this particular case I don't think it's relevant. The main goal of having a TestContext is to avoid mutable global state, which can be altered externally and therefore is not guaranteed to be how you left it at any given time. Your example still relies on a global mutable variable, albiet instantiated by a DI framework. The idea here is that each step should only ever see the state of the world when the previous step has finished - with no possibility of anything else ever affecting it. Good luck with your prototype! Thanks.
        Hide
        Sebastian Sickelmann added a comment - - edited

        Hi Barrie,

        Thanks for your comment. I think i will start discussion on comp.java.jbehave.devel with my idea of story and scenario scoped injections.

        Just one last question, because i don't see the point of:
        "The idea here is that each step should only ever see the state of the world when the previous step has finished - with no possibility of anything else ever affecting it."

        As i understand the jbehave-core code the execution of a story is always in a single thread, only multiple stories are eventually executed in parallel. I don't see where my prototyp breaks your requirement "that each step should only ever see the state of the world when the previous step has finished".

        Do you mean that the TestContext should always only flush it's values to the next step only if the previous succeed? A little bit of STM? How is success defined? Just no exception thrown or a special successful assert-method call as in your example?

        Show
        Sebastian Sickelmann added a comment - - edited Hi Barrie, Thanks for your comment. I think i will start discussion on comp.java.jbehave.devel with my idea of story and scenario scoped injections. Just one last question, because i don't see the point of: "The idea here is that each step should only ever see the state of the world when the previous step has finished - with no possibility of anything else ever affecting it." As i understand the jbehave-core code the execution of a story is always in a single thread, only multiple stories are eventually executed in parallel. I don't see where my prototyp breaks your requirement "that each step should only ever see the state of the world when the previous step has finished". Do you mean that the TestContext should always only flush it's values to the next step only if the previous succeed? A little bit of STM? How is success defined? Just no exception thrown or a special successful assert-method call as in your example?
        Hide
        Mauro Talevi added a comment -

        Yes, let's bring discussion to the dev list.

        Show
        Mauro Talevi added a comment - Yes, let's bring discussion to the dev list.

          People

          • Assignee:
            Unassigned
            Reporter:
            Barrie McGuire
          • Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated:

              Time Tracking

              Estimated:
              Original Estimate - 1 week
              1w
              Remaining:
              Remaining Estimate - 1 week
              1w
              Logged:
              Time Spent - Not Specified
              Not Specified