SlideShare a Scribd company logo
Mutation Testing

@DonSchado
cologne.rb | 16.10.2013
disclaimer
This presentation contains:
-

memes
a definition
lots of screenshots
overdrawn code examples
a short quiz time
surviving mutants
no ponies
def mutation_testing  
  <<-eos
   
is used to evaluate the quality of existing software tests
    modifying the program's source code
based on well-defined mutation operators
  
    each 'mutated' version is called a mutant
  
    a test which detects the mutation (fail) will kill the mutant
  
    mutants without failing tests are alive  
  eos 
end
def mutation_testing  
  <<-eos
   
is used to evaluate the quality of existing software tests
    modifying the program's source code
based on well-defined mutation operators
  
    each 'mutated' version is called a mutant
  
    a test which detects the mutation (fail) will kill the mutant
  
    mutants without failing tests are ALIVE  
  eos 
end
gem 'mutant', '~> 0.3.0.rc3'
Mutation testing with the mutant gem
Projects using
Mutant
The following projects
adopted mutant, and aim
100% mutation coverage:

•
•
•
•
•
•
•
•
•

axiom
axiom-types
rom-mapper
rom-session
event_bus
virtus
quacky
substation
large_binomials
Mutation testing with the mutant gem
Mutation testing with the mutant gem
source "https://rubygems.org"
   
gem 'simplecov', "~> 0.8.0.pre2" 
gem "rake", "~> 10.1.0"
gem "rspec", "~> 2.14.0"
gem "mutant", "~> 0.3.0.rc3"
gem "rspec-pride", "~> 2.2.0", :require => false
gem "activesupport", "~> 4.0.0", :require => false
require 'spec_helper'
 
describe 'FancyAlgorithm' do
 
  let(:random_list) { %w[2 1 3 5 6 4 9 8 7] }
  let(:sorted_list) { %w[1 2 3 4 5 6 7 8 9] }
  context ':sort' do
    subject { FancyAlgorithm.new(:sort) }
    it { expect(subject.perform(random_list)).to eql(sorted_list) }
  end
  context ':unsort' do
    subject { FancyAlgorithm.new(:unsort) }
    it { expect(subject.perform(random_list)).to_not eql(sorted_list) }
  end
end
class FancyAlgorithm
  attr_accessor :strategy
  def initialize(strategy)
    @strategy = strategy.to_s
  end
  def perform(list)
    self.send("#{strategy}_algorithm!", list)
  end
  private
    def sort_algorithm!(list)
      return list if list.size <= 1
      0.upto(list.size - 1) do |i|
        (list.size - 1).downto(i + 1) do |j|
          if list[j] < list[j - 1]
            list[j], list[j - 1] = list[j - 1], list[j]
          end 
        end
      end
      list 
    end
 
    def unsort_algorithm!(list)
      return list.shuffle unless list.empty?
    end 
end
class FancyAlgorithm
  attr_accessor :strategy
  def initialize(strategy)
    @strategy = strategy.to_s
  end
  def perform(list)
    self.send("#{strategy}_algorithm!", list)
  end
  private

This is obviously
more advanced
than Array#sort.

    def sort_algorithm!(list)
      return list if list.size <= 1
      0.upto(list.size - 1) do |i|
        (list.size - 1).downto(i + 1) do |j|
          if list[j] < list[j - 1]
            list[j], list[j - 1] = list[j - 1], list[j]
          end 
        end
      end
      list 
    end
 
    def unsort_algorithm!(list)
      return list.shuffle unless list.empty?
    end 
end
http://bigocheatsheet.com/
http://www.igvita.com/2009/03/26/ruby-algorithms-sorting-trie-heaps/
class FancyAlgorithm
  attr_accessor :strategy
  def initialize(strategy)
    @strategy = strategy.to_s
  end
  def perform(list)
    self.send("#{strategy}_algorithm!", list)
  end
  private

Quiztime:

Which sorting algorithm
is this?

    def sort_algorithm!(list)
      return list if list.size <= 1
      0.upto(list.size - 1) do |i|
        (list.size - 1).downto(i + 1) do |j|
          if list[j] < list[j - 1]
            list[j], list[j - 1] = list[j - 1], list[j]
          end 
        end
      end
      list 
    end
 
    def unsort_algorithm!(list)
      return list.shuffle unless list.empty?
    end 
end
http://bigocheatsheet.com/
http://www.igvita.com/2009/03/26/ruby-algorithms-sorting-trie-heaps/
class FancyAlgorithm
  attr_accessor :strategy
  def initialize(strategy)
    @strategy = strategy.to_s
  end
  def perform(list)
    self.send("#{strategy}_algorithm!", list)
  end
  private

Quiztime:

What‘s the average
Big-O complexity of this
sorting algorithm?

    def sort_algorithm!(list)
      return list if list.size <= 1
      0.upto(list.size - 1) do |i|
        (list.size - 1).downto(i + 1) do |j|
          if list[j] < list[j - 1]
            list[j], list[j - 1] = list[j - 1], list[j]
          end 
        end
      end
      list 
    end
 
    def unsort_algorithm!(list)
      return list.shuffle unless list.empty?
    end 
end
http://bigocheatsheet.com/
http://www.igvita.com/2009/03/26/ruby-algorithms-sorting-trie-heaps/
class FancyAlgorithm
  attr_accessor :strategy
  def initialize(strategy)
    @strategy = strategy.to_s
  end
  def perform(list)
    self.send("#{strategy}_algorithm!", list)
  end
  private

Quiztime:

What‘s the sorting
algorithm behind Ruby‘s
Array#sort?

    def sort_algorithm!(list)
      return list if list.size <= 1
      0.upto(list.size - 1) do |i|
        (list.size - 1).downto(i + 1) do |j|
          if list[j] < list[j - 1]
            list[j], list[j - 1] = list[j - 1], list[j]
          end 
        end
      end
      list 
    end
 
    def unsort_algorithm!(list)
      return list.shuffle unless list.empty?
    end 
