Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fails to cover file loaded multiple times #389

Open
Aethelflaed opened this issue May 21, 2015 · 8 comments
Open

Fails to cover file loaded multiple times #389

Aethelflaed opened this issue May 21, 2015 · 8 comments
Labels

Comments

@Aethelflaed
Copy link

I've a bot which defines each statement in a separate file to simplify testing.

To test the files, I remove all statements and then just load (not require, as it won't work) the ones I need for the specific test.

The coverage seems to work fine until I reach a test which loads all the statements.
If I had already tested e.g. ping.rb, and then this test runs, it will reload ping.rb anyway and reset all covering information about that file.

The coverage does not merge multiple loads of the same file but instead keeps only the last occurence.

I'm not sure but this may be due to ruby's Coverage and not Simplecov.

ruby 2.0.0p598 (2014-11-13 revision 48408) [x86_64-linux]
also tested with ruby 2.2.0p0 (2014-12-25 revision 49005) [x86_64-linux]

@bf4
Copy link
Collaborator

bf4 commented May 22, 2015

You need to give us more information on how to reproduce this issue, otherwise there is nothing we can do. Please read CONTRIBUTING.md file for more information about creating bug reports. Thanks!

Sample code would be great.

@bf4 bf4 closed this as completed May 22, 2015
@bf4 bf4 reopened this May 22, 2015
@Aethelflaed
Copy link
Author

File.rb:

def method
  puts 'Hello'
end
require 'simplecov'

SimpleCov.start
puts "SimpleCov v#{SimpleCov::VERSION}"

load File.expand_path('../file.rb', __FILE__)
method
load File.expand_path('../file.rb', __FILE__)

Result:

SimpleCov v0.10.0
Hello
SimpleCov failed to recognize the test framework and/or suite used. Please specify manually using SimpleCov.command_name 'Unit Tests'.
Coverage report generated for Unknown Test Framework to /tmp/test3387/coverage. 1 / 2 LOC (50.0%) covered.

If I comment the second load, I get:

SimpleCov v0.10.0
Hello
SimpleCov failed to recognize the test framework and/or suite used. Please specify manually using SimpleCov.command_name 'Unit Tests'.
Coverage report generated for Unknown Test Framework to /tmp/test3387/coverage. 2 / 2 LOC (100.0%) covered.

@bf4
Copy link
Collaborator

bf4 commented May 22, 2015

I don't quite follow where you're running the SimpleCov.start from, which file has the method defined, and which file is loading it.

maybe try this #328 (comment):

require 'json'
SimpleCov.at_exit do
  filename = File.join(SimpleCov.root, "coverage/#{$$}.json")
  File.write filename, JSON.pretty_generate(Coverage.result.sort)
end
pwd = File.expand_path('..', __FILE__)
File.write("file_that_defines_method_in_main.rb", <<-EOF)
    puts "File #{__FILE__} loaded by #{caller[0]}"
    def method_in_main
      puts "Hello, I am called from #{__FILE__} #{__LINE__} by #{caller[0]}"
    end
EOF
SimpleCov.start do
  command_name "test run"
end
load File.join(pwd, "file_that_defines_method_in_main.rb")
method_in_main
load File.join(pwd, "file_that_defines_method_in_main.rb")

@Aethelflaed
Copy link
Author

Oh sorry, I was running SimpleCov.start from the second file, but even with your test case, the output is different if I comment the second load:

[
  [
    "/tmp/test22731/file_that_defines_method_in_main.rb",
    [
      1,
      1,
      0,
      null
    ]
  ]
]
[
  [
    "/tmp/test22731/file_that_defines_method_in_main.rb",
    [
      1,
      1,
      1,
      null
    ]
  ]
]

The result is the same with ruby 2.0.0 and ruby 2.2.0

@Aethelflaed
Copy link
Author

Actually, I can get a correct result by patching Object#load and changing the command_name

def load(file, wrap = false)
  SimpleCov.result
  SimpleCov.start do
    command_name "#{command_name}1"
  end
  Kernel.load(file, wrap)
end

SimpleCov.result apparently merges the result so it's fine, but the default at_exit doesn't seem to call it, so I added:

SimpleCov.at_exit do
  SimpleCov.result.format!
end

I think the problem comes from ruby's Coverage module, not SimpleCov, but we can work around.

Ruby 2.3 introduce Coverage.peek_result which may be used to simplify the workaround

FriedSock added a commit to deliveroo/routemaster-client that referenced this issue Jan 3, 2017
These config files are singletons that contain state, which means that
they need to be reloaded between each test run. This is not currently
supported by the ruby coverage.so module which is used by SimpleCov

simplecov-ruby/simplecov#389
danielafeitosa added a commit to meedan/bridge-reader that referenced this issue May 11, 2017
On Check Api test, the classes are reloaded and this was messing up with
the code coverage. Each time the file was reloaded, it reset the coverage.
This patch merges the results.

Found on simplecov-ruby/simplecov#389
danielafeitosa added a commit to meedan/bridge-reader that referenced this issue May 11, 2017
On Check Api test, the classes are reloaded and this was messing up with
the code coverage. Each time the file was reloaded, it reset the coverage.
This patch merges the results.

Found on simplecov-ruby/simplecov#389
danielafeitosa added a commit to meedan/bridge-reader that referenced this issue May 11, 2017
On Check Api test, the classes are reloaded and this was messing up with
the code coverage. Each time the file was reloaded, it reset the coverage.
This patch merges the results.

Found on simplecov-ruby/simplecov#389
danielafeitosa added a commit to meedan/bridge-reader that referenced this issue May 11, 2017
On Check Api test, the classes are reloaded and this was messing up with
the code coverage. Each time the file was reloaded, it reset the coverage.
This patch merges the results.

Found on simplecov-ruby/simplecov#389
@PragTob
Copy link
Collaborator

PragTob commented Dec 3, 2019

Yes probably a coverage bug or rather loading a file multiples times isn't supported as per the coverage module and its intended usage.

Might be worth adding as a limitation to the README.

@PragTob PragTob added the Docs label Dec 3, 2019
jdelStrother added a commit to jdelStrother/view_component that referenced this issue May 13, 2023
simplecov is incompatible with code
reloads (simplecov-ruby/simplecov#389), so
trying to add `cache_classes = false` to our regular test runs results
in broken coverage reports.
@trisys3
Copy link

trisys3 commented Jan 8, 2024

@Aethelflaed How/where did you patch Object#load in your previous comment? I'm thinking of implementing your solution because I believe I'm having the same issue. Sorry, I know it's been awhile since you last had to think about this.

@Aethelflaed
Copy link
Author

@trisys3 I just def load directly in the file as stated in #389 (comment), this replaces the default Object#load that would get called otherwise

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

No branches or pull requests

4 participants