This gem may not be very useful when you want to use Coverage oneshot mode, however, It could be good example to study how to implement by yourself.
This gem provides simple tools to use oneshot mode easier. It gives you:
- Rack middleware for logging
- Pluggable logger interface
Please notice that it records code executions under the target path(usually, project base path). If you have bundle gem path under target path, It will be ignored by default.
Add this line to your application's Gemfile:
gem 'oneshot_coverage'
And then execute:
$ bundle
Or install it yourself as:
$ gem install oneshot_coverage
OneshotCoverage.configure(
target_path: '/base/project/path',
logger: OneshotCoverage::Logger::NullLogger.new,
emit_term: nil, # emit per `emit_term` seconds. It tries to emit per request when `nil`.
cover_bundle_path: false, # record bundle gem path. Default value is false.
)
OneshotCoverage.start
As default, OneshotCoverage supports 2 logger.
- OneshotCoverage::Logger::NullLogger (default)
- OneshotCoverage::Logger::StdoutLogger
- OneshotCoverage::Logger::FileLogger
Only required interface is #post
instance method, so you could implement
by yourself easily.
class FileLogger
def initialize(log_path)
@log_path = log_path
end
# new_logs: Struct.new(:path, :md5_hash, :lines)
def post(new_logs)
current_coverage = fetch
new_logs.each do |new_log|
key = "#{new_log.path}-#{new_log.md5_hash}"
logged_lines = current_coverage.fetch(key, [])
current_coverage[key] = logged_lines | new_log.lines
end
save(current_coverage)
end
private
def fetch
JSON.load(File.read(@log_path))
rescue Errno::ENOENT
{}
end
def save(data)
File.write(@log_path, JSON.dump(data))
end
end
Please use OneshotCoverage::Middleware
. This will emit logs per each request.
If you using Rails, middleware will be inserted automatically.
If your job or batch are exit as soon as it finished(i.e. execute via rails runner),
then you don't need to do anything. OneshotCoverage.start
will set trap
to emit via at_exit
.
On the other hand, it's not, then you need to emit it manually
at proper timing(i.e. when batch finished)
You can generate pretty report using simplecov(confirmed with 0.21.2). Here is some example:
require 'simplecov'
require 'oneshot_coverage/simplecov_reporter'
OneshotCoverage::SimplecovReporter.new(
project_path: Dir.pwd, # target project path. Dir.pwd is default.
log_path: 'coverage.json', # oneshot coverage log generated by FileLogger or same scheme json file acceptable
file_filter: OneshotCoverage::SimplecovReporter::DefaultFilter # Object respond to #call with return true | false. this filter used for coverage target. file_filter.call(path) return false, then path will not be included to report. DefaultFilter is default, which exclude non-ruby file, files under /spec/, /test/, /script/, /config/
).run
This code generates html report under <project_path>/coverage/
Note that cover_bundle_path
only cover managed gem by bundler.
In the other words, the gem installed with path
option, which bundler just load it, will not be included by this.
The gem is available as open source under the terms of the MIT License.
Everyone interacting in the OneshotCoverage project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.