Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Genetically Modified Tests

Genetically Modified Tests

Tests ensure the quality of your code, but what ensures the quality of your tests?
An introduction to mutation testing.

Xavier F. Gouchet

September 04, 2017
Tweet

Video

More Decks by Xavier F. Gouchet

Other Decks in Programming

Transcript

  1. ABOUT… XAVIER F. GOUCHET ANDROID ARCHITECT AT DEEZER #### ‘Mr

    Tools’ / CI Admin / UT Advocate #### Fluent in Android since Cupcake ON ALL SOCIAL NETWORKS … @XGOUCHET 2
  2. Unit tests ? Integration tests ? Functional tests ? Test

    Driven Development ? Code Coverage ? Mutation Testing ? 4
  3. ♫ Let's start at the very beginning (A very good

    place to start) ♪ — Julie Andrews 7
  4. “When a measure becomes a target, it ceases to be

    a good measure.” — Goodhart’s Law 14
  5. “The more any indicator is used for decision-making, the more

    subject it will be to corruption pressures.” — Campbell's Law 15
  6. THE GOAL OF TESTS ? “Verify that the code works”

    Make the contract explicit Guide the development (TDD) Prevent regression caused by Other devs Ourselves in the future Ensure retrocompatibility 16
  7. BAD TESTS CAN GIVE A FALSE SENSE OF SECURITY “We

    need to be as confident in the tests we code as we are in the code we test.” — Me 17
  8. MUTATION TESTING 101 1. Write tests 2. Mutate the code¹

    3. Watch the tests fail 4. ??? 5. Profit 19
  9. STEP 2 Mutate the code¹ Make one or more modification

    to the source code Mutation should break the behavior of the system 21
  10. ¹ WHAT'S A MUTATION ? A MODIFICATION OF A STATEMENT

    IN THE CODE Math operations switch Condition boundaries Constant values Return values … 22
  11. STEP 3 Watch the tests fail At least one test

    should break for each mutation ✗ … or not 23
  12. WHY WOULD A MUTATION DIE ? Test Condition Fails Unexpected

    Exception Non viable code System error Timeout 24
  13. EXAMPLE int check(boolean a, boolean b) { if (a &&

    b) { return 42; } else { return 0; } } void testCheck() { assertEquals(check(true, true), 42); assertEquals(check(false, false), 0); } 27
  14. EXAMPLE (MUTATED) int check(boolean a, boolean b) { if (a

    || b) { // {a && b} → {a || b} return 42; } else { return 0; } } void testCheck() { assertEquals(check(true, true), 42); assertEquals(check(false, false), 0); } 28
  15. EXAMPLE (FIXED) void testCheck() { assertEquals(check(true, true), 42); assertEquals(check(true, false),

    0); assertEquals(check(false, true), 0); assertEquals(check(false, false), 0); } 29
  16. GRADLE PLUGIN buildscript { repositories { mavenCentral() } dependencies {

    classpath 'pl.droidsonroids.gradle:gradle-pitest-plugin:0.0.9' } } apply plugin: 'pl.droidsonroids.pitest' 31
  17. 34

  18. FREQUENTLY ASKED QUESTIONS It does work with Kotlin… …and other

    JVM languages too …maybe Configurable Extensible 37
  19. THINGS TO KEEP IN MIND Mutants won’t find bugs in

    the code, just reveal test issues Not bulletproof Not a viable metric Only simulate atomic faults Costly 38
  20. MY OWN RECOMMENDATIONS Only used locally in the TDD process

    Automatically triggered per PR Not ran on CI server Coverage value is not shared with management Always take results with a grain of salt 39
  21. Java Framework : Pitest IntelliJ / Android Studio plugin :

    Android gradle plugin : pitest.org github.com/zalando/zester github.com/koral--/gradle-pitest-plugin 40