rspec / rspec-core

RSpec runner and formatters
http://rspec.info
MIT License
1.23k stars 764 forks source link

rspec exits with 0, but fails to display tail message #2484

Closed krainboltgreene closed 6 years ago

krainboltgreene commented 6 years ago

Versions:

ruby "2.4.2p198 (2017-09-14 revision 59899) [x86_64-darwin17]"
gem 'rails', '~> 4.2'
gem 'rspec-rails', '~> 3.6'
gem 'spring-commands-rspec', '~> 1.0'
gem 'rubocop-rspec', '~> 1.10.0', require: false # upgrades need to be tested with rubocop version
gem 'rspec_junit_formatter', '~> 0.3'
gem 'rspec-retry', '~> 0.5'
gem 'rspec-collection_matchers', '~> 1.1'

Output:

bin/rspec spec/requests/api/v1/users_request_spec.rb
Running via Spring preloader in process 47193
Run options: include {:focus=>true}

All examples were filtered out; ignoring {:focus=>true}

/v1/users
  /two_factor_auth
    with a user that has no phone
      supplying an email

====> React On Rails: Checking app/assets/webpack for outdated/missing bundles

        returns success
        returns the id of the account
        fires an email with the otp
      supplying a good code and good phone number
        returns success
        returns the id of the account
        uses the user's unverified phone number
      supplying a good phone number with attached code with ISO human style
        returns success
        returns the id of the account
        uses the user's unverified phone number
      supplying a good phone number with attached code with ISO machine style
        returns success
        returns the id of the account
        uses the user's unverified phone number
      supplying a good phone number with attached code with ISO machine style no plus
        returns success
        returns the id of the account
        uses the user's unverified phone number
      supplying a good phone number human without attached code
        returns success
        returns the id of the account
        uses the user's unverified phone number
      supplying a bad code and good phone number
        returns 422
        returns a success of false
        contains the bad number error message
      supplying a bad code and bad phone number
        returns 422
        returns a success of false
        contains the bad number error message
      supplying a really bad phone number
        returns 422
        returns a success of false
        contains the bad number error message
      supplying a bad phone number
        returns 422
        returns a success of false
        contains the bad number error message
      without a phone number
        returns unprocessable_entity
        returns a success of false
        contains the no phone number error message
    when the user already has a (unverified) number
      supplying an email
        returns success
        returns the id of the account
        returns the obfuscated phone of the account
        fires an email with the otp
      supplying a good code and good phone number
...@... at . on ± i2fa 𝑓 echo $?
0
krainboltgreene commented 6 years ago

I can definitely supply more information if needed.

krainboltgreene commented 6 years ago

If I specify certain contexts, via line specification, I don't get this issue. Currently I'm "bisect"ing my way though this, apparently there's a specific test that's doing this.

krainboltgreene commented 6 years ago

I've removed two comments because they were false alarms.

krainboltgreene commented 6 years ago

Okay, I've tracked it down to this:

At the top level of this test I have this:

    before do
      post "/api/v1/users/two_factor_auth", JSON.dump(body), default_headers.merge(headers)
    end

If I binding.pry inside that, before the post, and I manually call it:

    29:       end
    30:     end
    31:
    32:     before do
    33:       binding.pry
 => 34:       post "/api/v1/users/two_factor_auth", JSON.dump(body), default_headers.merge(headers)
    35:     end
    36:
    37:     context "with a user that has no phone" do
    38:       let(:user) { create(:user, phone: nil) }
    39:

(test) #<RSpec::ExampleGroups::V1Users::TwoFactorAuth::WhenTheUserAlreadyHasAUnverifiedNumber::SupplyingABadPhoneNumber:0x00007fe893b9b378>:0> post "/api/v1/users/two_factor_auth", JSON.dump(body), default_headers.merge(headers)

And the pry session exits with code 0.

krainboltgreene commented 6 years ago

There's zero loglines generated from that expression in my rails test.log, so that leaves me to believe the problem lies inside rpsec's scope of things.

myronmarston commented 6 years ago

I noticed you're running rspec via spring. Can you try without spring? Historically, spring has been the source of many, many odd behaviors folks see when using it to run RSpec.

Also, can you grep your codebase (and your gems, if possible) to see if any of them might be calling exit anywhere?

krainboltgreene commented 6 years ago

Historically, spring has been the source of many, many odd behaviors folks see when using it to run RSpec.

I should have known. I'm no fan, anyways this is what spring was hiding:

     SystemStackError:
       stack level too deep
     # ./spec/requests/api/v1/users_request_spec.rb:385:in `block (5 levels) in <top (required)>'
     # ./spec/requests/api/v1/users_request_spec.rb:264:in `block (4 levels) in <top (required)>'
     # ./spec/requests/api/v1/users_request_spec.rb:385:in `block (5 levels) in <top (required)>'
     # ./spec/requests/api/v1/users_request_spec.rb:264:in `block (4 levels) in <top (required)>'
     # ./spec/requests/api/v1/users_request_spec.rb:385:in `block (5 levels) in <top (required)>'
     # ./spec/requests/api/v1/users_request_spec.rb:264:in `block (4 levels) in <top (required)>'
     # ./spec/requests/api/v1/users_request_spec.rb:385:in `block (5 levels) in <top (required)>'
     # ./spec/requests/api/v1/users_request_spec.rb:264:in `block (4 levels) in <top (required)>'

I can handl it from here.

ctrlaltdylan commented 5 years ago

9 times out of 10 this kind of error is because I have a recursive application code level problem, not necessarily in the spec suite. Just a heads up for future lookers.