Skip to content
This repository has been archived by the owner on May 28, 2019. It is now read-only.

Reusing different backgrounds #41

Closed
ghost opened this issue Jun 5, 2015 · 35 comments
Closed

Reusing different backgrounds #41

ghost opened this issue Jun 5, 2015 · 35 comments

Comments

@ghost
Copy link

ghost commented Jun 5, 2015

@jbpros suggested to reopen an issue here.

I suggested many possible solution in the original post, one of them is the following:

Feature: Viewing post pages

  In order to absorb Lachlan's deep insights into man and machine
  I should be able to visit pages and pages and pages of blog posts

  Group:
    Background:
      Given I am logged in

    Scenario: viewing a post when logged in
      When I view the post page
      Then I see the page

    Scenario: viewing a mobile post when logged in
      When I view the mobile post page
      Then I see the page

    Scenario: viewing a mobile post when not logged in
      When I view the mobile post page
      Then I see the page


  Group:
    Background:
      Given I am not logged in

    Scenario: viewing a post when not logged in
      When I view the post page
      Then I see the page

The focus is on reusing multiple different backgrounds here. I think it's worth a discussion.

@mattwynne
Copy link
Contributor

Interesting. We've had this requested before, but the standard answer is "split your feature into two files" but I can see how this is helpful.

It strikes me that maybe the right way to model this is that scenarios (and scenario outlines) are child nodes of a background. That makes sense to me, and would mean we didn't need the extra Group keyword.

This would need to be supported in each of the Cucumbers though. I wonder if it's too much of a stretch for v3 and we should do this in v4?

@ghost
Copy link
Author

ghost commented Jun 6, 2015

@mattwynne I have not a clue, I am glad at least I started a conversation about it. I did not meant to tell the how, but the what part. Good luck! :-)

Ohh btw. this "I am logged in" stuff occurs very frequently, so I thought it might be extracted from the current feature, and it might be used as a helper or as tag? I don't know, I am not an expert of language design. Probably this is the most dense form of it, and you won't need to reuse the sentence as a tag.

@ghost
Copy link
Author

ghost commented Jun 12, 2015

@mattwynne I think this is loosely related to this missing feature: cucumber/cucumber-js#11 because it is about reusing step definitions as well. I think step reusability is a general problem in the language. It should be handled probably outside of the scope of the features and scenarios, in a similar way than defining functions by an average programming language.

Just an example:

Describe: Calculator

    Feature: adding numbers together

        Scenario: adding 2 numbers together
            Given I add 1
                And I add 2
            When I check the total
            Then it should be 3

        Scenario: adding multiple numbers together
            Given I add 1, 2, 3 and 4
            When I check the total
            Then it should be 10

    Feature: using multiple different operations together

        Scenario: using add and multiply together
            Given I add 1, 2 and 3 together
                And I multiply the result with 4
            When I check the total
            Then it should be 40

I think the main problem here that we are creating just another programming language, which is the complete opposite what we wanted to do with gherkin. Gherkin should be a very high level thing almost the same as plain English. :S I don't know how this can be solved.

Adding named functions/methods as another layer of abstraction is a standard solution by this kind of problems, but you'll need an async lib, which makes things too complex if all you want is simply reusing the code. Another problem with this solution, that if you change the step definition text, then you might need to refactor the related function names as well. So you end up refactoring many things instead of one.

My opinion that calling steps from the step definitions is the best solution and it should be supported with auto-complete and refactoring somehow.

A workaround (:D) to move the reusable part to a gherkin based step definition helper file, so we don't have to write boilerplate code in the actual programming language, and we can use the short syntax without polluting the feature file.

Describe: Calculator

    Define: I add <n>(, <n>)* and <n>
        Given I add <n>

But there is not big difference between this and calling the steps from the step definitions. The latter is easier to solve without new gherkin features.

@Zearin
Copy link
Contributor

Zearin commented Sep 3, 2015

I wonder if it's too much of a stretch for v3 and we should do this in v4?