end
http://bigocheatsheet.com/
http://www.igvita.com/2009/03/26/ruby-algorithms-sorting-trie-heaps/
Mutation testing with the mutant gem
$ mutant --help
usage: mutant STRATEGY [options] MATCHERS ...
Strategies:
--rspec
--rspec-level LEVEL
--ignore-subject MATCHER
--zombie
-I, --include DIRECTORY
-r, --require NAME
Options:

--version
--code FILTER
--fail-fast
-d, --debug
-h, --help

kills mutations with rspec
set rspec expansion level
ignores subjects that matches MATCHER
Run mutant zombified
Add DIRECTORY to $LOAD_PATH
Require file with NAME
Print mutants version
Adds a code filter
Fail fast
Enable debugging output
Show this message
$ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm#initialize
$ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm#initialize
Mutant configuration:
Matcher:
#<Mutant::Matcher::Method::Instance cache=#<Mutant::Cache>
scope=FancyAlgorithm method=#<UnboundMethod: FancyAlgorithm#initialize>>
Subject Filter: Mutant::Predicate::CONTRADICTION
Strategy:
#<Mutant::Strategy::Rspec level=0>
FancyAlgorithm#initialize:/../lib/fancy_algorithm.rb:4
......F...
(09/10) 90% - 0.79s
FancyAlgorithm#initialize:/../lib/fancy_algorithm.rb:4
evil:FancyAlgorithm#initialize:/../lib/fancy_algorithm.rb:4:b34d0
@@ -1,4 +1,4 @@
def initialize(strategy)
- @strategy = strategy.to_s
+ @strategy = strategy
end
(09/10) 90% - 0.79s
Subjects: 1
Mutations: 10
Kills:
9
Runtime:
0.86s
Killtime: 0.79s
Overhead: 8.84%
Coverage: 90.00%
Alive:
1
$ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm#initialize
Mutant configuration:
Matcher:
#<Mutant::Matcher::Method::Instance cache=#<Mutant::Cache>
scope=FancyAlgorithm method=#<UnboundMethod: FancyAlgorithm#initialize>>
Subject Filter: Mutant::Predicate::CONTRADICTION
Strategy:
#<Mutant::Strategy::Rspec level=0>
FancyAlgorithm#initialize:/../lib/fancy_algorithm.rb:4
......F...
(09/10) 90% - 0.79s
FancyAlgorithm#initialize:/../lib/fancy_algorithm.rb:4
evil:FancyAlgorithm#initialize:/../lib/fancy_algorithm.rb:4:b34d0
@@ -1,4 +1,4 @@
def initialize(strategy)
- @strategy = strategy.to_s
def initialize(strategy)
+ @strategy = strategy
    @strategy = strategy.to_s
end
  end
(09/10) 90% - 0.79s
Subjects: 1
def perform(list)
Mutations: 10
    self.send("#{strategy}_algorithm!", list)
Kills:
9
  end
Runtime:
0.86s
Killtime: 0.79s
Overhead: 8.84%
Coverage: 90.00%
Alive:
1

implicit!
$ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm
$ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm
Mutant configuration:
...
FancyAlgorithm#initialize:/../lib/fancy_algorithm.rb:4
......F...
(09/10) 90% - 0.80s
FancyAlgorithm#perform:/../lib/fancy_algorithm.rb:8
.......F..........
(17/18) 94% - 1.44s
FancyAlgorithm#sort_algorithm!:/../lib/fancy_algorithm.rb:14
...........FFF.F..FFFFF.........................F........
(47/57) 82% - 4.87s
FancyAlgorithm#unsort_algorithm!:/../lib/fancy_algorithm.rb:27
....FF.FFFFFFF.FFF
(06/18) 33% - 1.52s
Subjects:
Mutations:
Kills:
Runtime:
Killtime:
Overhead:
Coverage:
Alive:

4
103
79
9.46s
8.62s
8.84%
76.70%
24
$ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm
Mutant configuration:
...
FancyAlgorithm#initialize:/../lib/fancy_algorithm.rb:4
......F...
(09/10) 90% - 0.80s
FancyAlgorithm#perform:/../lib/fancy_algorithm.rb:8
.......F..........
(17/18) 94% - 1.44s
FancyAlgorithm#sort_algorithm!:/../lib/fancy_algorithm.rb:14
...........FFF.F..FFFFF.........................F........
(47/57) 82% - 4.87s
FancyAlgorithm#unsort_algorithm!:/../lib/fancy_algorithm.rb:27
....FF.FFFFFFF.FFF
(06/18) 33% - 1.52s
Subjects:
Mutations:
Kills:
Runtime:
Killtime:
Overhead:
Coverage:
Alive:

4
103
79
9.46s
8.62s
8.84%
76.70%
24
$ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm
Mutant configuration:
... self.send("#{strategy}_algorithm!", list)
def perform(list)
+ send("#{strategy}_algorithm!", list)
    self.send("#{strategy}_algorithm!", list)
  end

Subjects:
Mutations:
Kills:
Runtime:
Killtime:
Overhead:
Coverage:
Alive:

4
103
79
9.46s
8.62s
8.84%
76.70%
24
$ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm
Mutant configuration:
...

Subjects:
Mutations:
Kills:
Runtime:
Killtime:
Overhead:
Coverage:
Alive:

4
103
79
9.46s
8.62s
8.84%
76.70%
24

def sort_algorithm!(list)
      return list if list.size <= 1
      0.upto(list.size - 1) do |i|
        (list.size - 1).downto(i + 1) do |j|
          if list[j] < list[j - 1]
            list[j], list[j - 1] = list[j - 1], list[j]
          end 
        end
      end
      list 
    end
$ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm
Mutant configuration:
... if list.size <= 1
+

if list.size <= -1

Subjects:
Mutations:
Kills:
Runtime:
Killtime:
Overhead:
Coverage:
Alive:

4
103
79
9.46s
8.62s
8.84%
76.70%
24

def sort_algorithm!(list)
      return list if list.size <= 1
      0.upto(list.size - 1) do |i|
        (list.size - 1).downto(i + 1) do |j|
          if list[j] < list[j - 1]
            list[j], list[j - 1] = list[j - 1], list[j]
          end 
        end
      end
      list 
    end
$ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm
Mutant configuration:
... if list.size <= 1
+

