Personal observations on application testing and designing

Personal observations on application testing and designing

Just some thoughts I've gathered based on talks by Ian Copper, Robert Martin... Coupling and cohesion, testing behaviors, TDD... and certainly some controversial suggestions.

6acd3df818349485f3942b5c6d16247a?s=128

Youri Ackx

April 22, 2015
Tweet

Transcript

  1. 2.

    Disclaimer These I just personal observations and ideas I’ve been

    chewing over. Some of them may even be contradictory.
  2. 4.

    Warmup question Q: Is it possible to write an implementation

    class that cannot be covered 100% ? A: Yes. Sanity check lines may be unreachable. You do have them in your code, right?
  3. 5.

    It shines beyond testing Applying testing principles may reveal design

    weaknesses in implementation code (Most) TDD principles are worth applying, even if you don’t do TDD
  4. 6.

    Some of our sins Never failing tests Test coupled to

    implementation Complex object graph construction Integration test masquerading Mocking private methods Large, recycled datasets for integration tests
  5. 7.

    Never failing tests How can you be sure that your

    test is actually relevant if you have never seen it fail?
  6. 8.

    Mock complex object graph Anemic objects won’t be a problem

    but constructors that checks invariants + computed fields can be cumbersome
  7. 9.

    Mock complex object graph // Needed for Foo constructor Bar

    bar = new Bar(“bar”); Chung chung = ChungFactor.create(bar); // Now I can have foo Foo myFoo = new Foo(bar, chung) // Simulate actual value Date date = new Date(); Integer value = 42; // Past 3 dates are mandatory for foo.getCurrentValue() to work myFoo.addValue(new Date(), null); myFoo.addValue(new Date(), null); myFoo.addValue(date, value); // OK now I can test something that requires foo // but that is *not* about foo
  8. 10.

    Mock complex object graph // Needed for Foo constructor Bar

    bar = new Bar(“bar”); Chung chung = ChungFactor.create(bar); // Now I can have foo Foo myFoo = new Foo(bar, chung) // Simulate actual value Date date = new Date(); Integer value = 42; // Past 3 dates are mandatory for foo.getCurrentValue() to work myFoo.addValue(new Date(), null); myFoo.addValue(new Date(), null); myFoo.addValue(date, value); // OK now I can test something that requires foo // but that is *not* about foo I just don’t care. Irrelevant for my test.
  9. 11.

    Mock complex object graph // Just need a dummy Foo

    Foo foo = mock(Foo.class); // Mock current value doReturn(42).when(foo).getCurrentValue(); // OK now I can test something that requires foo
  10. 12.

    Mock complex object graph Easier to set up Clearly focuses

    on what you’re testing Arguably more maintainable Don’t overuse it or your test will become overspecified Some people might try to hurt me for saying that
  11. 13.

    Some potent talk “ TDD, Where did it all go

    wrong ” Ian Cooper https://vimeo.com/68375232
  12. 14.

    Quoted “ Test behaviors, not operations or classes ” Testing

    operations does not capture the ethos of TDD
  13. 15.

    Question OK, but what’s a behavior? Harder to capture when

    working without human actors (more abstract) Varies greatly depending on your context
  14. 17.

    Coupling Loose: You and the guy at the convenience store.

    You communicate through a well-defined protocol to achieve your respective goals - you pay money, he lets you walk out with the bag of Cheetos. Either one of you can be replaced without disrupting the system. Tight: You and your wife. http://stackoverflow.com/questions/39946/coupling-and-cohesion
  15. 18.

    Cohesion Low: The convenience store. You go there for everything

    from gas to milk to ATM banking. Products and services have little in common, and the convenience of having them all in one place may not be enough to offset the resulting increase in cost and decrease in quality. High: The cheese store. They sell cheese. Nothing else. Can't beat 'em when it comes to cheese though.
  16. 20.

    Real-life example Take some code that doesn’t look right, draw

    relations and behaviors on paper, identify issues
  17. 22.

    It goes like this... 1. RED : Write a little

    code that does not work 2. GREEN : Make it work, committing whatever sins necessary in the process 3. Refactor while GREEN, not RED. Remove code smells, duplication, introduce design patterns. Do not introduce public classes
  18. 23.

    It goes like this... You can’t both do engineering and

    solve a problem at the same time. If you write a test during refactoring, you couple your test to your implementation
  19. 26.

    Recycled datasets Large shared datasets make integration tests more fragile.

    Build a dataset a small as possible. Don’t worry about duplication.
  20. 27.

    Testing too much? Think about all the times you had

    to “fix” a test, and had to figure out what amount or what date was expected.
  21. 29.

    Attributions See references on specific slides Java 8 Follow Up

    by Youri Ackx is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.