👍

@aslakhellesoy
Copy link
Contributor

I dunno - I don't think it would be that hard TBH:

Feature: foo
  Background:
  Scenario: a
  Scenario: b

  Background:
  Scenario: c
  Scenario: d

Supporting this should only require minimal changes to the grammar (and parser) - it's the compiler that would have to change - and that hasn't even been written yet!

@mattwynne
Copy link
Contributor

mattwynne commented Sep 3, 2015 via email

@Zearin
Copy link
Contributor

Zearin commented Sep 3, 2015

…and it would be backwards compatible. But it’s scope creep - we need to focus on getting it integrated IMO.

Just slate it for a future minor release. From http://semver.org :

MINOR version when you add functionality in a backwards-compatible manner

Schedule the “getting it integrated” stuff first. Then schedule this PR after that.

Anything wrong with that?

@ghost
Copy link
Author

ghost commented Feb 17, 2016

Another possible solution to reuse code is the following

SubScenario xy
    Given x
        And y

Scenario a
    Given xy
        And z
    When p
    Then q

Scenario b
    Given xy
    When r
    Then t

It's like extracting code to a new function. I am not sure whether this could be used in practice. Did not have time to think about.

In other terms the SubScenario is a named Background, but I guess Backgrounds are only about Givens, while these SubScenarios could be used by all three words during the conversation.

@jfinkhaeuser
Copy link

+1 for backgrounds applying only to the following/nested features

Multiple backgrounds per feature are a massive improvement, IMHO

@jfinkhaeuser
Copy link

Not quite related, but see #198 for another use of backgrounds.

@Mathiou04
Copy link

Borrowing from @Inf3rno example, here is what I would find pretty useful:

Feature: Viewing post pages

In order to absorb Lachlan's deep insights into man and machine
I should be able to visit pages and pages and pages of blog posts

Background 1:
  Given I am logged in

Background 2:
  Given I am not logged in

Scenario: viewing a post
  When I view the post page
  Then I see the page

The example of "logged in/not logged in" might not be the best to illustrate this, but let's say I have some kind of interface class that is inherited many times, and I want to test that all of them works for the same Scenarios.
Currently, I guess I will have to write a feature file per inherited class in which I would put exactly the same Scenarios but a different Background.

In this "use case", I think you might want to have all the Scenarios run against all the possible Background.

@ghost
Copy link
Author

ghost commented Mar 31, 2016

@Mathiou04 I think we should talk at first about the new features and only after that about the syntax.

As far as I know the original features were:

  • a.1.) a single feature contains zero or one background
  • b.1.) backgrounds contain only given statements
  • c.1.) each scenario in the feature uses the background if given
  • d.1.) each scenario uses at most a single background (implicit because of a.1. but not so evident by a.2)

I suggested the following modifications in the original post:

  • a.2.) a single feature can contain many backgrounds

Aslakhellesoy added the following:

  • e.1.) backward compatibility

What you suggested is something like this as far as I understand:

  • d.2.) each scenario iterates through all of the backgrounds in the actual feature

@Mathiou04
Copy link

@Inf3rno: I think you summed it up perfectly, at least for the point I was addressing.
Not sure if what I suggest is only a question of syntax, to me it sounds like a new feature.
But I might be wrong...

@enkessler
Copy link
Contributor

Lots of talk about Backgrounds recently and there do seem to be two distinct features emerging from the conversations:

  1. Having multiple backgrounds in one file
  2. Letting backgrounds behave like outlines

The first feature helps with test organization and the second one helps with test permutations. Intermixing them would be an amusing explosion of raw power. ;)

@ghost
Copy link
Author

ghost commented Mar 31, 2016

@enkessler I like the idea of scenario outline like backgrounds, but I am not sure whether it is possible to find a simple backward compatible syntax.

@jfinkhaeuser
Copy link

@Inf3rno Background vs. Background Outline seems perfectly backwards compatible to me. Forward compatibility is going to be hard :)

