A quick, brief, stupid overview of TDD in general, and then some Kiwi-specific stuff. Codebase referenced in the slidedeck is here: https://github.com/crebma/pants-lister
careless refactors build a design that is inherently testable, which means modular and easy to change reveal code smells (srp, dawg!) breaks large nebulous things into small tasks so it can inform the next step (omg, just like a card wall!)
careless refactors build a design that is inherently testable, which means modular and easy to change reveal code smells (srp, dawg!) breaks large nebulous things into small tasks so it can inform the next step (omg, just like a card wall!) allows the ability to change code with confidence
most-often run tests. you want the feedback cycle to be fast, so we cut out the parts that are slow and replace them with mocks. you don't want to test third party libraries. if you’ve done library selection carefully, you’ve chosen a library that already has tests, so we can focus on testing our own output and not everyone else’s.
api. when you expose your privates and test those, you are locking in the implementation of that object, rather than the output of that object. you want to test that your object does or produces X in a given scenario, not exactly how it will come to produce X. this makes it easier to refactor code to do the same thing, but better, without having to change your tests.
our object in isolation, we want to be able to completely control the scenario for each test, similar to pulling the strings on a puppet. more on this later. be a puppet master
our object in isolation, we want to be able to completely control the scenario for each test, similar to pulling the strings on a puppet. more on this later. …yes, i’m talking about mocks. what is wrong with me. be a puppet master
our object in isolation, we want to be able to completely control the scenario for each test, similar to pulling the strings on a puppet. more on this later. …yes, i’m talking about mocks. what is wrong with me. be a puppet master
understand what is happening. arrange your test goodly this costs more time for someone to figure out: that’s a test with parts in it, presumably ending with an assertion…?
test failure becomes ambiguous. it could be any given assertion in a test. this is especially a pain if your multiple asserts are by way of a for loop. have fun debugging that. one assert per test
test failure becomes ambiguous. it could be any given assertion in a test. this is especially a pain if your multiple asserts are by way of a for loop. have fun debugging that. one assert per test it also means you’re probably taking WAY too big of a step. take baby steps. all you have to do is take one little step at a time, and you can do anything!
test failure becomes ambiguous. it could be any given assertion in a test. this is especially a pain if your multiple asserts are by way of a for loop. have fun debugging that. one assert per test it also means you’re probably taking WAY too big of a step. take baby steps. all you have to do is take one little step at a time, and you can do anything!
the process instead of some nebulous “refactor stuff” card later that never gets played because no one knows what it means. red green refactor 1. you write a little test.
the process instead of some nebulous “refactor stuff” card later that never gets played because no one knows what it means. red green refactor 1. you write a little test. 2. you make the test pass.
the process instead of some nebulous “refactor stuff” card later that never gets played because no one knows what it means. red green refactor 1. you write a little test. 2. you make the test pass. 3. you look at your code and see if there is anything to clean up or any way to make it better. this also applies to your test code. this is refactoring!
the process instead of some nebulous “refactor stuff” card later that never gets played because no one knows what it means. red green refactor 1. you write a little test. 2. you make the test pass. 3. you look at your code and see if there is anything to clean up or any way to make it better. this also applies to your test code. this is refactoring! 4. go back to 1 and start over. don’t skip 3.
are awesome. let’s draw on the board about that. that puppet thing…mocks there are a couple kinds of mocks. a strict mock will blow up if anything on it is called that you did not stub. a nice mock will either do nothing or return null if necessary.
are awesome. let’s draw on the board about that. that puppet thing…mocks there are a couple kinds of mocks. a strict mock will blow up if anything on it is called that you did not stub. a nice mock will either do nothing or return null if necessary. what is “stub”?
are awesome. let’s draw on the board about that. that puppet thing…mocks there are a couple kinds of mocks. a strict mock will blow up if anything on it is called that you did not stub. a nice mock will either do nothing or return null if necessary. what is “stub”? a stub is the way you pull the puppet strings. you can stub a mock to return some predetermined value, or to execute some alternate functionality! strings!!!!
mean mocks and stubs. whatever. but this service talks to an external api we can mock the actual library that talks to the external api and stub it to return a predetermined bunch of data, and then test our service’s output. in java, that probably means an injected wrapper class. in iOS, you can just do it. examples later.
objects. but this has a lot of view interactions where possible, you should extract the non- view logic to a collaborator, which will make it much easier to test. for example, in a view controller in iOS, anything that gets data should be in a collaborator object.
objects. but this has a lot of view interactions where possible, you should extract the non- view logic to a collaborator, which will make it much easier to test. for example, in a view controller in iOS, anything that gets data should be in a collaborator object. tests around how things *look* instead of how things *behave* should live in a different quite of tests. we’ll talk a little about that later.
code is exercised by tests. it will examine logic branches, like ifs and loops, as well as your public methods. scavenger hunt is at about 72% coverage, which means they can change code with a relatively high degree of confidence that the tests will tell them if anything went wrong. a chart that shows what is tested!
is no magic number that leads to doing stuff like testing getters and setters, which is silly. a lot of folks aim for 85%, knowing that being below that is perfectly fine if it is explainable. that seems like a good goal.
we talked about in the beginning. they can also be called logic tests. kinds of tests integration tests are also a thing. they test the contract between 2-3 layers. these tests might talk to an actual database or an actual database and test the contract between your service object and the network or database.
we talked about in the beginning. they can also be called logic tests. kinds of tests integration tests are also a thing. they test the contract between 2-3 layers. these tests might talk to an actual database or an actual database and test the contract between your service object and the network or database. another kind of test is acceptance tests, also called behavior tests, end to end tests, or application tests. these tests do not mock at all if possible, and run through the real ui right down to the real service.
yourFaceIsAmazing() { Face yourFace = new Face(); assertThat(yourFace, is(“Amazing”)); } @Test public void yourFaceIsSmilingWhenYouAreHappy() { Face yourFace = new Face(); yourFace.setMood(HAPPY); assertThat(yourFace.getExpression(), is(SMILING)); } }