if list.size <= -1

+

if list.size <= 1
if list.size <= 2

Subjects:
Mutations:
Kills:
Runtime:
Killtime:
Overhead:
Coverage:
Alive:

4
103
79
9.46s
8.62s
8.84%
76.70%
24

def sort_algorithm!(list)
      return list if list.size <= 1
      0.upto(list.size - 1) do |i|
        (list.size - 1).downto(i + 1) do |j|
          if list[j] < list[j - 1]
            list[j], list[j - 1] = list[j - 1], list[j]
          end 
        end
      end
      list 
    end
$ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm
Mutant configuration:
... if list.size <= 1
+

if list.size <= -1

+

if list.size <= 1
if list.size <= 2

+

if list.size <= 1
if list.size <= nil

Subjects:
Mutations:
Kills:
Runtime:
Killtime:
Overhead:
Coverage:
Alive:

4
103
79
9.46s
8.62s
8.84%
76.70%
24

def sort_algorithm!(list)
      return list if list.size <= 1
      0.upto(list.size - 1) do |i|
        (list.size - 1).downto(i + 1) do |j|
          if list[j] < list[j - 1]
            list[j], list[j - 1] = list[j - 1], list[j]
          end 
        end
      end
      list 
    end
$ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm
Mutant configuration:
... if list.size <= 1
+

if list.size <= -1

+

if list.size <= 1
if list.size <= 2

+

if list.size <= 1
if list.size <= nil

+

if list.size <= 1
if list.size <= false

Subjects:
Mutations:
Kills:
Runtime:
Killtime:
Overhead:
Coverage:
Alive:

4
103
79
9.46s
8.62s
8.84%
76.70%
24

def sort_algorithm!(list)
      return list if list.size <= 1
      0.upto(list.size - 1) do |i|
        (list.size - 1).downto(i + 1) do |j|
          if list[j] < list[j - 1]
            list[j], list[j - 1] = list[j - 1], list[j]
          end 
        end
      end
      list 
    end
$ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm
Mutant configuration:
... return(list)
+

return(nil)

Subjects:
Mutations:
Kills:
Runtime:
Killtime:
Overhead:
Coverage:
Alive:

4
103
79
9.46s
8.62s
8.84%
76.70%
24

def sort_algorithm!(list)
      return list if list.size <= 1
      0.upto(list.size - 1) do |i|
        (list.size - 1).downto(i + 1) do |j|
          if list[j] < list[j - 1]
            list[j], list[j - 1] = list[j - 1], list[j]
          end 
        end
      end
      list 
    end
$ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm
Mutant configuration:
... return(list)
+

return(nil)

+

if list.size <= 1
return(list)
end
nil

Subjects:
Mutations:
Kills:
Runtime:
Killtime:
Overhead:
Coverage:
Alive:

4
103
79
9.46s
8.62s
8.84%
76.70%
24

def sort_algorithm!(list)
      return list if list.size <= 1
      0.upto(list.size - 1) do |i|
        (list.size - 1).downto(i + 1) do |j|
          if list[j] < list[j - 1]
            list[j], list[j - 1] = list[j - 1], list[j]
          end 
        end
      end
      list 
    end
$ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm
Mutant configuration:
... return(list)
+

return(nil)

+

if list.size <= 1
return(list)
end
nil

-

if list.size <= 1
return(list)
end

Subjects:
Mutations:
Kills:
Runtime:
Killtime:
Overhead:
Coverage:
Alive:

4
103
79
9.46s
8.62s
8.84%
76.70%
24

def sort_algorithm!(list)
      return list if list.size <= 1
      0.upto(list.size - 1) do |i|
        (list.size - 1).downto(i + 1) do |j|
          if list[j] < list[j - 1]
            list[j], list[j - 1] = list[j - 1], list[j]
          end 
        end
      end
      list 
    end
$ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm
Mutant configuration:
...
def unsort_algorithm!(list)
      return list.shuffle unless list.empty?
    end 

Subjects:
Mutations:
Kills:
Runtime:
Killtime:
Overhead:
Coverage:
Alive:

4
103
79
9.46s
8.62s
8.84%
76.70%
24
$ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm
Mutant configuration:
... unless list.empty?
+

unless nil

Subjects:
Mutations:
Kills:
Runtime:
Killtime:
Overhead:
Coverage:
Alive:

4
103
79
9.46s
8.62s
8.84%
76.70%
24

def unsort_algorithm!(list)
      return list.shuffle unless list.empty?
    end 
$ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm
Mutant configuration:
... unless list.empty?
+

unless nil

+

unless list.empty?
unless !list.emtpy?

Subjects:
Mutations:
Kills:
Runtime:
Killtime:
Overhead:
Coverage:
Alive:

4
103
79
9.46s
8.62s
8.84%
76.70%
24

def unsort_algorithm!(list)
      return list.shuffle unless list.empty?
    end 
$ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm
Mutant configuration:
... unless list.empty?
+

unless nil

+

unless list.empty?
unless !list.emtpy?

+

unless list.empty?
unless false

Subjects:
Mutations:
Kills:
Runtime:
Killtime:
Overhead:
Coverage:
Alive:

4
103
79
9.46s
8.62s
8.84%
76.70%
24

def unsort_algorithm!(list)
      return list.shuffle unless list.empty?
    end 
$ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm
Mutant configuration:
... unless list.empty?
+

unless nil

+

unless list.empty?
unless !list.emtpy?

+

unless list.empty?
unless false

+

unless list.empty?
if list.empty?

Subjects:
Mutations:
Kills:
Runtime:
Killtime:
Overhead:
Coverage:
Alive:

4
103
79
9.46s
8.62s
8.84%
76.70%
24

def unsort_algorithm!(list)
      return list.shuffle unless list.empty?
    end 
$ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm
Mutant configuration:
... return(list.shuffle)
+

return(list)

Subjects:
Mutations:
Kills:
Runtime:
Killtime:
Overhead:
Coverage:
Alive:

4
103
79
9.46s
8.62s
8.84%
76.70%
24

def unsort_algorithm!(list)
      return list.shuffle unless list.empty?
    end 
$ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm
Mutant configuration:
... return(list.shuffle)
+

return(list)

+

return(list.shuffle)
list.shuffle

Subjects:
Mutations:
Kills:
Runtime:
Killtime:
Overhead:
Coverage:
Alive:

4
103
79
9.46s
8.62s
8.84%
76.70%
24

def unsort_algorithm!(list)
      return list.shuffle unless list.empty?
    end 
$ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm
Mutant configuration:
... return(list.shuffle)
+

return(list)

+

return(list.shuffle)
list.shuffle

+

return(list.shuffle)
return(nil)

Subjects:
Mutations:
Kills:
Runtime:
Killtime:
Overhead:
Coverage:
Alive:

4
103
79
9.46s
8.62s
8.84%
76.70%
24

def unsort_algorithm!(list)
      return list.shuffle unless list.empty?
    end 
$ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm
Mutant configuration:
... return(list.shuffle)
+

return(list)

+

return(list.shuffle)
list.shuffle

+

return(list.shuffle)
return(nil)

+

unless list.empty?
return(list.shuffle)
end
nil

Subjects:
Mutations:
Kills:
Runtime:
Killtime:
Overhead:
Coverage:
Alive:

4
103
79
9.46s
8.62s
8.84%
76.70%
24

def unsort_algorithm!(list)
      return list.shuffle unless list.empty?
    end 
-

Try it by yourself
clone the repo
play around
write specs to kill the mutants
run mutant in other projects
create issues
help improve the documentation
mutate all the things
example project (including this slides):
https://github.com/DonSchado/colognerb-on-mutant
in addition:
https://github.com/DonSchado/bob-the-mutant
obviously:
https://github.com/mbj/mutant
for reference:
http://slid.es/markusschirp/mutation-testing/
http://solnic.eu/2013/01/23/mutation-testing-with-mutant.html
rails?
https://github.com/mockdeep/mutant-rails

More Related Content

What's hot (20)

PPTX
python beginner talk slide
jonycse
 
PDF
Protocols with Associated Types, and How They Got That Way
Alexis Gallagher
 
PDF
Google Guava for cleaner code
Mite Mitreski
 
PDF
Swift 2
Jens Ravens
 
PDF
Google Guava
Scott Leberknight
 
PDF
Google guava
t fnico
 
PDF
The core libraries you always wanted - Google Guava
Mite Mitreski
 
PDF
Go Java, Go!
Andres Almiray
 
PPTX
Go Java, Go!
Andres Almiray
 
PDF
Scripting3
Nao Dara
 
PDF
Google guava - almost everything you need to know
Tomasz Dziurko
 
PDF
Google guava overview
Steve Min
 
PDF
Functional programming in java
John Ferguson Smart Limited
 
PDF
Advanced Python, Part 1
Zaar Hai
 
PPT
Functional Programming In Java
Andrei Solntsev
 
PDF
Introduction to Swift programming language.
Icalia Labs
 
PDF
Swift Programming Language
Giuseppe Arici
 
PDF
Zend Certification Preparation Tutorial
Lorna Mitchell
 
PDF
Java 8: the good, the bad and the ugly (Oracle Code Brussels 2017)
Brian Vermeer
 
PDF
Java 8: the good, the bad and the ugly (JBCNConf 2017)
Brian Vermeer
 
python beginner talk slide
jonycse
 
Protocols with Associated Types, and How They Got That Way
Alexis Gallagher
 
Google Guava for cleaner code
Mite Mitreski
 
Swift 2
Jens Ravens
 
Google Guava
Scott Leberknight
 
Google guava
t fnico
 
The core libraries you always wanted - Google Guava
Mite Mitreski
 
Go Java, Go!
Andres Almiray
 
Go Java, Go!
Andres Almiray
 
Scripting3
Nao Dara
 
Google guava - almost everything you need to know
Tomasz Dziurko
 
Google guava overview
Steve Min
 
Functional programming in java
John Ferguson Smart Limited
 
Advanced Python, Part 1
Zaar Hai
 
Functional Programming In Java
Andrei Solntsev
 
Introduction to Swift programming language.
Icalia Labs
 
Swift Programming Language
Giuseppe Arici
 
Zend Certification Preparation Tutorial
Lorna Mitchell
 
Java 8: the good, the bad and the ugly (Oracle Code Brussels 2017)
Brian Vermeer
 
Java 8: the good, the bad and the ugly (JBCNConf 2017)
Brian Vermeer
 

Similar to Mutation testing with the mutant gem (20)

ODP
Quick sort
Nicholas Case
 
PDF
Funtional Ruby - Mikhail Bortnyk
Ruby Meditation
 
PDF
Functional Ruby
Amoniac OÜ
 
PDF
How fast is it really? Benchmarking in Practice (Ruby Version)
Tobias Pfeiffer
 
PPTX
Intro to ruby
Heather Campbell
 
PPTX
Day 1 - Intro to Ruby
Barry Jones
 
KEY
An introduction to Ruby
Wes Oldenbeuving
 
PPTX
Mutation Testing
10Pines
 
PDF
Mutation Testing
ESUG
 
PDF
Machine learning
Ashok Masti
 
PDF
Approval Testing & Mutation Testing - Cork Software Crafters - June 2019
Paulo Clavijo
 
PDF
How to Write Better Code with Mutation Testing
John Backus
 
PDF
Happy Coding with Ruby on Rails
Ochirkhuyag Lkhagva
 
PDF
Building Large Web Applications That Are Easy to Maintain
MarsBased
 
PDF
Can You Trust Your Tests? (Agile Tour 2015 Kaunas)
Vaidas Pilkauskas
 
PDF
Better Developers
Mike Donikian
 
ODP
Intro to Sorting + Insertion Sort
Nicholas Case
 
PDF
Average sort
Waqas Tariq
 
ODP
Merge sort
Nicholas Case
 
Quick sort
Nicholas Case
 
Funtional Ruby - Mikhail Bortnyk
Ruby Meditation
 
Functional Ruby
Amoniac OÜ
 
How fast is it really? Benchmarking in Practice (Ruby Version)
Tobias Pfeiffer
 
Intro to ruby
Heather Campbell
 
Day 1 - Intro to Ruby
Barry Jones
 
An introduction to Ruby
Wes Oldenbeuving
 
Mutation Testing
10Pines
 
Mutation Testing
ESUG
 
Machine learning
Ashok Masti
 
Approval Testing & Mutation Testing - Cork Software Crafters - June 2019
Paulo Clavijo
 
How to Write Better Code with Mutation Testing
John Backus
 
Happy Coding with Ruby on Rails
Ochirkhuyag Lkhagva
 
Building Large Web Applications That Are Easy to Maintain
MarsBased
 
Can You Trust Your Tests? (Agile Tour 2015 Kaunas)
Vaidas Pilkauskas
 
Better Developers
Mike Donikian
 
Intro to Sorting + Insertion Sort
Nicholas Case
 
Average sort
Waqas Tariq
 
Merge sort
Nicholas Case
 
Ad

More from DonSchado (7)

PDF
Ruby MVC from scratch with Rack
DonSchado
 
PDF
The return of an old enemy
DonSchado
 
PDF
Rails Girls: Programming, Web Applications and Ruby on Rails
DonSchado
 
PDF
Decorator & Presenter Design Pattern
DonSchado
 
PDF
Ruby's require, autoload and load methods
DonSchado
 
PDF
A taste of Computer Science
DonSchado
 
PDF
Rails - How does it work?
DonSchado
 
Ruby MVC from scratch with Rack
DonSchado
 
The return of an old enemy
DonSchado
 
Rails Girls: Programming, Web Applications and Ruby on Rails
DonSchado
 
Decorator & Presenter Design Pattern
DonSchado
 
Ruby's require, autoload and load methods
DonSchado
 
A taste of Computer Science
DonSchado
 
Rails - How does it work?
DonSchado
 
Ad

Recently uploaded (20)

PDF
CIFDAQ Market Insights for July 7th 2025
CIFDAQ
 
PDF
"AI Transformation: Directions and Challenges", Pavlo Shaternik
Fwdays
 
PDF
Timothy Rottach - Ramp up on AI Use Cases, from Vector Search to AI Agents wi...
AWS Chicago
 
PDF
"Beyond English: Navigating the Challenges of Building a Ukrainian-language R...
Fwdays
 
PDF
[Newgen] NewgenONE Marvin Brochure 1.pdf
darshakparmar
 
PDF
Building Real-Time Digital Twins with IBM Maximo & ArcGIS Indoors
Safe Software
 
PDF
Jak MŚP w Europie Środkowo-Wschodniej odnajdują się w świecie AI
dominikamizerska1
 
PPTX
OpenID AuthZEN - Analyst Briefing July 2025
David Brossard
 
PDF
Presentation - Vibe Coding The Future of Tech
yanuarsinggih1
 
PDF
NewMind AI - Journal 100 Insights After The 100th Issue
NewMind AI
 
PDF
LLMs.txt: Easily Control How AI Crawls Your Site
Keploy
 
PDF
CIFDAQ Token Spotlight for 9th July 2025
CIFDAQ
 
PDF
Exolore The Essential AI Tools in 2025.pdf
Srinivasan M
 
PDF
New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
PDF
Achieving Consistent and Reliable AI Code Generation - Medusa AI
medusaaico
 
PDF
HubSpot Main Hub: A Unified Growth Platform
Jaswinder Singh
 
PPTX
Q2 FY26 Tableau User Group Leader Quarterly Call
lward7
 
PPTX
COMPARISON OF RASTER ANALYSIS TOOLS OF QGIS AND ARCGIS
Sharanya Sarkar
 
PDF
Fl Studio 24.2.2 Build 4597 Crack for Windows Free Download 2025
faizk77g
 
PDF
Newgen 2022-Forrester Newgen TEI_13 05 2022-The-Total-Economic-Impact-Newgen-...
darshakparmar
 
CIFDAQ Market Insights for July 7th 2025
CIFDAQ
 
"AI Transformation: Directions and Challenges", Pavlo Shaternik
Fwdays
 
Timothy Rottach - Ramp up on AI Use Cases, from Vector Search to AI Agents wi...
AWS Chicago
 
"Beyond English: Navigating the Challenges of Building a Ukrainian-language R...
Fwdays
 
[Newgen] NewgenONE Marvin Brochure 1.pdf
darshakparmar
 
Building Real-Time Digital Twins with IBM Maximo & ArcGIS Indoors
Safe Software
 
Jak MŚP w Europie Środkowo-Wschodniej odnajdują się w świecie AI
dominikamizerska1
 
OpenID AuthZEN - Analyst Briefing July 2025
David Brossard
 
Presentation - Vibe Coding The Future of Tech
yanuarsinggih1
 
NewMind AI - Journal 100 Insights After The 100th Issue
NewMind AI
 
LLMs.txt: Easily Control How AI Crawls Your Site
Keploy
 
CIFDAQ Token Spotlight for 9th July 2025
CIFDAQ
 
Exolore The Essential AI Tools in 2025.pdf
Srinivasan M
 
New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
Achieving Consistent and Reliable AI Code Generation - Medusa AI
medusaaico
 
HubSpot Main Hub: A Unified Growth Platform
Jaswinder Singh
 
Q2 FY26 Tableau User Group Leader Quarterly Call
lward7
 
COMPARISON OF RASTER ANALYSIS TOOLS OF QGIS AND ARCGIS
Sharanya Sarkar
 
Fl Studio 24.2.2 Build 4597 Crack for Windows Free Download 2025
faizk77g
 
Newgen 2022-Forrester Newgen TEI_13 05 2022-The-Total-Economic-Impact-Newgen-...
darshakparmar
 