@Mathiou04
Copy link

@enkessler: Just had a look at the Scenario Outline, as I wasn't aware of this feature: Background Outline would seem like a perfect solution to me.

@mattwynne
Copy link
Contributor

Can I see a real-world example of this? It seems like something that testers would want, but that would create documentation that's very awkward to read.

@jenisys
Copy link

jenisys commented Apr 6, 2016

I agree with @mattwynne and @aslakhellesoy regarding the first point (multiple backgrounds in a feature). While some kind of grouping mechanism might be cleaner, the approach that a group of scenarios inherits the last seen background in a feature file is closer to backward compatibility. In addition, it might be useful for feature writers.

Regarding the second suggestion with "Background Outline" (Background 1 and Background 2), I agree with @mattwynne that there should be a compelling real-world example first that shows its merit (and this combination functionality is needed). The example from above is not convincing for me because the web server behaviour (and therefore the scenarios) normally differs when a user is logged in or logged out. Therefore, I would not expect to use the same set of scenarios and all should pass.

@Mathiou04
Copy link

Sorry for the delay, planned to answer @mattwynne but couldn't find the proper moment.

Here is my actual use case but I think it can be generalized for any code that used interface classes.

I currently work on a software that need to use a payment platform. As you might know, there are many available (Paypal, Adyen, Braintree, etc...) and the software has to be able to use several of them. I can detail why here if you want but not sure it is relevant.
With all those platforms I want to be able to perform the same kind of operations (called payment authorization, payment capture, payment refund etc...). So I create a Payment class for each of those platform, all inheriting from the same interface class that groups all the methods related to the previously stated operations.
Actually, there is a gem called ActiveMerchant that allows to do something like that.

