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'
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
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/
$ 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

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

What's hot (20)

python beginner talk slide
python beginner talk slidepython beginner talk slide
python beginner talk slide
 
Protocols with Associated Types, and How They Got That Way
Protocols with Associated Types, and How They Got That WayProtocols with Associated Types, and How They Got That Way
Protocols with Associated Types, and How They Got That Way
 
Google Guava for cleaner code
Google Guava for cleaner codeGoogle Guava for cleaner code
Google Guava for cleaner code
 
Swift 2
Swift 2Swift 2
Swift 2
 
Google Guava
Google GuavaGoogle Guava
Google Guava
 
Google guava
Google guavaGoogle guava
Google guava
 
The core libraries you always wanted - Google Guava
The core libraries you always wanted - Google GuavaThe core libraries you always wanted - Google Guava
The core libraries you always wanted - Google Guava
 
Go Java, Go!
Go Java, Go!Go Java, Go!
Go Java, Go!
 
Go Java, Go!
Go Java, Go!Go Java, Go!
Go Java, Go!
 
Scripting3
Scripting3Scripting3
Scripting3
 
Google guava - almost everything you need to know
Google guava - almost everything you need to knowGoogle guava - almost everything you need to know
Google guava - almost everything you need to know
 
Google guava overview
Google guava overviewGoogle guava overview
Google guava overview
 
Functional programming in java
Functional programming in javaFunctional programming in java
Functional programming in java
 
Advanced Python, Part 1
Advanced Python, Part 1Advanced Python, Part 1
Advanced Python, Part 1
 
Functional Programming In Java
Functional Programming In JavaFunctional Programming In Java
Functional Programming In Java
 
Introduction to Swift programming language.
Introduction to Swift programming language.Introduction to Swift programming language.
Introduction to Swift programming language.
 
Swift Programming Language
Swift Programming LanguageSwift Programming Language
Swift Programming Language
 
Zend Certification Preparation Tutorial
Zend Certification Preparation TutorialZend Certification Preparation Tutorial
Zend Certification Preparation Tutorial
 
Java 8: the good, the bad and the ugly (Oracle Code Brussels 2017)
Java 8: the good, the bad and the ugly (Oracle Code Brussels 2017)Java 8: the good, the bad and the ugly (Oracle Code Brussels 2017)
Java 8: the good, the bad and the ugly (Oracle Code Brussels 2017)
 
Java 8: the good, the bad and the ugly (JBCNConf 2017)
Java 8: the good, the bad and the ugly (JBCNConf 2017)Java 8: the good, the bad and the ugly (JBCNConf 2017)
Java 8: the good, the bad and the ugly (JBCNConf 2017)
 

Similar to Mutation testing with the mutant gem

Ruby tricks2
Ruby tricks2Ruby tricks2
Ruby tricks2
Michał Łomnicki
 
Groovy unleashed
Groovy unleashed Groovy unleashed
Groovy unleashed
Isuru Samaraweera
 
Introductionto fp with groovy
Introductionto fp with groovyIntroductionto fp with groovy
Introductionto fp with groovy
Isuru Samaraweera
 
Python basics
Python basicsPython basics
Python basics
Hoang Nguyen
 
Python basics
Python basicsPython basics
Python basics
Young Alista
 
Python basics
Python basicsPython basics
Python basics
Fraboni Ec
 
Python basics
Python basicsPython basics
Python basics
Harry Potter
 
Python basics
Python basicsPython basics
Python basics
James Wong
 
Python basics
Python basicsPython basics
Python basics
Tony Nguyen
 
Python basics
Python basicsPython basics
Python basics
Luis Goldster
 
Core java
Core javaCore java
Core java
kasaragaddaslide
 
Lazy Java
Lazy JavaLazy Java
Lazy Java
J On The Beach
 
Lazy java
Lazy javaLazy java
Lazy java
Mario Fusco
 
Lazy Java
Lazy JavaLazy Java
Lazy Java
Nicola Pedot
 
Mario Fusco - Lazy Java - Codemotion Milan 2018
Mario Fusco - Lazy Java - Codemotion Milan 2018Mario Fusco - Lazy Java - Codemotion Milan 2018
Mario Fusco - Lazy Java - Codemotion Milan 2018
Codemotion
 
