Last active
August 9, 2016 20:59
Revisions
-
Julian Maicher renamed this gist
Oct 27, 2014 . 1 changed file with 0 additions and 0 deletions.There are no files selected for viewing
File renamed without changes. -
Julian Maicher revised this gist
Oct 27, 2014 . 2 changed files with 1 addition and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -28,6 +28,7 @@ def run_unittest_without_output(): def unittest_with_mutant(mutant): code = compile(mutant, '<string>', 'exec') # don't do that at home exec code in globals() return run_unittest_without_output() File renamed without changes. -
Julian Maicher renamed this gist
Oct 27, 2014 . 1 changed file with 0 additions and 0 deletions.There are no files selected for viewing
File renamed without changes. -
Julian Maicher created this gist
Oct 27, 2014 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,10 @@ class FooBar: @classmethod def baz(cls, x): if (x % 3 == 0) or (x % 5 == 0): return "foo" elif x % 2 == 0: return "bar" else: return "baz" This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,57 @@ import unittest import ast, astunparse, inspect from foobar import FooBar from mutate import mutate class FooBarTest(unittest.TestCase): # missing case def test_foo(self): # self.assertEquals(FooBar.baz(9), 'foo') pass def test_bar(self): self.assertEquals(FooBar.baz(2), 'bar') def test_baz(self): self.assertEquals(FooBar.baz(7), 'baz') def run_unittest_without_output(): suite = unittest.TestSuite() for test in ['test_foo', 'test_bar', 'test_baz']: suite.addTest(FooBarTest(test)) result = unittest.TestResult() suite.run(result) return result def unittest_with_mutant(mutant): code = compile(mutant, '<string>', 'exec') exec code in globals() return run_unittest_without_output() def unittest_with_mutants(mutants): print "Running mutation tests..." passedWithMutant = False for mutant in mutants: result = unittest_with_mutant(mutant) if result.wasSuccessful(): # mutant passed => failed passedWithMutant = True source = astunparse.unparse(mutant) print "FAILED - Everything passed with the following mutant: %s" % source if not passedWithMutant: print "OK - Tested with %i mutant(s), everything covered" % len(mutants) if __name__ == '__main__': # Test without mutations unittest.main(exit=False) # Test with mutations source_ast = ast.parse(inspect.getsource(FooBar)) mutants = mutate(source_ast) unittest_with_mutants(mutants) This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,35 @@ import ast, _ast, copy class Mutator(ast.NodeTransformer): MUTATIONS = [ # (FromOp, ToOp) (_ast.Or, _ast.And), (_ast.And, _ast.Or) ] def mutate(self, root, mutation): self._changed = False self._mutation = mutation mutant = self.visit(root) return (mutant, self._changed) def visit_BoolOp(self, node): (FromOp, ToOp) = self._mutation if(type(node.op) == FromOp): self._changed = True node.op = ToOp() return node # returns all mutants for given ast def mutate(ast): mutants = [] mutator = Mutator() for mutation in Mutator.MUTATIONS: (mutant, mutated) = mutator.mutate(copy.deepcopy(ast), mutation) if mutated: mutants.append(mutant) return mutants This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,19 @@ ... ---------------------------------------------------------------------- Ran 3 tests in 0.001s OK Running mutation tests... FAILED - Everything passed with the following mutant: class FooBar: @classmethod def baz(cls, x): if (((x % 3) == 0) and ((x % 5) == 0)): return 'foo' elif ((x % 2) == 0): return 'bar' else: return 'baz'