Loading ...
Sorry, an error occurred while loading the content.

Re: [junit] Chaining of rules

Expand Messages
  • Malte Finsterwalder
    I would prefer to give rules in the order they are applied. How would I name the methods? Hmmm.... Maybe just: RuleChain.first(new FirstRule()).next(new
    Message 1 of 12 , Aug 1, 2011
    • 0 Attachment
      I would prefer to give rules in the order they are applied.

      How would I name the methods? Hmmm....

      Maybe just:
      RuleChain.first(new FirstRule()).next(new SecondRule()).next(new ThirdRule()); ?

      Greetings,
      Malte

      On 30 July 2011 10:33, stefan.birkner <mail@...> wrote:
      > Hello,
      > sometimes you care about the order of rules. Therefore I created a RuleChain, which is a rule itself:
      >
      > @Rule
      > public TestRule chain = RuleChain.outerRule(new FirstRule()).enclose(new SecondRule());
      >
      > What do you thing about the naming outerRule and enclose?
      >
      > What do you think about starting with the outer rule instead of starting with the inner rule:
      >
      > @Rule
      > public TestRule chain = RuleChain.innerRule(new SecondRule()).enclosedBy(new FirstRule());
      >
      > If you want to see the code, look at https://github.com/stefanbirkner/junit/commit/3584c44bedd8705f30dda4f4213fa45655b998c7
      > The issue is https://github.com/KentBeck/junit/issues/193
      >
      > ciao,
      > stefan
    • Kent Beck
      The lack of order of rules is by design. Rules are intended to be composeable and order-independent. I would need a compelling use case to tighten this
      Message 2 of 12 , Aug 1, 2011
      • 0 Attachment
        The lack of order of rules is by design. Rules are intended to be composeable and order-independent. I would need a compelling use case to tighten this constraint.

        Kent

        On Jul 30, 2011, at 1:33 AM, stefan.birkner wrote:

        > Hello,
        > sometimes you care about the order of rules. Therefore I created a RuleChain, which is a rule itself:
        >
        > @Rule
        > public TestRule chain = RuleChain.outerRule(new FirstRule()).enclose(new SecondRule());
        >
        > What do you thing about the naming outerRule and enclose?
        >
        > What do you think about starting with the outer rule instead of starting with the inner rule:
        >
        > @Rule
        > public TestRule chain = RuleChain.innerRule(new SecondRule()).enclosedBy(new FirstRule());
        >
        > If you want to see the code, look at https://github.com/stefanbirkner/junit/commit/3584c44bedd8705f30dda4f4213fa45655b998c7
        > The issue is https://github.com/KentBeck/junit/issues/193
        >
        > ciao,
        > stefan
        >
        >



        [Non-text portions of this message have been removed]
      • Malte Finsterwalder
        ... This makes total sense to me in general and I would not change it! But if I do have a problem that needs a specific order, I think the trick to use a
        Message 3 of 12 , Aug 1, 2011
        • 0 Attachment
          On 1 August 2011 16:31, Kent Beck <kentb@...> wrote:
          > The lack of order of rules is by design. Rules are intended to be composeable and order-independent. I would need a compelling use case to tighten this constraint.

          This makes total sense to me in general and I would not change it!

          But if I do have a problem that needs a specific order, I think the
          trick to use a chaining Rule sounds like the best workaround I can
          think of right now.
          And that's what it is to me: A workaround.

          For example in my current project: We have a "registry" for dependency
          lookup. This needs to be initiated before some other things can
          happen.
          We don't currently have a Rules problem here, but I can imaging, that
          such a quirky design can lead to such problems. And then a workaround
          might be helpful.
          (Yes, this really is a design flaw in the application and we are
          working on fixing it soon.)

          Greetings,
          Malte
        • David Saff
          Kent, I ve seen several examples in the wild. Easiest to explain is this: I have an ExternalResource that starts and stops an expensive server. I also have a
          Message 4 of 12 , Aug 4, 2011
          • 0 Attachment
            Kent,

            I've seen several examples in the wild. Easiest to explain is this: I
            have an ExternalResource that starts and stops an expensive server. I
            also have a Timeout rule. If the Timeout is applied around the
            ExternalResource, then I am asserting that server startup + test +
            server stopping all happens within the timeout. If the
            ExternalResource is applied around the Timeout, then I am ignoring the
            server startup time, and just asserting about the test time.

            One possibility is to create specialized TimeoutExternalResource and
            ExternalResourceTimeout rules that bake-in the ordering. I like the
            RuleChain approach better, because it encourages separation of
            concerns.

            David Saff

            On Mon, Aug 1, 2011 at 10:31 AM, Kent Beck <kentb@...> wrote:
            > The lack of order of rules is by design. Rules are intended to be composeable and order-independent. I would need a compelling use case to tighten this constraint.
            >
            > Kent
            >
            > On Jul 30, 2011, at 1:33 AM, stefan.birkner wrote:
            >
            >> Hello,
            >> sometimes you care about the order of rules. Therefore I created a RuleChain, which is a rule itself:
            >>
            >> @Rule
            >> public TestRule chain = RuleChain.outerRule(new FirstRule()).enclose(new SecondRule());
            >>
            >> What do you thing about the naming outerRule and enclose?
            >>
            >> What do you think about starting with the outer rule instead of starting with the inner rule:
            >>
            >> @Rule
            >> public TestRule chain = RuleChain.innerRule(new SecondRule()).enclosedBy(new FirstRule());
            >>
            >> If you want to see the code, look at https://github.com/stefanbirkner/junit/commit/3584c44bedd8705f30dda4f4213fa45655b998c7
            >> The issue is https://github.com/KentBeck/junit/issues/193
            >>
            >> ciao,
            >> stefan
            >>
            >>
            >
            >
            >
            > [Non-text portions of this message have been removed]
            >
            >
            >
            > ------------------------------------
            >
            > Yahoo! Groups Links
            >
            >
            >
            >
          • jens_schauder
            I agree with David. I am having the pretty much this scenario right now. I think it is related to rules doing fundamental different things: - doing setup/tear
            Message 5 of 12 , Aug 5, 2011
            • 0 Attachment
              I agree with David. I am having the pretty much this scenario right now.

              I think it is related to rules doing fundamental different things:

              - doing setup/tear down work

              - doing runtime manipulation of the test execution, like executing it in parallel or in special thread (e.g. Swing EDT)

              - doing additional assertions like the mentioned Timeout Rule.

              If you have rules from different groups you need to control the order of things very often.

              Jens

              --- In junit@yahoogroups.com, David Saff <david@...> wrote:
              >
              > Kent,
              >
              > I've seen several examples in the wild. Easiest to explain is this: I
              > have an ExternalResource that starts and stops an expensive server. I
              > also have a Timeout rule. If the Timeout is applied around the
              > ExternalResource, then I am asserting that server startup + test +
              > server stopping all happens within the timeout. If the
              > ExternalResource is applied around the Timeout, then I am ignoring the
              > server startup time, and just asserting about the test time.
              >
            • jens_schauder
              I don t like this idea. Using something like next basically refers to the order in which the Rules are called. But for most Rules I have seen, the
              Message 6 of 12 , Aug 5, 2011
              • 0 Attachment
                I don't like this idea. Using something like 'next' basically refers to the order in which the Rules are called. But for most Rules I have seen, the interesting stuff happens in the Statements. So people say Rule, but really mean Statement. And for Statements 'next' doesn't make sense, while 'enclosed' does.

                Jens

                --- In junit@yahoogroups.com, Malte Finsterwalder <malte@...> wrote:
                >
                > I would prefer to give rules in the order they are applied.
                >
                > How would I name the methods? Hmmm....
                >
                > Maybe just:
                > RuleChain.first(new FirstRule()).next(new SecondRule()).next(new ThirdRule()); ?
                >
                > Greetings,
                > Malte
                >
                > On 30 July 2011 10:33, stefan.birkner <mail@...> wrote:
                > > Hello,
                > > sometimes you care about the order of rules. Therefore I created a RuleChain, which is a rule itself:
                > >
                > > @Rule
                > > public TestRule chain = RuleChain.outerRule(new FirstRule()).enclose(new SecondRule());
                > >
                > > What do you thing about the naming outerRule and enclose?
                > >
                > > What do you think about starting with the outer rule instead of starting with the inner rule:
                > >
                > > @Rule
                > > public TestRule chain = RuleChain.innerRule(new SecondRule()).enclosedBy(new FirstRule());
                > >
                > > If you want to see the code, look at https://github.com/stefanbirkner/junit/commit/3584c44bedd8705f30dda4f4213fa45655b998c7
                > > The issue is https://github.com/KentBeck/junit/issues/193
                > >
                > > ciao,
                > > stefan
                >
              • jens_schauder
                +1 for the idea and +1 for the first variant. Jens
                Message 7 of 12 , Aug 5, 2011
                • 0 Attachment
                  +1 for the idea
                  and
                  +1 for the first variant.

                  Jens

                  --- In junit@yahoogroups.com, "stefan.birkner" <mail@...> wrote:
                  >
                  > Hello,
                  > sometimes you care about the order of rules. Therefore I created a RuleChain, which is a rule itself:
                  >
                  > @Rule
                  > public TestRule chain = RuleChain.outerRule(new FirstRule()).enclose(new SecondRule());
                  >
                  > What do you thing about the naming outerRule and enclose?
                  >
                  > What do you think about starting with the outer rule instead of starting with the inner rule:
                  >
                  > @Rule
                  > public TestRule chain = RuleChain.innerRule(new SecondRule()).enclosedBy(new FirstRule());
                  >
                  > If you want to see the code, look at https://github.com/stefanbirkner/junit/commit/3584c44bedd8705f30dda4f4213fa45655b998c7
                  > The issue is https://github.com/KentBeck/junit/issues/193
                  >
                  > ciao,
                  > stefan
                  >
                • David Saff
                  A challenge in this naming is that if I want this ordering: Rule A has control Rule B has control Test method has control Rule B has control Rule A has control
                  Message 8 of 12 , Aug 5, 2011
                  • 0 Attachment
                    A challenge in this naming is that if I want this ordering:

                    Rule A has control
                    Rule B has control
                    Test method has control
                    Rule B has control
                    Rule A has control

                    Then "first" and "next" are somewhat ambiguous:

                    - A is "first" in the sense that it gets control first
                    - B is "first" in the sense that, as somewhat of an implementation
                    detail, it is wrapped around the test before A is wrapped around B.

                    Or perhaps if I didn't know the implementation, I would find only the
                    first meaning interesting?

                    David Saff

                    On Mon, Aug 1, 2011 at 3:56 AM, Malte Finsterwalder
                    <malte@...> wrote:
                    > I would prefer to give rules in the order they are applied.
                    >
                    > How would I name the methods? Hmmm....
                    >
                    > Maybe just:
                    > RuleChain.first(new FirstRule()).next(new SecondRule()).next(new ThirdRule()); ?
                    >
                    > Greetings,
                    >   Malte
                    >
                    > On 30 July 2011 10:33, stefan.birkner <mail@...> wrote:
                    >> Hello,
                    >> sometimes you care about the order of rules. Therefore I created a RuleChain, which is a rule itself:
                    >>
                    >> @Rule
                    >> public TestRule chain = RuleChain.outerRule(new FirstRule()).enclose(new SecondRule());
                    >>
                    >> What do you thing about the naming outerRule and enclose?
                    >>
                    >> What do you think about starting with the outer rule instead of starting with the inner rule:
                    >>
                    >> @Rule
                    >> public TestRule chain = RuleChain.innerRule(new SecondRule()).enclosedBy(new FirstRule());
                    >>
                    >> If you want to see the code, look at https://github.com/stefanbirkner/junit/commit/3584c44bedd8705f30dda4f4213fa45655b998c7
                    >> The issue is https://github.com/KentBeck/junit/issues/193
                    >>
                    >> ciao,
                    >> stefan
                    >
                    >
                    > ------------------------------------
                    >
                    > Yahoo! Groups Links
                    >
                    >
                    >
                    >
                  • Esko Luontola
                    Recently I had this kind of example: I have a AppRunner rule which is responsible for starting/stopping the application before/after its end-to-end tests. The
                    Message 9 of 12 , Aug 6, 2011
                    • 0 Attachment
                      Recently I had this kind of example:

                      I have a AppRunner rule which is responsible for starting/stopping the
                      application before/after its end-to-end tests. The AppRunner in turn
                      uses the org.junit.rules.TemporaryFolder rule to create its temporary
                      directories. At first I had code like this:

                      @Rule public TemporaryFolder sandbox = new TemporaryFolder();
                      @Rule public AppRunner app = new AppRunner(sandbox);

                      But since that didn't work quite right, I had to embed the
                      TemporaryFolder inside AppRunner and manually wrap it around AppRunner's
                      execution.

                      BTW, it would be better for TemporaryFolder to throw an exception if its
                      getRoot/newFile/newFolder method is called before create() is called.
                      When I was using it incorrectly, my tests were polluting the current
                      working directory with temporary files, because new File(null, fileName)
                      produces a relative path. I'll go file an issue about this...


                      David Saff wrote on 4.8.2011 20:45:
                      > Kent,
                      >
                      > I've seen several examples in the wild. Easiest to explain is this: I
                      > have an ExternalResource that starts and stops an expensive server. I
                      > also have a Timeout rule. If the Timeout is applied around the
                      > ExternalResource, then I am asserting that server startup + test +
                      > server stopping all happens within the timeout. If the
                      > ExternalResource is applied around the Timeout, then I am ignoring the
                      > server startup time, and just asserting about the test time.
                      >
                      > One possibility is to create specialized TimeoutExternalResource and
                      > ExternalResourceTimeout rules that bake-in the ordering. I like the
                      > RuleChain approach better, because it encourages separation of
                      > concerns.
                      >
                      > David Saff
                      >

                      --
                      Esko Luontola
                      www.orfjackal.net
                    • Stefan Birkner
                      The separation of concerns is essential. If somebody needs to create a composition of two rules, we should provide the tool. Imagine a UserProviderRule and a
                      Message 10 of 12 , Aug 6, 2011
                      • 0 Attachment
                        The separation of concerns is essential. If somebody needs to create a composition of two rules, we should provide the tool.

                        Imagine a UserProviderRule and a ProductRule. The UserProviderRule creates a user and deletes it after the test. The ProductRule is configured with a user and adds a product to its shopping cart and deletes it after the test. Both rules work pretty for itself, but we could create a nice rule by combining the UserProviderRule and the ProductProviderRule. The new rule will create a user with a product and delete both after the test.

                        --- In junit@yahoogroups.com, David Saff <david@...> wrote:
                        >
                        > Kent,
                        >
                        > I've seen several examples in the wild. Easiest to explain is this: I
                        > have an ExternalResource that starts and stops an expensive server. I
                        > also have a Timeout rule. If the Timeout is applied around the
                        > ExternalResource, then I am asserting that server startup + test +
                        > server stopping all happens within the timeout. If the
                        > ExternalResource is applied around the Timeout, then I am ignoring the
                        > server startup time, and just asserting about the test time.
                        >
                        > One possibility is to create specialized TimeoutExternalResource and
                        > ExternalResourceTimeout rules that bake-in the ordering. I like the
                        > RuleChain approach better, because it encourages separation of
                        > concerns.
                        >
                        > David Saff
                        >
                        > On Mon, Aug 1, 2011 at 10:31 AM, Kent Beck <kentb@...> wrote:
                        > > The lack of order of rules is by design. Rules are intended to be composeable and order-independent. I would need a compelling use case to tighten this constraint.
                        > >
                        > > Kent
                        > >
                        > > On Jul 30, 2011, at 1:33 AM, stefan.birkner wrote:
                        > >
                        > >> Hello,
                        > >> sometimes you care about the order of rules. Therefore I created a RuleChain, which is a rule itself:
                        > >>
                        > >> @Rule
                        > >> public TestRule chain = RuleChain.outerRule(new FirstRule()).enclose(new SecondRule());
                        > >>
                        > >> What do you thing about the naming outerRule and enclose?
                        > >>
                        > >> What do you think about starting with the outer rule instead of starting with the inner rule:
                        > >>
                        > >> @Rule
                        > >> public TestRule chain = RuleChain.innerRule(new SecondRule()).enclosedBy(new FirstRule());
                        > >>
                        > >> If you want to see the code, look at https://github.com/stefanbirkner/junit/commit/3584c44bedd8705f30dda4f4213fa45655b998c7
                        > >> The issue is https://github.com/KentBeck/junit/issues/193
                        > >>
                        > >> ciao,
                        > >> stefan
                        > >>
                        > >>
                        > >
                        > >
                        > >
                        > > [Non-text portions of this message have been removed]
                        > >
                        > >
                        > >
                        > > ------------------------------------
                        > >
                        > > Yahoo! Groups Links
                        > >
                        > >
                        > >
                        > >
                        >
                      • David Saff
                        Back to naming, I think: 1) I like having the outermost rule first in the chain, because, among other reasons, if the ordering matters, it s because the inner
                        Message 11 of 12 , Aug 8, 2011
                        • 0 Attachment
                          Back to naming, I think:

                          1) I like having the outermost rule first in the chain, because, among
                          other reasons, if the ordering matters, it's because the inner rules
                          are depending on the context provided by the outer rules, so outermost
                          to innermost is the right conceptual ordering.
                          2) I like outerRule, or outermost, as the first method name. I prefer
                          "around" to "enclose", because the connotations are similar, but
                          "around" will be familiar to users of Lisp's defadvice macro who are
                          currently using JUnit (yes, both of us...)

                          David Saff

                          On Sat, Jul 30, 2011 at 4:33 AM, stefan.birkner <mail@...> wrote:
                          > Hello,
                          > sometimes you care about the order of rules. Therefore I created a RuleChain, which is a rule itself:
                          >
                          > @Rule
                          > public TestRule chain = RuleChain.outerRule(new FirstRule()).enclose(new SecondRule());
                          >
                          > What do you thing about the naming outerRule and enclose?
                          >
                          > What do you think about starting with the outer rule instead of starting with the inner rule:
                          >
                          > @Rule
                          > public TestRule chain = RuleChain.innerRule(new SecondRule()).enclosedBy(new FirstRule());
                          >
                          > If you want to see the code, look at https://github.com/stefanbirkner/junit/commit/3584c44bedd8705f30dda4f4213fa45655b998c7
                          > The issue is https://github.com/KentBeck/junit/issues/193
                          >
                          > ciao,
                          > stefan
                          >
                          >
                          >
                          > ------------------------------------
                          >
                          > Yahoo! Groups Links
                          >
                          >
                          >
                          >
                        Your message has been successfully submitted and would be delivered to recipients shortly.