Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/deep-cover/deep-cover
The best coverage tool for Ruby code
https://github.com/deep-cover/deep-cover
branch-coverage coverage ruby
Last synced: about 1 month ago
JSON representation
The best coverage tool for Ruby code
- Host: GitHub
- URL: https://github.com/deep-cover/deep-cover
- Owner: deep-cover
- License: mit
- Created: 2017-09-21T22:33:30.000Z (about 7 years ago)
- Default Branch: master
- Last Pushed: 2022-02-19T21:42:10.000Z (over 2 years ago)
- Last Synced: 2024-05-20T16:34:00.114Z (6 months ago)
- Topics: branch-coverage, coverage, ruby
- Language: Ruby
- Homepage:
- Size: 1.65 MB
- Stars: 206
- Watchers: 8
- Forks: 16
- Open Issues: 7
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- Funding: .github/FUNDING.yml
- License: LICENSE.txt
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
[![Build Status](https://travis-ci.org/deep-cover/deep-cover.svg?branch=master)](https://travis-ci.org/deep-cover/deep-cover)
[![Backers on Open Collective](https://opencollective.com/deep-cover/backers/badge.svg)](#backers)
[![Sponsors on Open Collective](https://opencollective.com/deep-cover/sponsors/badge.svg)](#sponsors)# Maintenance status
Deep Cover has not been updated for Ruby 3.x new syntax features, in particular:
- pattern match
- `{x:}` notationUnfortunately, both co-authors are occupied contributing to other projects and can offer only minimal maintenance: complete PRs will be accepted and we welcome applications if you are interested in becoming a maintainer for this project.
# DeepCover
Deep Cover aims to be the best coverage tool for Ruby code:
- more accurate line coverage
- branch coverage
- can be used as a drop-in replacement for the built-in Coverage library.It reports a more accurate picture of your code usage. In particular a line is considered covered if and only if it is entirely executed:
```
def foo(something: false)
bar if something # => This is considered covered by builtin coverage,
# even though `bar` might not even exist
end# somewhere in a test:
foo
```Optionally, branch coverage will detect if some branches are never taken. In the following example, `test_foo` only provides values for `x` that respond to `:to_s`, thus the implicit `else` is never tested (i.e. a value of `x` that does not respond to `:to_s`)
```
def foo(x)
x = x.to_s if x.respond_to? :to_s
# ...
enddef test_foo
assert_equal something, foo(42)
assert_equal something_else, foo(:hello)
end
```## Examples
These examples are direct outputs from our HTML reporter:
- [Rails' `activesupport`](https://deep-cover.github.io/rails-cover/activesupport/)
- [Rails' `activerecord`](https://deep-cover.github.io/rails-cover/activerecord/)## DeepCover vs builtin coverage
| Feature | MRI | DeepCover |
| ---------------- | :-------: | :--------------: |
| Line coverage | partial | ✓ |
| Node coverage | no | ✓ |
| Branch coverage | partial | ✓ |
| Method coverage | ✓ | ~ |
| Slowdown | < 1% | ~20% |
| Platform support | Ruby 2.5+ | Ruby 2.1+, JRuby |**Line coverage**: MRI doesn't cover some lines (e.g. `when some_value`).
**Node coverage**: MRI provides no way to tell which parts of any line is evaluated (e.g. `0.times { never_run }`). DeepCover covers everything.
**Method coverage**: MRI considers every method defined, including methods defined on objects or via `define_method`, `class_eval`, etc. For Istanbul output, DeepCover has a different approach and covers all `def` and all blocks.
| **Branch coverage** | MRI | DeepCover |
| ----------------------- | :-: | :-------: |
| `if` / `unless` / `?:` | ✓ | ✓ |
| `case` / `when` | ✓ | ✓ |
| `❘❘` / `&&` | no | ✓ |
| `foo&.bar` | ✓ | ✓ |
| `{❘foo = 42, bar: 43❘}` | no | ✓ |
| `while` / `until` | ✓ | ! |_Note on loops (!)_: DeepCover doesn't consider loops to be branches, but it's
easy to support it if needed.## Installation
Do the appropriate of the installation of the gem, then follow the steps that correspond to your situation.
# if the project is a gem, add this to your .gemspec and then run `bundle install`
spec.add_development_dependency 'deep-cover', '~> 0.7'# otherwise if using a Gemfile, add this to it and then run `bundle install`
gem 'deep-cover', '~> 0.7', group: :test# otherwise just run:
gem install deep-cover### Trying `deep-cover` quickly
An easy way to try `deep-cover`, without any configuration needed:
deep-cover clone command to run test
# ex:
deep-cover clone rake testCheck the produced `coverage/index.html`.
Note, this is a bit slower and may cause issues in your tests if your use relative paths that lead outside of the directory (Such as a dependency that is in a parent directory).
### Regular setup
1. Require `deep-cover`
You must call `require 'deep-cover'` **before** the code you want to cover is loaded.
Typically, you want to insert that line **at the very top** of `test/test_helper.rb` or `spec/spec_helper.rb` . If `deep-cover` is required after your code, then it won't be able to detect the coverage.
Note that if some of your tests run by launching another process, that process will have to `require 'deep-cover'` also. For example you could insert `require 'deep-cover' if ENV['DEEP_COVER']` at the beginning of `lib/my_awesome_gem.rb`, before all the `require_relative 'my_awesome_gem/fabulous_core_part_1'`, ...
Note that the environment variable `DEEP_COVER` is set by `deep-cover exec` or `DeepCover.start`.2. Create a config file (optional)
You may want to create a config file `.deep_cover.rb` at the root of your project, where you can set the config as you wish.
```
# File .deep_cover.rb
DeepCover.configure do
ignore_uncovered :default_argument
# ...
end
```3. Launch it
Even after `DeepCover` is `require`d and configured, only a very minimal amount of code is actually loaded and coverage is _not started_.
The easiest way to actually start it is to use `deep-cover exec`
For example:
```
$ deep-cover exec rspec
# ...all the output of rspec
# ...coverage report
```### Already using SimpleCov / builtin Coverage
To make it easier to transition for projects already using the builtin `Coverage` library (such as those using `SimpleCov`), `deep-cover` can inject itself into those tools so that, while you still only have line-by-line coverage information, it becomes stricter, only marking a line as executed if _everything_ on it has been executed.
You must call `require 'deep_cover/builtin_takeover'` **before** you require the coverage tool that you normally use.
For example, the `test/test_helper.rb` file for `SimpleCov` users will look like
```
require 'deep_cover/builtin_takeover'
require 'simplecov'
SimpleCov.start
# rest of `test_helper.rb`
```Once this is done, simply generate the coverage as you normally would. In order to get detailed information about why a line is not covered, you will need to the regular `deep-cover` mode.
### Online coverage tools such as Code Climate, Coveralls, Codecov
At the moment, those tools do not support deep-cover. It is however possible to use the takeover system to, at least, make them stricter. Follow the explanation in the above section for injecting into `SimpleCov`.
## Usage
### Configuration
`configure` is used to specify how specific `DeepCover` should be and which files it should analyse. The following code reflects the default settings:
```
DeepCover.configure do
ignore_uncovered :raise, :default_argument
detect_uncovered :trivial_if
paths %w[app lib]
exclude_paths ['fixtures', /^lib\/ignore/]
end
```The file `.deep_cover.rb` is loaded automatically when requiring `deep-cover` and is the best place to put the configuration.
#### Custom filters
`deep-cover` comes with a few filters that make it possible to ignore certain uncovered codes.
It is easy to add you own filters.
For example, if one wants to ignore uncovered calls to `raise` but the code uses `our_custom_raise` instead, the following with work:
```
DeepCover.configure do
ignore_uncovered do
type == :send &&
receiver == nil &&
message == :our_custom_raise
end
end
```## Development
After checking out the repo, run `bundle` then `rake dev:install` to install dependencies. Then, run `rake` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
For detailed analysis:
`deep-cover -d -e "if(:try_me); puts 'cool'; end"`
To run one of the specs in `spec`:
`bin/cov boolean`
More details in the [contributing guide](https://github.com/deep-cover/deep-cover/blob/master/CONTRIBUTING.md).
## Contributing
Please ask questions on StackOverflow.com. Maintainers monitor the tag `deep-cover.rb`.
Bug reports and pull requests are welcome on GitHub at https://github.com/deep-cover/deep-cover. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
## Contributors
This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].
## License
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
## Code of Conduct
Everyone interacting in the DeepCover project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/deep-cover/deep-cover/blob/master/CODE_OF_CONDUCT.md).