free_mutant/docs/mutant-minitest.md

150 lines
4.3 KiB
Markdown
Raw Permalink Normal View History

2018-11-27 08:50:44 -05:00
mutant-minitest
===============
Before starting with mutant its recommended to understand the
[nomenclature](/docs/nomenclature.md).
## Setup
To add mutant to your minitest code base you need to:
1. Add `mutant-minitest` as development dependency to your `Gemfile` or `.gemspec`
This may look like:
```ruby
# A gemfile
gem 'mutant-minitest'
```
2. Add `require 'mutant/minitest/coverage'` to your test environment (example to your `test/test_helper.rb`)
Example:
```ruby
require 'minitest/autorun'
require 'mutant/minitest/coverage'
class YourTestBaseClass < MiniTest::Test
# ...
```
3. Add `.cover` call sides to your test suite to mark them as eligible for killing mutations in subjects.
Example:
```ruby
class YourLibrarySomeClassTest < YourTestBaseClass
cover 'YourLibrary::SomeClass*' # tells mutant which subjects this tests should cover
# ...
```
4. Run mutant against the minitest integration
```sh
bundle exec mutant --include lib --require 'your_library.rb' --use minitest -- 'YourLibrary*'
```
## Run through example
This uses [mbj/auom](https://github.com/mbj/auom) a small library that
has 100% mutation coverage. Its tests execute very fast and do not have any IO
so its a good playground example to interact with.
All the setup described above is already done.
```sh
git clone https://github.com/mbj/auom
2018-11-28 05:41:59 -05:00
cd auom
2018-11-27 08:50:44 -05:00
bundle install # gemfile references mutant-minitest already
bundle exec mutant --include lib --require auom --use minitest -- 'AUOM*'
```
This prints a report like:
```sh
Mutant configuration:
Matcher: #<Mutant::Matcher::Config match_expressions: [AUOM*]>
Integration: Mutant::Integration::Minitest
Jobs: 8
Includes: ["lib"]
Requires: ["auom"]
Subjects: 23
Mutations: 1003
Results: 1003
Kills: 1003
Alive: 0
Runtime: 9.68s
Killtime: 3.80s
Overhead: 154.30%
Mutations/s: 103.67
Coverage: 100.00%
```
Now lets try adding some redundant (or unspecified) code:
```sh
patch -p1 <<'PATCH'
--- a/lib/auom/unit.rb
+++ b/lib/auom/unit.rb
@@ -170,7 +170,7 @@ module AUOM
# TODO: Move defaults coercions etc to .build method
#
def self.new(scalar, numerators = nil, denominators = nil)
- scalar = rational(scalar)
+ scalar = rational(scalar) if true
scalar, numerators = resolve([*numerators], scalar, :*)
scalar, denominators = resolve([*denominators], scalar, :/)
PATCH
```
Running mutant again prints the following:
```
AUOM::Unit.new:/home/mrh-dev/auom/lib/auom/unit.rb:172
- minitest:AUOMTest::ClassMethods::New#test_reduced_unit
- minitest:AUOMTest::ClassMethods::New#test_normalized_denominator_scalar
- minitest:AUOMTest::ClassMethods::New#test_normalized_numerator_unit
- minitest:AUOMTest::ClassMethods::New#test_incompatible_scalar
- minitest:AUOMTest::ClassMethods::New#test_integer
- minitest:AUOMTest::ClassMethods::New#test_sorted_numerator
- minitest:AUOMTest::ClassMethods::New#test_unknown_unit
- minitest:AUOMTest::ClassMethods::New#test_rational
- minitest:AUOMTest::ClassMethods::New#test_normalized_numerator_scalar
- minitest:AUOMTest::ClassMethods::New#test_sorted_denominator
- minitest:AUOMTest::ClassMethods::New#test_normalized_denominator_unit
evil:AUOM::Unit.new:/home/mrh-dev/auom/lib/auom/unit.rb:172:cd9ee
@@ -1,9 +1,7 @@
def self.new(scalar, numerators = nil, denominators = nil)
- if true
- scalar = rational(scalar)
- end
+ scalar = rational(scalar)
scalar, numerators = resolve([*numerators], scalar, :*)
scalar, denominators = resolve([*denominators], scalar, :/)
super(scalar, *[numerators, denominators].map(&:sort)).freeze
end
-----------------------
Mutant configuration:
Matcher: #<Mutant::Matcher::Config match_expressions: [AUOM*]>
Integration: Mutant::Integration::Minitest
Jobs: 8
Includes: ["lib"]
Requires: ["auom"]
Subjects: 23
Mutations: 1009
Results: 1009
Kills: 1008
Alive: 1
Runtime: 9.38s
Killtime: 3.47s
Overhead: 170.06%
Mutations/s: 107.60
Coverage: 99.90%
```
This shows mutant detected the alive mutation. Which shows the conditional we deliberately added above is redundant.
Feel free to also remove some tests. Or do other modifications to either test or code.