Skip to content

Latest commit

 

History

History
151 lines (123 loc) · 4.44 KB

mutant-minitest.md

File metadata and controls

151 lines (123 loc) · 4.44 KB

mutant-minitest

Before starting with mutant its recommended to understand the nomenclature.

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:

    # A gemfile
    gem 'mutant-minitest'
  2. Add require 'mutant/minitest/coverage' to your test environment (example to your test/test_helper.rb)

    Example:

    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:

    class YourLibrarySomeClassTest < YourTestBaseClass
      cover YourLibrary::SomeClass # tells mutant which subjects this tests should cover
      cover 'YourLibrary::SomeClass#some_method' # alternative for more fine grained control.
      # ...
  4. Run mutant against the minitest integration

    bundle exec mutant run --include lib --require 'your_library.rb' --integration minitest -- 'YourLibrary*'

Run through example

This uses 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.

git clone https://github.com/mbj/auom
cd auom
bundle install # gemfile references mutant-minitest already
bundle exec mutant run --include lib --require auom --integration minitest -- 'AUOM*'

This prints a report like:

Mutant environment:
Usage:           opensource
Matcher:         #<Mutant::Matcher::Config subjects: [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
Efficiency:      39.25%
Mutations/s:     103.67
Coverage:        100.00%

Now lets try adding some redundant (or unspecified) code:

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
Efficiency:      39.25%
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.