Now, I want to test that my methods (let's call them authorize, capture and refund) actually work.
I will have one scenario per method:

Scenario: testing authorize
  When I authorize an amount on the credit card
  Then it successes

Scenario: testing capture
  When I capture an amount on the previous authorization
  Then it successes

Scenario: testing refund
  When I refund a capture
  Then it successes

But as I want to test all those scenarios for each Payment system, currently I more or less need to do 3 files with 3 different Backgrounds saying something like:

Background:
  Given I use Paypal

Background:
  Given I use Adyen

Background:
  Given I use Braintree

@jenisys
Copy link

jenisys commented Apr 6, 2016

Ok, I see your point.
You want to add another dimension and need a scenario combination generator, one for each specific context to run the scenarios in. But this needs a new concept, like "Background Outline", "Combination" or "Suite Generation" or ...

Background Outline: 
   Given I use <payment system>

   Examples:
       | payment system |
       | Paypal |
       | Adyen  |
       | Braintree |

This approach would also allow to specify additional dimensions by providing one row per combination to use (by adding additional columns/parameters in the Examples table).

@jfinkhaeuser
Copy link

Well, yes. The Background Outline concept is discussed in #56 .

This here is about multiple Background in a feature, and the suggestion for applying a background to all following scenarios is fairly simple, largely backwards compatible, and just allows a little more flexibility with scenarios.

Actually, logged in vs. not logged in is IMHO the perfect example for why one would want to use this; they're different scenarios all relating to the same feature, some require you to be logged in, and others do not.

@ghost
Copy link
Author

ghost commented Apr 7, 2016

@jfinkhaeuser I agree. I think both solve different problems and could be supported on the long run.

@ghost
Copy link
Author

ghost commented Apr 17, 2016

I had some time to think about background outline and this issue. I think we could use some kind of background template here as well, not just by Background Outlines.

Background Template: I am {authorized} to modify the {section}
    Given I have an account
    And my account is {authorized} to modify the {section} 
    And I am authenticated
    And I view the {section} page

Background Template: I am a visitor of the {section}
    Given I am not authenticated
    And I view the {section} page

Feature: Modifying the todo list

    Background: I am authorized to modify the todo list

    Scenario: editing a task
        When I select a todo to edit
        Then I should be able to modify the selected todo

    Scenario: adding a task
        When I try to add a new todo
        Then the new todo should be added

    Scenario: removing a task
        When I remove a todo
        Then the todo should be removed from the list

    Background: I am a visitor of the todo list

    Scenario: viewing the todo list
        When I look at the content of the current page
        Then I should see the full todo list

Ofc. it does not have to be done this way, it's just brainstorming.

@SabotageAndi
Copy link
Contributor

Just my two cents about this and the other background discussions in #56

I always saw Gherkins purpose is, to be a simple "language", so that everybody is able to understand it and can collaborate on the scenarios.

I like the explanation on the Wikipedia page: https://en.wikipedia.org/wiki/Cucumber_(software)#Gherkin_.28Language.29
... It is designed to be non-technical and human readable, and collectively describes use cases relating to a software system. ...

With the current simplicity sometimes I need already to explain how Backgrounds and Scenario Outlines are to understand. So adding this complexity with multiple Backgrounds in a Feature I think will increase it even higher and make it not understandable by a non-developer.

@dirkrombauts
Copy link
Contributor

I can see how Background reuse would be useful for testing purposes, but the main purpose of gherkin and feature files is to bridge the communication gap between business/non-technical people and IT/technical people. It's important that everybody involved in the project feels comfortable using the feature files.

In my experience business people are not trained/drilled in the kind of technical thinking that decomposes problems in small bits so that the largest number of bits can be reused. I fear that adding these extra background-related features will make the feature files more complicated and alienate business people. And then you would lose the most important and valuable part of BDD.

So I vote for not changing the background handling.

@Mathiou04
Copy link

@jfinkhaeuser: sorry, I understand this topic is about multiple background and not about background outlines, but I might mix those a bit one more time...

@Inf3rno: interesting input. But in the end it looks to me as if it doesn't change the problem of having to repeat Scenarios code, given different backgrounds (if my need is to run multiple Scenarios against multiple Backgrounds)

@SabotageAndi & @dirkrombauts: I see your point and I agree with the primary purpose of Gherkins. But in my humble opinion, it would be a pity to discard features important for a testing framework such as those two (I think @enkessler perfectly sum up the need in his post).
I agree that it is important to keep an easy-to-understand syntax. Let's brainstorm on it then, and try to find a way to answer the developer need with a syntax that is easy to read for the business actor.

Lastly, it looks to me like the tests readability is the responsibility of the developer using the framework. Introducing Background outlines doesn't mean that you have to use it all the time (or at all).

@ghost
Copy link
Author

ghost commented Apr 18, 2016

@Mathiou04 I was just brainstorming. I agree more or less with @dirkrombauts , not all of the solutions are simple enough, but some of them are usable, that's why we are discussing the topic.

@ghost
Copy link
Author

ghost commented Apr 18, 2016

I think the main problem is not with background reusability. It is just a symptom. I tried to start discussion about this, but it was closed very fast. So I write the simple version here, maybe you have some ideas how to handle this problem.

In natural languages we use verbal context, and gherkin wants to be similar to natural languages, and still it does not support verbal contexts in any way. For example if we are talking about features we usually have some important properties with different states, which at some point determine how many scenarios we will have. E.g. by our example: "I am logged in" or "I am not logged in". So we will have at least 2 scenarios. Or "using desktop browser" vs "using mobile browser". We have another property with 2 possible states. So by combining these, we will have 2 x 2 = 4 possible states: "logged in + mobile", "logged in + desktop", "logged out + mobile", "logged out + desktop". By the proposed background syntax we would describe these as:

Background
  Given I am logged in
  And I use desktop browser
...
Background
  Given I am logged in
  And I use mobile browser
...
Background
  Given I am logged out
  And I use desktop browser
...
Background
  Given I am logged out
  And I use mobile browser
...

The more contextual properties we have, the longer it gets and the more repeated Given statements we will have.

Natural languages solve this problem by keeping the context between Backgrounds and only modifying it, changing states, removing contextual properties, etc...

So for example "When I am logged in using the desktop browser if I initiate a then b should happen, but after I log out I won't be able to initiate a any longer except if I use the mobile browser, etc..." Yes, these are rules, but I hope in the future we'll be able to use gherkin to describe these simple rules. So I think we need to keep the context between different Backgrounds and only override it somehow.

Background
  Given I am logged in
  And I use desktop browser
...
Background
  Given I use mobile browser  // desktop -> mobile, and still logged in
...
Background
  Given I am logged out // logged in -> logged out, and still mobile
...
Background
  Given I use desktop browser // mobile -> desktop, and still logged out
...

To make this work and easy debugable, the parser should somehow track the contextual properties and that which Background definition touched which property. But that part is an implementation detail. So I still support this backward compatible format with this extension, that new Background definitions should not reset the verbal context, they should only modify the current context. In some cases this can have drawbacks, but it is still closer to the natural languages than calling a reset before every background change.

This is somewhat similar to

Given x
When a
Then b
When c
Then d
...

just on a higher level. I am not sure whether this is supported by the current gherkin syntax.

@jfinkhaeuser
Copy link

the main purpose of gherkin and feature files is to bridge the communication gap between business/non-technical people and IT/technical people

This is always an important point to filter proposals by, absolutely, but let's not take it too far.

I don't see how non-technical people would, as a rule, be confused by the concept of prerequisites - which is what Backgrounds are, or at least can be explained as. Similarly, prerequisites applying to some, but not all scenarios, isn't a difficult concept.

For what it's worth, the Outline + Example combination is harder to understand, and that's something already in Gherkin.

@Som7
Copy link

Som7 commented Nov 11, 2016

Hello All,

We were using multiple backgrounds in same feature file in our implementation with cucumber "0.10.3". We are using cucumber along with protractor. We have now moved to Cucumber "1.2.1". But we are getting the following parser error:

(27:1): expected: #EOF, #TableRow, #DocStringSeparator, #StepLine, #TagLine, #ScenarioLine, #ScenarioOutlineLine, #Comment, #Empty, got 'background:'
(57:1): expected: #EOF, #TableRow, #DocStringSeparator, #StepLine, #TagLine, #ScenarioLine, #ScenarioOutlineLine, #Comment, #Empty, got 'background:'

Are multiple backgrounds no longer allowed? Is there a workaround to use multiple backgrounds with the newer versions?

@enkessler
Copy link
Contributor

@Som7 Between the version numbers you are describing and the usage of Protractor, I am guessing that you are referring to cucumber-js?

As far as I know, multiple backgrounds have never been allowed (that's kind of the point of this issue thread in the first place). Regardless, cucumber-js upgraded from Gherkin 2.x to Gherkin 4.x with their 1.0.0 release. Gherkin 4.x definitely does not allow multiple backgrounds. By upgrading from 0.x to 1.x of a semantically versioned package, you run the risk of breaking changes and it seems that you have found one of them.

@aslakhellesoy
Copy link
Contributor

I'm puzzled. Multiple backgrounds have never been allowed. Ok, it may have been accepted by the parser (although I doubt it), but I really don't think Cucumber has ever processed more than one.

@Som7
Copy link

Som7 commented Nov 15, 2016

@enkessler Thanks for the response
Yes I am referring to the versions of cucumber-js
For us multiple backgrounds were working. When the next background was processed the first one used to get cleared and we could thus have different background for a different set of tests.
But now its not working with the newer ones :(
Do you know of any workaround that can be used where in I can specify a few steps to run as the precondition for a group of tests? Any help in this direction would be great!

@Som7
Copy link

Som7 commented Nov 15, 2016

@aslakhellesoy Thanks for the response
The first version I worked with was accepting it.It is still working properly in my machine. But now we need to move the the new version which as you said is not parsing multiple backgrounds.
Do you know of any workaround which serves the same purpose as multiple backgrounds?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants