free_mutant/docs/mutant-minitest.md

149 lines
4.3 KiB
Markdown
Raw 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 redundant alive conditional.
Feel free to also remove some tests. Or do other modifications to either tests or code.