Python_UNIT-I.pptx
Python_UNIT-I.pptxPython_UNIT-I.pptx
Python_UNIT-I.pptx
mustafatahertotanawa1
 
Refactor like a boss
Refactor like a bossRefactor like a boss
Refactor like a boss
gsterndale
 
PYTHON -Chapter 2 - Functions, Exception, Modules and Files -MAULIK BOR...
PYTHON -Chapter 2 - Functions,   Exception, Modules  and    Files -MAULIK BOR...PYTHON -Chapter 2 - Functions,   Exception, Modules  and    Files -MAULIK BOR...
PYTHON -Chapter 2 - Functions, Exception, Modules and Files -MAULIK BOR...
Maulik Borsaniya
 
Desarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutosDesarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutos
Edgar Suarez
 
Refactoring Ruby Code
Refactoring Ruby CodeRefactoring Ruby Code
Refactoring Ruby Code
Caike Souza
 

Similar to Mutation testing with the mutant gem (20)

Ruby tricks2
Ruby tricks2Ruby tricks2
Ruby tricks2
 
Groovy unleashed
Groovy unleashed Groovy unleashed
Groovy unleashed
 
Introductionto fp with groovy
Introductionto fp with groovyIntroductionto fp with groovy
Introductionto fp with groovy
 
Python basics
Python basicsPython basics
Python basics
 
Python basics
Python basicsPython basics
Python basics
 
Python basics
Python basicsPython basics
Python basics
 
Python basics
Python basicsPython basics
Python basics
 
Python basics
Python basicsPython basics
Python basics
 
Python basics
Python basicsPython basics
Python basics
 
Python basics
Python basicsPython basics
Python basics
 
Core java
Core javaCore java
Core java
 
Lazy Java
Lazy JavaLazy Java
Lazy Java
 
Lazy java
Lazy javaLazy java
Lazy java
 
Lazy Java
Lazy JavaLazy Java
Lazy Java
 
Mario Fusco - Lazy Java - Codemotion Milan 2018
Mario Fusco - Lazy Java - Codemotion Milan 2018Mario Fusco - Lazy Java - Codemotion Milan 2018
Mario Fusco - Lazy Java - Codemotion Milan 2018
 
Python_UNIT-I.pptx
Python_UNIT-I.pptxPython_UNIT-I.pptx
Python_UNIT-I.pptx
 
Refactor like a boss
Refactor like a bossRefactor like a boss
Refactor like a boss
 
PYTHON -Chapter 2 - Functions, Exception, Modules and Files -MAULIK BOR...
PYTHON -Chapter 2 - Functions,   Exception, Modules  and    Files -MAULIK BOR...PYTHON -Chapter 2 - Functions,   Exception, Modules  and    Files -MAULIK BOR...
PYTHON -Chapter 2 - Functions, Exception, Modules and Files -MAULIK BOR...
 
Desarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutosDesarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutos
 
Refactoring Ruby Code
Refactoring Ruby CodeRefactoring Ruby Code
Refactoring Ruby Code
 

More from DonSchado

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

More from DonSchado (7)

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

Recently uploaded

Dandelion Hashtable: beyond billion requests per second on a commodity server
Dandelion Hashtable: beyond billion requests per second on a commodity serverDandelion Hashtable: beyond billion requests per second on a commodity server
Dandelion Hashtable: beyond billion requests per second on a commodity server
Antonios Katsarakis
 
Biomedical Knowledge Graphs for Data Scientists and Bioinformaticians
Biomedical Knowledge Graphs for Data Scientists and BioinformaticiansBiomedical Knowledge Graphs for Data Scientists and Bioinformaticians
Biomedical Knowledge Graphs for Data Scientists and Bioinformaticians
Neo4j
 
