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)
2014-06-04 15:07:07 -04:00
[![Inline docs ](http://inch-ci.org/github/mbj/mutant.png )](http://inch-ci.org/github/mbj/mutant)
2014-06-08 08:46:59 -04:00
[![Gem Version ](https://img.shields.io/gem/v/mutant.svg )](https://rubygems.org/gems/mutant)
2012-07-26 13:38:17 -04:00
2014-08-12 17:09:59 -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
2014-08-12 17:09:59 -04:00
Mutant supports MRI and RBX 1.9, 2.0 and 2.1, 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
2014-08-12 17:09:59 -04:00
Mutant uses a pure Ruby [parser ](https://github.com/whitequark/parser ) and an [unparser ](https://github.com/mbj/unparser )
2014-04-07 14:51:59 -04:00
to do its magic.
2014-05-07 11:58:58 -04:00
Mutant does not have really good "getting started" documentation currently so please refer to presentations and blog posts below.
2014-08-17 08:41:17 -04:00
Mutation-Operators:
-------------------
Mutant supports a wide range of mutation operators. An exhaustive list can be found in the [mutant-meta ](https://github.com/mbj/mutant/tree/master/meta ).
The `mutant-meta` is arranged to the AST-Node-Types of parser. Refer to parsers [AST documentation ](https://github.com/whitequark/parser/blob/master/doc/AST_FORMAT.md ) in doubt.
There is no easy and universal way to count the number of mutation operators a tool supports.
2014-05-07 11:58:58 -04:00
Presentations
-------------
There are some presentations about mutant in the wild:
* [RailsConf 2014 ](http://railsconf.com/ ) / http://confreaks.com/videos/3333-railsconf-mutation-testing-with-mutant
* [Wrocloverb 2014 ](http://wrocloverb.com/ ) / https://www.youtube.com/watch?v=rz-lFKEioLk
2014-06-06 09:53:04 -04:00
* [eurucamp 2013 ](http://2013.eurucamp.org/ ) / FrOSCon-2013 http://slid.es/markusschirp/mutation-testing
2014-05-07 11:58:58 -04:00
* [Cologne.rb ](http://www.colognerb.de/topics/mutation-testing-mit-mutant ) / https://github.com/DonSchado/colognerb-on-mutant/blob/master/mutation_testing_slides.pdf
Blog-Posts
----------
* http://www.sitepoint.com/mutation-testing-mutant/
* http://solnic.eu/2013/01/23/mutation-testing-with-mutant.html
2013-04-27 09:54:20 -04:00
Projects using Mutant
---------------------
2012-12-21 14:59:59 -05:00
2014-08-12 17:09:59 -04:00
The following projects adopted mutant, and aim for 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 )
2013-12-01 18:18:03 -05:00
* [promise.rb ](https://github.com/lgierth/promise.rb )
2013-12-04 10:59:02 -05:00
* [full_name ](https://github.com/AGILiDEE/full_name )
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
2014-01-18 18:48:12 -05:00
```ruby
gem install mutant
```
2014-08-12 17:09:59 -04:00
If you plan to use the RSpec integration you'll have to install `mutant-rspec` also.
Please add an explicit dependency to `rspec-core` for the RSpec version you want to use.
2013-07-03 04:07:23 -04:00
2013-07-03 01:49:13 -04:00
```ruby
2014-02-01 11:10:23 -05:00
gem install mutant-rspec
2013-07-03 01:49:13 -04:00
```
2014-07-14 14:32:19 -04:00
The minitest integration is still in the works.
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
2014-08-12 17:09:59 -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.
2014-08-12 17:09:59 -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
2014-08-12 17:09:59 -04:00
NOTE: The textbook examples you find on mutation testing are intentionally not implemented. This is subject to change.
2014-04-06 16:59:16 -04:00
2013-08-04 19:15:03 -04:00
Some stats from the [axiom ](https://github.com/dkubb/axiom ) library:
2013-07-21 12:59:13 -04:00
```
2013-08-05 03:31:35 -04:00
Subjects: 424 # Amount of subjects being mutated (currently only methods)
Mutations: 6760 # Amount of mutations mutant generated (~13 mutations per method)
Kills: 6664 # Amount of successfully killed mutations
Runtime: 5123.13s # Total runtime
Killtime: 5092.63s # Time spend killing mutations
Overhead: 0.60%
Coverage: 98.58% # Coverage score
Alive: 96 # Amount of alive mutations.
2013-07-21 12:59:13 -04:00
```
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.
2014-08-12 17:09:59 -04:00
The goal is to remove this Generic mutator and have dedicated mutator for every type of node.
2013-07-21 12:59:13 -04:00
2012-07-26 13:38:17 -04:00
Examples
--------
2012-12-07 05:52:53 -05:00
```
2012-12-08 09:12:52 -05:00
cd virtus
2013-08-04 19:15:03 -04:00
# Run mutant on virtus namespace
2014-06-07 14:41:35 -04:00
mutant --include lib --require virtus --use rspec Virtus*
2013-04-17 23:31:21 -04:00
# Run mutant on specific virtus class
2014-06-07 14:41:35 -04:00
mutant --include lib --require virtus --use rspec Virtus::Attribute
2012-12-08 09:09:45 -05:00
# Run mutant on specific virtus class method
2014-06-07 14:41:35 -04:00
mutant --include lib --require virtus --use rspec Virtus::Attribute.build
2012-12-08 09:09:45 -05:00
# Run mutant on specific virtus instance method
2014-06-07 14:41:35 -04:00
mutant --include lib --require virtus --use rspec Virtus::Attribute#type
2012-12-07 05:52:53 -05:00
```
2013-01-23 07:59:03 -05:00
2014-05-06 17:11:41 -04:00
Subjects
--------
2012-12-08 09:09:45 -05:00
2013-08-04 19:15:03 -04:00
Mutant currently mutates code in instance and singleton methods. It is planned to support mutation
of constant definitions and domain specific languages, DSL probably as plugins.
2012-12-08 09:09:45 -05:00
2013-08-04 19:15:03 -04:00
Test-Selection
--------------
2012-12-08 09:09:45 -05:00
2013-08-04 19:15:03 -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 strategy for selecting tests/specs:
2012-12-08 09:09:45 -05:00
2013-08-04 19:17:14 -04:00
Mutant uses the "longest rspec example group descriptions prefix match" to select the tests to run.
2012-12-08 09:09:45 -05:00
2013-08-04 19:15:03 -04:00
Example for a subject like `Foo::Bar#baz` it will run all example groups with description prefixes in
`Foo::Bar#baz` , `Foo::Bar` and `Foo` . The order is important, so if mutant finds example groups in the
current prefix level, these example groups *must* kill the mutation.
2012-12-08 09:09:45 -05:00
2014-08-29 09:07:45 -04:00
Rails
-------
Assuming you are using rspec, you can mutation test Rails models by adding the following lines to your Gemfile:
```ruby
group :test do
gem 'mutant'
gem 'mutant-rspec'
end
```
Next, run bundle and comment out ```require 'rspec/autorun'``` from your spec_helper.rb file. Having done so you should be able to use commands like the following:
```sh
2014-08-29 09:13:46 -04:00
RAILS_ENV=test bundle exec mutant -r ./config/environment --use rspec User
2014-08-29 09:07:45 -04:00
```
2013-02-27 15:35:51 -05:00
Support
-------
2014-08-07 12:00:31 -04:00
I'm very happy to receive/answer feedback/questions and criticism.
2013-02-27 15:35:51 -05:00
Your options:
2014-08-06 12:46:02 -04:00
* [GitHub Issues ](https://github.com/mbj/mutant/issues )
* Ping me on [twitter ](https://twitter.com/_m_b_j_ )
There is also the [#mutant] channel on freenode. As my OSS time budged is very limited I cannot
2014-08-12 17:09:59 -04:00
join it often. Please prefer to use GitHub issues with a 'Question: ' prefix in title.
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.