2012-07-26 13:38:17 -04:00
|
|
|
mutant
|
|
|
|
======
|
|
|
|
|
|
|
|
[![Build Status](https://secure.travis-ci.org/mbj/mutant.png?branch=master)](http://travis-ci.org/mbj/mutant)
|
|
|
|
[![Dependency Status](https://gemnasium.com/mbj/mutant.png)](https://gemnasium.com/mbj/mutant)
|
2013-02-07 19:40:19 -05:00
|
|
|
[![Code Climate](https://codeclimate.com/github/mbj/mutant.png)](https://codeclimate.com/github/mbj/mutant)
|
2012-07-26 13:38:17 -04:00
|
|
|
|
2013-07-21 12:59:13 -04:00
|
|
|
Mutant is a mutation testing tool for ruby.
|
2012-07-26 13:38:17 -04:00
|
|
|
|
2013-04-17 23:31:21 -04:00
|
|
|
The idea is that if code can be changed and your tests do not notice, either that code isn't being covered
|
2012-12-21 14:59:59 -05:00
|
|
|
or it does not have a speced side effect.
|
2012-12-08 09:09:45 -05:00
|
|
|
|
2013-07-16 12:03:35 -04:00
|
|
|
A more readable introduction can be found under: http://solnic.eu/2013/01/23/mutation-testing-with-mutant.html
|
|
|
|
|
2013-06-25 06:24:12 -04:00
|
|
|
Mutant supports MRI and RBX 1.9 and 2.0, while support for jruby is planned. It should also work under
|
|
|
|
any ruby engine that supports POSIX-fork(2) semantics.
|
2012-12-21 14:59:59 -05:00
|
|
|
|
2013-06-17 22:47:16 -04:00
|
|
|
Only rspec2 is supported currently. This is subject to change.
|
2013-06-15 11:41:12 -04:00
|
|
|
|
|
|
|
It is easy to write a mutation killer for other test/spec frameworks than rspec2.
|
2012-12-21 14:59:59 -05:00
|
|
|
Just create your own Mutant::Killer subclass, and make sure I get a PR!
|
2012-07-26 13:38:17 -04:00
|
|
|
|
2012-12-08 09:11:51 -05:00
|
|
|
See this [ASCII-Cast](http://ascii.io/a/1707) for mutant in action! (v0.2.1)
|
|
|
|
|
2013-04-27 09:54:20 -04:00
|
|
|
Projects using Mutant
|
|
|
|
---------------------
|
2012-12-21 14:59:59 -05:00
|
|
|
|
2013-03-09 07:49:29 -05:00
|
|
|
The following projects adopted mutant, and aim 100% mutation coverage:
|
2012-12-21 14:59:59 -05:00
|
|
|
|
2013-04-13 04:56:28 -04:00
|
|
|
* [axiom](https://github.com/dkubb/axiom)
|
|
|
|
* [axiom-types](https://github.com/dkubb/axiom-types)
|
2013-06-25 10:51:44 -04:00
|
|
|
* [rom-mapper](https://github.com/rom-rb/rom-mapper)
|
|
|
|
* [rom-session](https://github.com/rom-rb/rom-session)
|
2013-05-03 03:24:12 -04:00
|
|
|
* [event_bus](https://github.com/kevinrutherford/event_bus)
|
2012-12-21 14:59:59 -05:00
|
|
|
* [virtus](https://github.com/solnic/virtus)
|
2013-04-14 14:45:18 -04:00
|
|
|
* [quacky](https://github.com/benmoss/quacky)
|
2013-05-14 10:00:46 -04:00
|
|
|
* [substation](https://github.com/snusnu/substation)
|
2013-07-28 13:19:36 -04:00
|
|
|
* [large_binomials](https://github.com/filipvanlaenen/large_binomials)
|
2012-12-21 14:59:59 -05:00
|
|
|
* various small/minor stuff under https://github.com/mbj
|
|
|
|
|
|
|
|
Feel free to ping me to add your project to the list!
|
|
|
|
|
2012-07-26 13:38:17 -04:00
|
|
|
Installation
|
|
|
|
------------
|
|
|
|
|
2013-02-27 15:35:51 -05:00
|
|
|
Install the gem `mutant` via your preferred method.
|
2012-07-26 13:38:17 -04:00
|
|
|
|
2013-07-03 04:07:23 -04:00
|
|
|
The 0.2 series is stable but has outdated dependencies. The 0.3 series is in beta phase currently.
|
|
|
|
|
2013-07-03 01:49:13 -04:00
|
|
|
```ruby
|
2013-07-16 11:40:44 -04:00
|
|
|
gem install mutant --pre
|
2013-07-03 01:49:13 -04:00
|
|
|
```
|
|
|
|
|
2013-07-21 12:59:13 -04:00
|
|
|
Mutations
|
|
|
|
---------
|
|
|
|
|
2013-07-21 13:31:07 -04:00
|
|
|
Mutant supports a very wide range of mutation operators. Listing them all in detail would blow this document up.
|
2013-07-21 12:59:13 -04:00
|
|
|
|
2013-07-21 13:31:07 -04:00
|
|
|
It is planned to parse a list of mutation operators from the source. In the meantime please refer to the
|
2013-07-22 02:29:17 -04:00
|
|
|
[code](https://github.com/mbj/mutant/tree/master/lib/mutant/mutator/node) each subclass of `Mutant::Mutator::Node`
|
2013-07-21 12:59:13 -04:00
|
|
|
emits around 3-6 mutations.
|
|
|
|
|
2013-07-21 13:31:07 -04:00
|
|
|
Currently mutant covers the majority of ruby's complex nodes that often occur in method bodies.
|
2013-07-21 12:59:13 -04:00
|
|
|
|
|
|
|
A some stats from the [axiom](https://github.com/dkubb/axiom) library:
|
|
|
|
|
|
|
|
```
|
|
|
|
Subjects: 417 # Amount of subjects being mutated (currently only methods)
|
|
|
|
Mutations: 5442 # Amount of mutations mutant generated (~13 mutations per method)
|
|
|
|
Kills: 5385 # Amount of successfully killed mutations
|
|
|
|
Runtime: 1898.11s # Total runtime
|
|
|
|
Killtime: 1884.17s # Time spend killing mutations
|
|
|
|
Overhead: 0.73%
|
|
|
|
Coverage: 98.95% # Coverage score
|
|
|
|
Alive: 57 # Amount of alive mutations.
|
|
|
|
```
|
|
|
|
|
2013-07-21 13:32:49 -04:00
|
|
|
|
2013-07-22 02:29:17 -04:00
|
|
|
Nodes still missing a dedicated mutator are handled via the
|
2013-07-21 13:31:07 -04:00
|
|
|
[Generic](https://github.com/mbj/mutant/blob/master/lib/mutant/mutator/node/generic.rb) mutator.
|
2013-07-21 13:32:49 -04:00
|
|
|
The goal is to remove this mutator and have dedicated mutator for every type of node and removing
|
|
|
|
the Generic handler altogether.
|
2013-07-21 12:59:13 -04:00
|
|
|
|
2012-07-26 13:38:17 -04:00
|
|
|
Examples
|
|
|
|
--------
|
|
|
|
|
2012-12-21 14:59:59 -05:00
|
|
|
CLI will be simplified in the next releases, but currently stick with this:
|
|
|
|
|
2012-12-07 05:52:53 -05:00
|
|
|
```
|
2012-12-08 09:12:52 -05:00
|
|
|
cd virtus
|
2012-12-08 09:09:45 -05:00
|
|
|
# Run mutant on virtus namespace (that uses the dm-2 style spec layout)
|
2013-07-03 10:20:35 -04:00
|
|
|
mutant --rspec-dm2 '::Virtus*'
|
2013-04-17 23:31:21 -04:00
|
|
|
# Run mutant on specific virtus class
|
2013-07-03 04:20:27 -04:00
|
|
|
mutant --rspec-dm2 ::Virtus::Attribute
|
2012-12-08 09:09:45 -05:00
|
|
|
# Run mutant on specific virtus class method
|
2013-07-03 04:20:27 -04:00
|
|
|
mutant --rspec-dm2 ::Virtus::Attribute.build
|
2012-12-08 09:09:45 -05:00
|
|
|
# Run mutant on specific virtus instance method
|
2013-07-03 04:20:27 -04:00
|
|
|
mutant --rspec-dm2 ::Virtus::Attribute#name
|
2012-12-08 09:09:45 -05:00
|
|
|
```
|
|
|
|
|
|
|
|
Strategies
|
|
|
|
----------
|
|
|
|
|
2013-06-17 22:47:16 -04:00
|
|
|
Mutation testing is slow. The key to making it fast is selecting the correct set of tests to run.
|
|
|
|
Mutant currently supports the following built-in strategies for selecting tests/specs.
|
2012-12-08 09:09:45 -05:00
|
|
|
|
|
|
|
### --rspec-dm2
|
|
|
|
|
|
|
|
This strategy is the *fastest* but requires discipline in spec file naming.
|
|
|
|
|
|
|
|
The following specs are executed to kill a mutation on:
|
|
|
|
```
|
|
|
|
Public instance methods: spec/unit/#{namespace}/#{class_name}/#{method_name}_spec.rb
|
|
|
|
Public singleton methods: spec/unit/#{namespace}/#{class_name}/class_methods/#{method_name}_spec.rb
|
2013-01-08 05:07:25 -05:00
|
|
|
Private instance methods: spec/unit/#{namespace}/#{class_name}/*_spec.rb
|
2013-01-08 05:07:41 -05:00
|
|
|
Private singleton methods: spec/unit/#{namespace}/#{class_name}/class_methods/*_spec.rb
|
2012-12-07 05:52:53 -05:00
|
|
|
```
|
2013-01-23 07:59:03 -05:00
|
|
|
|
|
|
|
#### Expansions:
|
|
|
|
|
2013-06-17 22:47:16 -04:00
|
|
|
Symbolic operator-like methods are expanded, e.g. ```Foo#<<``` is expanded to:
|
2013-01-23 07:58:29 -05:00
|
|
|
```
|
2013-01-23 08:01:04 -05:00
|
|
|
spec/unit/foo/left_shift_operator_spec.rb
|
2013-01-23 07:58:29 -05:00
|
|
|
````
|
|
|
|
|
2013-06-17 22:47:16 -04:00
|
|
|
The full list of expansions can be found here:
|
2013-01-23 07:58:29 -05:00
|
|
|
|
|
|
|
https://github.com/mbj/mutant/blob/master/lib/mutant/constants.rb
|
2012-12-07 05:52:53 -05:00
|
|
|
|
2012-12-08 09:09:45 -05:00
|
|
|
### --rspec-unit
|
|
|
|
|
|
|
|
This strategy executes all specs under ``./spec/unit`` for each mutation.
|
|
|
|
|
|
|
|
### --rspec-integration
|
|
|
|
|
|
|
|
This strategy executes all specs under ``./spec/integration`` for each mutation.
|
|
|
|
|
|
|
|
### --rspec-full
|
|
|
|
|
|
|
|
This strategy executes all specs under ``./spec`` for each mutation.
|
|
|
|
|
2013-06-17 22:51:31 -04:00
|
|
|
In the future, we plan on allowing explicit selections on the specs to be run, as well as support for other test frameworks.
|
2012-12-08 09:09:45 -05:00
|
|
|
Custom project specific strategies are also on the roadmap.
|
|
|
|
|
2012-12-28 16:14:48 -05:00
|
|
|
Alternatives
|
|
|
|
------------
|
|
|
|
|
|
|
|
* [heckle](https://github.com/seattlerb/heckle)
|
|
|
|
|
2013-02-27 15:35:51 -05:00
|
|
|
Support
|
|
|
|
-------
|
|
|
|
|
|
|
|
I'm very happy to receive/answer feedback/questions and critism.
|
|
|
|
|
|
|
|
Your options:
|
|
|
|
|
2013-06-12 15:29:23 -04:00
|
|
|
* GitHub Issues https://github.com/mbj/mutant/issues
|
2013-04-17 23:31:21 -04:00
|
|
|
* Ping me on https://twitter.com/_m_b_j_
|
2013-07-29 16:06:33 -04:00
|
|
|
* #mutant channel on freenode, I hang around on CET daytimes. (nick mbj)
|
|
|
|
You'll also find others [ROM](https://github.com/rom-rb) team members here that can answer questions.
|
2013-02-27 15:35:51 -05:00
|
|
|
|
2012-07-26 13:38:17 -04:00
|
|
|
Credits
|
|
|
|
-------
|
|
|
|
|
2013-01-03 17:40:57 -05:00
|
|
|
* [Markus Schirp (mbj)](https://github.com/mbj)
|
2012-12-07 05:54:13 -05:00
|
|
|
* A [gist](https://gist.github.com/1065789) from [dkubb](https://github.com/dkubb) showing ideas.
|
2012-12-07 05:55:04 -05:00
|
|
|
* Older abandoned [mutant](https://github.com/txus/mutant). For motivating me doing this one.
|
2012-12-07 05:54:13 -05:00
|
|
|
* [heckle](https://github.com/seattlerb/heckle). For getting me into mutation testing.
|
2012-07-26 13:38:17 -04:00
|
|
|
|
|
|
|
Contributing
|
|
|
|
-------------
|
|
|
|
|
|
|
|
* Fork the project.
|
|
|
|
* Make your feature addition or bug fix.
|
|
|
|
* Add tests for it. This is important so I don't break it in a
|
|
|
|
future version unintentionally.
|
|
|
|
* Commit, do not mess with Rakefile or version
|
|
|
|
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
|
|
|
* Send me a pull request. Bonus points for topic branches.
|
|
|
|
|
|
|
|
License
|
|
|
|
-------
|
|
|
|
|
2012-12-21 14:59:59 -05:00
|
|
|
See LICENSE file.
|