Mutation testing with the mutant gem

  • 2. disclaimer This presentation contains: - memes a definition lots of screenshots overdrawn code examples a short quiz time surviving mutants no ponies
  • 3. def mutation_testing     <<-eos     is used to evaluate the quality of existing software tests     modifying the program's source code based on well-defined mutation operators        each 'mutated' version is called a mutant        a test which detects the mutation (fail) will kill the mutant        mutants without failing tests are alive     eos  end
  • 4. def mutation_testing     <<-eos     is used to evaluate the quality of existing software tests     modifying the program's source code based on well-defined mutation operators        each 'mutated' version is called a mutant        a test which detects the mutation (fail) will kill the mutant        mutants without failing tests are ALIVE     eos  end
  • 5. gem 'mutant', '~> 0.3.0.rc3'
  • 7. Projects using Mutant The following projects adopted mutant, and aim 100% mutation coverage: • • • • • • • • • axiom axiom-types rom-mapper rom-session event_bus virtus quacky substation large_binomials
  • 10. source "https://rubygems.org"     gem 'simplecov', "~> 0.8.0.pre2"  gem "rake", "~> 10.1.0" gem "rspec", "~> 2.14.0" gem "mutant", "~> 0.3.0.rc3" gem "rspec-pride", "~> 2.2.0", :require => false gem "activesupport", "~> 4.0.0", :require => false
  • 11. require 'spec_helper'   describe 'FancyAlgorithm' do     let(:random_list) { %w[2 1 3 5 6 4 9 8 7] }   let(:sorted_list) { %w[1 2 3 4 5 6 7 8 9] }   context ':sort' do     subject { FancyAlgorithm.new(:sort) }     it { expect(subject.perform(random_list)).to eql(sorted_list) }   end   context ':unsort' do     subject { FancyAlgorithm.new(:unsort) }     it { expect(subject.perform(random_list)).to_not eql(sorted_list) }   end end
  • 12. class FancyAlgorithm   attr_accessor :strategy   def initialize(strategy)     @strategy = strategy.to_s   end   def perform(list)     self.send("#{strategy}_algorithm!", list)   end   private     def sort_algorithm!(list)       return list if list.size <= 1       0.upto(list.size - 1) do |i|         (list.size - 1).downto(i + 1) do |j|           if list[j] < list[j - 1]             list[j], list[j - 1] = list[j - 1], list[j]           end          end       end       list      end       def unsort_algorithm!(list)       return list.shuffle unless list.empty?     end  end
  • 13. class FancyAlgorithm   attr_accessor :strategy   def initialize(strategy)     @strategy = strategy.to_s   end   def perform(list)     self.send("#{strategy}_algorithm!", list)   end   private This is obviously more advanced than Array#sort.     def sort_algorithm!(list)       return list if list.size <= 1       0.upto(list.size - 1) do |i|         (list.size - 1).downto(i + 1) do |j|           if list[j] < list[j - 1]             list[j], list[j - 1] = list[j - 1], list[j]           end          end       end       list      end       def unsort_algorithm!(list)       return list.shuffle unless list.empty?     end  end http://bigocheatsheet.com/ http://www.igvita.com/2009/03/26/ruby-algorithms-sorting-trie-heaps/
  • 14. class FancyAlgorithm   attr_accessor :strategy   def initialize(strategy)     @strategy = strategy.to_s   end   def perform(list)     self.send("#{strategy}_algorithm!", list)   end   private Quiztime: Which sorting algorithm is this?     def sort_algorithm!(list)       return list if list.size <= 1       0.upto(list.size - 1) do |i|         (list.size - 1).downto(i + 1) do |j|           if list[j] < list[j - 1]             list[j], list[j - 1] = list[j - 1], list[j]           end          end       end       list      end       def unsort_algorithm!(list)       return list.shuffle unless list.empty?     end  end http://bigocheatsheet.com/ http://www.igvita.com/2009/03/26/ruby-algorithms-sorting-trie-heaps/
  • 15. class FancyAlgorithm   attr_accessor :strategy   def initialize(strategy)     @strategy = strategy.to_s   end   def perform(list)     self.send("#{strategy}_algorithm!", list)   end   private Quiztime: What‘s the average Big-O complexity of this sorting algorithm?     def sort_algorithm!(list)       return list if list.size <= 1       0.upto(list.size - 1) do |i|         (list.size - 1).downto(i + 1) do |j|           if list[j] < list[j - 1]             list[j], list[j - 1] = list[j - 1], list[j]           end          end       end       list      end       def unsort_algorithm!(list)       return list.shuffle unless list.empty?     end  end http://bigocheatsheet.com/ http://www.igvita.com/2009/03/26/ruby-algorithms-sorting-trie-heaps/
  • 16. class FancyAlgorithm   attr_accessor :strategy   def initialize(strategy)     @strategy = strategy.to_s   end   def perform(list)     self.send("#{strategy}_algorithm!", list)   end   private Quiztime: What‘s the sorting algorithm behind Ruby‘s Array#sort?     def sort_algorithm!(list)       return list if list.size <= 1       0.upto(list.size - 1) do |i|         (list.size - 1).downto(i + 1) do |j|           if list[j] < list[j - 1]             list[j], list[j - 1] = list[j - 1], list[j]           end          end       end       list      end       def unsort_algorithm!(list)       return list.shuffle unless list.empty?     end  end http://bigocheatsheet.com/ http://www.igvita.com/2009/03/26/ruby-algorithms-sorting-trie-heaps/
  • 18. $ mutant --help usage: mutant STRATEGY [options] MATCHERS ... Strategies: --rspec --rspec-level LEVEL --ignore-subject MATCHER --zombie -I, --include DIRECTORY -r, --require NAME Options: --version --code FILTER --fail-fast -d, --debug -h, --help kills mutations with rspec set rspec expansion level ignores subjects that matches MATCHER Run mutant zombified Add DIRECTORY to $LOAD_PATH Require file with NAME Print mutants version Adds a code filter Fail fast Enable debugging output Show this message
  • 19. $ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm#initialize
  • 20. $ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm#initialize Mutant configuration: Matcher: #<Mutant::Matcher::Method::Instance cache=#<Mutant::Cache> scope=FancyAlgorithm method=#<UnboundMethod: FancyAlgorithm#initialize>> Subject Filter: Mutant::Predicate::CONTRADICTION Strategy: #<Mutant::Strategy::Rspec level=0> FancyAlgorithm#initialize:/../lib/fancy_algorithm.rb:4 ......F... (09/10) 90% - 0.79s FancyAlgorithm#initialize:/../lib/fancy_algorithm.rb:4 evil:FancyAlgorithm#initialize:/../lib/fancy_algorithm.rb:4:b34d0 @@ -1,4 +1,4 @@ def initialize(strategy) - @strategy = strategy.to_s + @strategy = strategy end (09/10) 90% - 0.79s Subjects: 1 Mutations: 10 Kills: 9 Runtime: 0.86s Killtime: 0.79s Overhead: 8.84% Coverage: 90.00% Alive: 1
  • 21. $ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm#initialize Mutant configuration: Matcher: #<Mutant::Matcher::Method::Instance cache=#<Mutant::Cache> scope=FancyAlgorithm method=#<UnboundMethod: FancyAlgorithm#initialize>> Subject Filter: Mutant::Predicate::CONTRADICTION Strategy: #<Mutant::Strategy::Rspec level=0> FancyAlgorithm#initialize:/../lib/fancy_algorithm.rb:4 ......F... (09/10) 90% - 0.79s FancyAlgorithm#initialize:/../lib/fancy_algorithm.rb:4 evil:FancyAlgorithm#initialize:/../lib/fancy_algorithm.rb:4:b34d0 @@ -1,4 +1,4 @@ def initialize(strategy) - @strategy = strategy.to_s def initialize(strategy) + @strategy = strategy     @strategy = strategy.to_s end   end (09/10) 90% - 0.79s Subjects: 1 def perform(list) Mutations: 10     self.send("#{strategy}_algorithm!", list) Kills: 9   end Runtime: 0.86s Killtime: 0.79s Overhead: 8.84% Coverage: 90.00% Alive: 1 implicit!
  • 22. $ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm
  • 23. $ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm Mutant configuration: ... FancyAlgorithm#initialize:/../lib/fancy_algorithm.rb:4 ......F... (09/10) 90% - 0.80s FancyAlgorithm#perform:/../lib/fancy_algorithm.rb:8 .......F.......... (17/18) 94% - 1.44s FancyAlgorithm#sort_algorithm!:/../lib/fancy_algorithm.rb:14 ...........FFF.F..FFFFF.........................F........ (47/57) 82% - 4.87s FancyAlgorithm#unsort_algorithm!:/../lib/fancy_algorithm.rb:27 ....FF.FFFFFFF.FFF (06/18) 33% - 1.52s Subjects: Mutations: Kills: Runtime: Killtime: Overhead: Coverage: Alive: 4 103 79 9.46s 8.62s 8.84% 76.70% 24
  • 24. $ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm Mutant configuration: ... FancyAlgorithm#initialize:/../lib/fancy_algorithm.rb:4 ......F... (09/10) 90% - 0.80s FancyAlgorithm#perform:/../lib/fancy_algorithm.rb:8 .......F.......... (17/18) 94% - 1.44s FancyAlgorithm#sort_algorithm!:/../lib/fancy_algorithm.rb:14 ...........FFF.F..FFFFF.........................F........ (47/57) 82% - 4.87s FancyAlgorithm#unsort_algorithm!:/../lib/fancy_algorithm.rb:27 ....FF.FFFFFFF.FFF (06/18) 33% - 1.52s Subjects: Mutations: Kills: Runtime: Killtime: Overhead: Coverage: Alive: 4 103 79 9.46s 8.62s 8.84% 76.70% 24
  • 25. $ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm Mutant configuration: ... self.send("#{strategy}_algorithm!", list) def perform(list) + send("#{strategy}_algorithm!", list)     self.send("#{strategy}_algorithm!", list)   end Subjects: Mutations: Kills: Runtime: Killtime: Overhead: Coverage: Alive: 4 103 79 9.46s 8.62s 8.84% 76.70% 24
  • 26. $ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm Mutant configuration: ... Subjects: Mutations: Kills: Runtime: Killtime: Overhead: Coverage: Alive: 4 103 79 9.46s 8.62s 8.84% 76.70% 24 def sort_algorithm!(list)       return list if list.size <= 1       0.upto(list.size - 1) do |i|         (list.size - 1).downto(i + 1) do |j|           if list[j] < list[j - 1]             list[j], list[j - 1] = list[j - 1], list[j]           end          end       end       list      end
  • 27. $ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm Mutant configuration: ... if list.size <= 1 + if list.size <= -1 Subjects: Mutations: Kills: Runtime: Killtime: Overhead: Coverage: Alive: 4 103 79 9.46s 8.62s 8.84% 76.70% 24 def sort_algorithm!(list)       return list if list.size <= 1       0.upto(list.size - 1) do |i|         (list.size - 1).downto(i + 1) do |j|           if list[j] < list[j - 1]             list[j], list[j - 1] = list[j - 1], list[j]           end          end       end       list      end
  • 28. $ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm Mutant configuration: ... if list.size <= 1 + if list.size <= -1 + if list.size <= 1 if list.size <= 2 Subjects: Mutations: Kills: Runtime: Killtime: Overhead: Coverage: Alive: 4 103 79 9.46s 8.62s 8.84% 76.70% 24 def sort_algorithm!(list)       return list if list.size <= 1       0.upto(list.size - 1) do |i|         (list.size - 1).downto(i + 1) do |j|           if list[j] < list[j - 1]             list[j], list[j - 1] = list[j - 1], list[j]           end          end       end       list      end
  • 29. $ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm Mutant configuration: ... if list.size <= 1 + if list.size <= -1 + if list.size <= 1 if list.size <= 2 + if list.size <= 1 if list.size <= nil Subjects: Mutations: Kills: Runtime: Killtime: Overhead: Coverage: Alive: 4 103 79 9.46s 8.62s 8.84% 76.70% 24 def sort_algorithm!(list)       return list if list.size <= 1       0.upto(list.size - 1) do |i|         (list.size - 1).downto(i + 1) do |j|           if list[j] < list[j - 1]             list[j], list[j - 1] = list[j - 1], list[j]           end          end       end       list      end
  • 30. $ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm Mutant configuration: ... if list.size <= 1 + if list.size <= -1 + if list.size <= 1 if list.size <= 2 + if list.size <= 1 if list.size <= nil + if list.size <= 1 if list.size <= false Subjects: Mutations: Kills: Runtime: Killtime: Overhead: Coverage: Alive: 4 103 79 9.46s 8.62s 8.84% 76.70% 24 def sort_algorithm!(list)       return list if list.size <= 1       0.upto(list.size - 1) do |i|         (list.size - 1).downto(i + 1) do |j|           if list[j] < list[j - 1]             list[j], list[j - 1] = list[j - 1], list[j]           end          end       end       list      end
  • 31. $ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm Mutant configuration: ... return(list) + return(nil) Subjects: Mutations: Kills: Runtime: Killtime: Overhead: Coverage: Alive: 4 103 79 9.46s 8.62s 8.84% 76.70% 24 def sort_algorithm!(list)       return list if list.size <= 1       0.upto(list.size - 1) do |i|         (list.size - 1).downto(i + 1) do |j|           if list[j] < list[j - 1]             list[j], list[j - 1] = list[j - 1], list[j]           end          end       end       list      end
  • 32. $ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm Mutant configuration: ... return(list) + return(nil) + if list.size <= 1 return(list) end nil Subjects: Mutations: Kills: Runtime: Killtime: Overhead: Coverage: Alive: 4 103 79 9.46s 8.62s 8.84% 76.70% 24 def sort_algorithm!(list)       return list if list.size <= 1       0.upto(list.size - 1) do |i|         (list.size - 1).downto(i + 1) do |j|           if list[j] < list[j - 1]             list[j], list[j - 1] = list[j - 1], list[j]           end          end       end       list      end
  • 33. $ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm Mutant configuration: ... return(list) + return(nil) + if list.size <= 1 return(list) end nil - if list.size <= 1 return(list) end Subjects: Mutations: Kills: Runtime: Killtime: Overhead: Coverage: Alive: 4 103 79 9.46s 8.62s 8.84% 76.70% 24 def sort_algorithm!(list)       return list if list.size <= 1       0.upto(list.size - 1) do |i|         (list.size - 1).downto(i + 1) do |j|           if list[j] < list[j - 1]             list[j], list[j - 1] = list[j - 1], list[j]           end          end       end       list      end
  • 34. $ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm Mutant configuration: ... def unsort_algorithm!(list)       return list.shuffle unless list.empty?     end  Subjects: Mutations: Kills: Runtime: Killtime: Overhead: Coverage: Alive: 4 103 79 9.46s 8.62s 8.84% 76.70% 24
  • 35. $ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm Mutant configuration: ... unless list.empty? + unless nil Subjects: Mutations: Kills: Runtime: Killtime: Overhead: Coverage: Alive: 4 103 79 9.46s 8.62s 8.84% 76.70% 24 def unsort_algorithm!(list)       return list.shuffle unless list.empty?     end 
  • 36. $ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm Mutant configuration: ... unless list.empty? + unless nil + unless list.empty? unless !list.emtpy? Subjects: Mutations: Kills: Runtime: Killtime: Overhead: Coverage: Alive: 4 103 79 9.46s 8.62s 8.84% 76.70% 24 def unsort_algorithm!(list)       return list.shuffle unless list.empty?     end 
  • 37. $ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm Mutant configuration: ... unless list.empty? + unless nil + unless list.empty? unless !list.emtpy? + unless list.empty? unless false Subjects: Mutations: Kills: Runtime: Killtime: Overhead: Coverage: Alive: 4 103 79 9.46s 8.62s 8.84% 76.70% 24 def unsort_algorithm!(list)       return list.shuffle unless list.empty?     end 
  • 38. $ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm Mutant configuration: ... unless list.empty? + unless nil + unless list.empty? unless !list.emtpy? + unless list.empty? unless false + unless list.empty? if list.empty? Subjects: Mutations: Kills: Runtime: Killtime: Overhead: Coverage: Alive: 4 103 79 9.46s 8.62s 8.84% 76.70% 24 def unsort_algorithm!(list)       return list.shuffle unless list.empty?     end 
  • 39. $ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm Mutant configuration: ... return(list.shuffle) + return(list) Subjects: Mutations: Kills: Runtime: Killtime: Overhead: Coverage: Alive: 4 103 79 9.46s 8.62s 8.84% 76.70% 24 def unsort_algorithm!(list)       return list.shuffle unless list.empty?     end 
  • 40. $ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm Mutant configuration: ... return(list.shuffle) + return(list) + return(list.shuffle) list.shuffle Subjects: Mutations: Kills: Runtime: Killtime: Overhead: Coverage: Alive: 4 103 79 9.46s 8.62s 8.84% 76.70% 24 def unsort_algorithm!(list)       return list.shuffle unless list.empty?     end 
  • 41. $ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm Mutant configuration: ... return(list.shuffle) + return(list) + return(list.shuffle) list.shuffle + return(list.shuffle) return(nil) Subjects: Mutations: Kills: Runtime: Killtime: Overhead: Coverage: Alive: 4 103 79 9.46s 8.62s 8.84% 76.70% 24 def unsort_algorithm!(list)       return list.shuffle unless list.empty?     end 
  • 42. $ mutant --rspec -I lib -r fancy_algorithm FancyAlgorithm Mutant configuration: ... return(list.shuffle) + return(list) + return(list.shuffle) list.shuffle + return(list.shuffle) return(nil) + unless list.empty? return(list.shuffle) end nil Subjects: Mutations: Kills: Runtime: Killtime: Overhead: Coverage: Alive: 4 103 79 9.46s 8.62s 8.84% 76.70% 24 def unsort_algorithm!(list)       return list.shuffle unless list.empty?     end 
  • 43. - Try it by yourself clone the repo play around write specs to kill the mutants run mutant in other projects create issues help improve the documentation mutate all the things
  • 44. example project (including this slides): https://github.com/DonSchado/colognerb-on-mutant in addition: https://github.com/DonSchado/bob-the-mutant obviously: https://github.com/mbj/mutant for reference: http://slid.es/markusschirp/mutation-testing/ http://solnic.eu/2013/01/23/mutation-testing-with-mutant.html rails? https://github.com/mockdeep/mutant-rails