Code Monkey home page Code Monkey logo

Comments (7)

ccthiel avatar ccthiel commented on August 27, 2024

I've also run into this error when upgrading from 0.10.0 to 1.0.0.
While it doesn't cause the run to fail, if you're using the --rerun option of the cucumber run and outputting it to a file, it does cause the resulting file to contain nothing but ": : : :" in the file, which obviously causes cucumber to barf when you try to run that file.

Should note my setup is exactly the same as above, running a feature file that has a background and excluding tags for the only scenario within that feature file causes this.

from cucumber-ruby.

ccthiel avatar ccthiel commented on August 27, 2024

So, I've tracked down the problem to a block of code that capybara calls.

In capybara-1.0.0/lib/capybara/cucumber.rb, we have:

  scenario.source_tag_names.each do |tag|
    driver_name = tag.sub(/^@/, '').to_sym
    if Capybara.drivers.has_key?(driver_name)
      Capybara.current_driver = driver_name
    end
    end

`````` end

All well and good in most situations, but in the above situation we have no scenarios.
In this case, cucumber does the following, in cucumber-1.0.1/lib/cucumber/ast/background.rb:
```def hook_context
  @feature_elements.first || self
```end

..so if there aren't any feature elements, ```Background``` simply passes itself along for any of the hooks.
Great, until it hits the capybara code above, which calls source_tag_names.
From what I can tell, a ```Background``` can't have tags, and a simple look through background.rb shows
that indeed, tags are never initialized when a background is created.

```def initialize(comment, line, keyword, title, description, raw_steps)
  @comment, @line, @keyword, @title, @description, @raw_steps = comment, line, keyword, title, description, raw_steps
  @feature_elements = []
```end

From what I can tell, they're never initialized anywhere. So when the capybara code executes, it tanks because
source_tag_names, which lies in cucumber-1.0.1/lib/cucumber/ast/feature_element.rb and is a module that
```Background``` includes, looks like this:
```def source_tag_names
  (@tags.tag_names.to_a + (@feature ? @feature.source_tag_names.to_a : [])).uniq
```end

Which is what is causing the ```NoMethodError```, as @tags is nill for a background.
I don't believe this is any wrong doing on capybara's part to assume that it can
call ```Before do |scenario|``` regardless of what things look like in the feature file.

There's any number of simple solutions to this, the easiest of which is
something like overriding ```source_tag_names``` in ```Background``` to return ```nil```, but that feels pretty
wrong to me. My bigger question is why is ```Background``` being treated as a ```FeatureElement``` when
in this case, it behaves differently? (has no tags) The better approach may be to refactor the 
```FeatureElement``` and remove those things that are common to ```FeatureElement``` and ```Background```
into a new module, and only keep the behavior common to ```FeatureElement``` in that module.
This may be a bit overkill if ```source_tag_names``` is the only behavior that ```Background``` doesn't share with the other
feature elements, however. I haven't come across anything else in that module that doesn't apply to
a ```Background``` yet.

Or simply change the method in ```FeatureElement``` from:
 ```def source_tag_names
  (@tags.tag_names.to_a  + (@feature ? @feature.source_tag_names.to_a : [])).uniq
 ```end

to:

```def source_tag_names
  (@tags ? @tags.tag_names.to_a : [] + (@feature ? @feature.source_tag_names.to_a : [])).uniq
 ```end
This causes a test error elsewhere that would have to be looked into, but could also be a viable solution.


I'd be happy to code up a test and solution to this problem and submit a patch, but I'm not sure which approach
people would like taken.

Comments? Thoughts?

from cucumber-ruby.

luishurtado avatar luishurtado commented on August 27, 2024

@ccthiel, Thank you for such clear explanation of the source of the problem.
+1 to the refactor of FeatureElement.

from cucumber-ruby.

ccthiel avatar ccthiel commented on August 27, 2024

Haven't heard anything from anyone else, so I just forked cucumber and, for the time being, took my final approach of refactoring:
def source_tag_names
(@tags.tag_names.to_a + (@feature ? @feature.source_tag_names.to_a : [])).uniq
end

to

def source_tag_names
(@tags ? @tags.tag_names.to_a : [] + (@feature ? @feature.source_tag_names.to_a : [])).uniq
end

This is causing a few test failures when running the tests for cucumber which I haven't fixed, however. I've just been waiting to hear something from anyone before I put any more effort into this and get a little guidance as to exactly where and how the tests for cucumber are run, as the setup for it is confusing me.

from cucumber-ruby.

mattwynne avatar mattwynne commented on August 27, 2024

@ccthiel thanks for your hard work and sorry it feels like nobody has been listening - it was a problem with the github notifications that's hopefully been fixed now.

You've discovered that the modelling of scenarios is quite flawed in Cucumber right now. There have been a number of brave attempts to refactor or rewrite it but so far none of them have made it back out into daylight - it's a big rabbit warren.

From reading your analysis, it seems to me that the root cause is that the hook is firing at all when there are no scenarios to run. In my mind, the background steps are really part of each scenario, so if there are no scenarios there are no hooks to fire.

It also sounds as if splitting FeatureElement might be a good idea. I think it was originally intended to model what I'd probably now call a Keyword, something that has this structure:

Keyword: Name
  Description

Which fits all the keywords like Feature, Background, Scenario, Scenario Outline, Examples. If FeatureElement has been bloated out with other responsibilities, split it!

As for getting the tests to run, you should be able to just run rake in the root directory, and it will run the specs, plus both sets of features (ugly old pre-aruba ones and shiny new aruba-friendly ones).

It would be great to see some more energy put into refactoring. Try to send us nice small pull requests with baby-step refactorings, keeping the tests passing each time.

from cucumber-ruby.

mattwynne avatar mattwynne commented on August 27, 2024

Closing due to inactivity. This should be fixed by the work going into the AST for 2.0 e.g. #319

from cucumber-ruby.

lock avatar lock commented on August 27, 2024

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

from cucumber-ruby.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.