[OReilly Superstream] Occupy the Space: A grassroots guide to engineering (an...
[OReilly Superstream] Occupy the Space: A grassroots guide to engineering (an...[OReilly Superstream] Occupy the Space: A grassroots guide to engineering (an...
[OReilly Superstream] Occupy the Space: A grassroots guide to engineering (an...
Jason Yip
 
"Choosing proper type of scaling", Olena Syrota
"Choosing proper type of scaling", Olena Syrota"Choosing proper type of scaling", Olena Syrota
"Choosing proper type of scaling", Olena Syrota
Fwdays
 
Taking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdfTaking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdf
ssuserfac0301
 
Northern Engraving | Nameplate Manufacturing Process - 2024
Northern Engraving | Nameplate Manufacturing Process - 2024Northern Engraving | Nameplate Manufacturing Process - 2024
Northern Engraving | Nameplate Manufacturing Process - 2024
Northern Engraving
 
Essentials of Automations: Exploring Attributes & Automation Parameters
Essentials of Automations: Exploring Attributes & Automation ParametersEssentials of Automations: Exploring Attributes & Automation Parameters
Essentials of Automations: Exploring Attributes & Automation Parameters
Safe Software
 
"Frontline Battles with DDoS: Best practices and Lessons Learned", Igor Ivaniuk
"Frontline Battles with DDoS: Best practices and Lessons Learned",  Igor Ivaniuk"Frontline Battles with DDoS: Best practices and Lessons Learned",  Igor Ivaniuk
"Frontline Battles with DDoS: Best practices and Lessons Learned", Igor Ivaniuk
Fwdays
 
Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024
Jason Packer
 
AppSec PNW: Android and iOS Application Security with MobSF
AppSec PNW: Android and iOS Application Security with MobSFAppSec PNW: Android and iOS Application Security with MobSF
AppSec PNW: Android and iOS Application Security with MobSF
Ajin Abraham
 
"$10 thousand per minute of downtime: architecture, queues, streaming and fin...
"$10 thousand per minute of downtime: architecture, queues, streaming and fin..."$10 thousand per minute of downtime: architecture, queues, streaming and fin...
"$10 thousand per minute of downtime: architecture, queues, streaming and fin...
Fwdays
 
Freshworks Rethinks NoSQL for Rapid Scaling & Cost-Efficiency
Freshworks Rethinks NoSQL for Rapid Scaling & Cost-EfficiencyFreshworks Rethinks NoSQL for Rapid Scaling & Cost-Efficiency
Freshworks Rethinks NoSQL for Rapid Scaling & Cost-Efficiency
ScyllaDB
 
Fueling AI with Great Data with Airbyte Webinar
Fueling AI with Great Data with Airbyte WebinarFueling AI with Great Data with Airbyte Webinar
Fueling AI with Great Data with Airbyte Webinar
Zilliz
 
Monitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdfMonitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdf
Tosin Akinosho
 
The Microsoft 365 Migration Tutorial For Beginner.pptx
The Microsoft 365 Migration Tutorial For Beginner.pptxThe Microsoft 365 Migration Tutorial For Beginner.pptx
The Microsoft 365 Migration Tutorial For Beginner.pptx
operationspcvita
 
GNSS spoofing via SDR (Criptored Talks 2024)
GNSS spoofing via SDR (Criptored Talks 2024)GNSS spoofing via SDR (Criptored Talks 2024)
GNSS spoofing via SDR (Criptored Talks 2024)
Javier Junquera
 
zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...
zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...
zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...
Alex Pruden
 
Y-Combinator seed pitch deck template PP
Y-Combinator seed pitch deck template PPY-Combinator seed pitch deck template PP
Y-Combinator seed pitch deck template PP
c5vrf27qcz
 
Session 1 - Intro to Robotic Process Automation.pdf
Session 1 - Intro to Robotic Process Automation.pdfSession 1 - Intro to Robotic Process Automation.pdf
Session 1 - Intro to Robotic Process Automation.pdf
UiPathCommunity
 
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development ProvidersYour One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
akankshawande
 

Recently uploaded (20)

Dandelion Hashtable: beyond billion requests per second on a commodity server
Dandelion Hashtable: beyond billion requests per second on a commodity serverDandelion Hashtable: beyond billion requests per second on a commodity server
Dandelion Hashtable: beyond billion requests per second on a commodity server
 
Biomedical Knowledge Graphs for Data Scientists and Bioinformaticians
Biomedical Knowledge Graphs for Data Scientists and BioinformaticiansBiomedical Knowledge Graphs for Data Scientists and Bioinformaticians
Biomedical Knowledge Graphs for Data Scientists and Bioinformaticians
 
[OReilly Superstream] Occupy the Space: A grassroots guide to engineering (an...
[OReilly Superstream] Occupy the Space: A grassroots guide to engineering (an...[OReilly Superstream] Occupy the Space: A grassroots guide to engineering (an...
[OReilly Superstream] Occupy the Space: A grassroots guide to engineering (an...
 
"Choosing proper type of scaling", Olena Syrota
"Choosing proper type of scaling", Olena Syrota"Choosing proper type of scaling", Olena Syrota
"Choosing proper type of scaling", Olena Syrota
 
Taking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdfTaking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdf
 
Northern Engraving | Nameplate Manufacturing Process - 2024
Northern Engraving | Nameplate Manufacturing Process - 2024Northern Engraving | Nameplate Manufacturing Process - 2024
Northern Engraving | Nameplate Manufacturing Process - 2024
 
Essentials of Automations: Exploring Attributes & Automation Parameters
Essentials of Automations: Exploring Attributes & Automation ParametersEssentials of Automations: Exploring Attributes & Automation Parameters
Essentials of Automations: Exploring Attributes & Automation Parameters
 
"Frontline Battles with DDoS: Best practices and Lessons Learned", Igor Ivaniuk
"Frontline Battles with DDoS: Best practices and Lessons Learned",  Igor Ivaniuk"Frontline Battles with DDoS: Best practices and Lessons Learned",  Igor Ivaniuk
"Frontline Battles with DDoS: Best practices and Lessons Learned", Igor Ivaniuk
 
Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024
 
AppSec PNW: Android and iOS Application Security with MobSF
AppSec PNW: Android and iOS Application Security with MobSFAppSec PNW: Android and iOS Application Security with MobSF
AppSec PNW: Android and iOS Application Security with MobSF
 
"$10 thousand per minute of downtime: architecture, queues, streaming and fin...
"$10 thousand per minute of downtime: architecture, queues, streaming and fin..."$10 thousand per minute of downtime: architecture, queues, streaming and fin...
"$10 thousand per minute of downtime: architecture, queues, streaming and fin...
 
Freshworks Rethinks NoSQL for Rapid Scaling & Cost-Efficiency
Freshworks Rethinks NoSQL for Rapid Scaling & Cost-EfficiencyFreshworks Rethinks NoSQL for Rapid Scaling & Cost-Efficiency
Freshworks Rethinks NoSQL for Rapid Scaling & Cost-Efficiency
 
Fueling AI with Great Data with Airbyte Webinar
Fueling AI with Great Data with Airbyte WebinarFueling AI with Great Data with Airbyte Webinar
Fueling AI with Great Data with Airbyte Webinar
 
Monitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdfMonitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdf
 
The Microsoft 365 Migration Tutorial For Beginner.pptx
The Microsoft 365 Migration Tutorial For Beginner.pptxThe Microsoft 365 Migration Tutorial For Beginner.pptx
The Microsoft 365 Migration Tutorial For Beginner.pptx
 
GNSS spoofing via SDR (Criptored Talks 2024)
GNSS spoofing via SDR (Criptored Talks 2024)GNSS spoofing via SDR (Criptored Talks 2024)
GNSS spoofing via SDR (Criptored Talks 2024)
 
zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...
zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...
zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...
 
Y-Combinator seed pitch deck template PP
Y-Combinator seed pitch deck template PPY-Combinator seed pitch deck template PP
Y-Combinator seed pitch deck template PP
 
Session 1 - Intro to Robotic Process Automation.pdf
Session 1 - Intro to Robotic Process Automation.pdfSession 1 - Intro to Robotic Process Automation.pdf
Session 1 - Intro to Robotic Process Automation.pdf
 
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development ProvidersYour One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
 

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'
  • 6.
  • 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
  • 8.
  • 9.
  • 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/
  • 17.
  • 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