<div dir="ltr">I have been trying to digest the following series of talks between Martin Fowler, Kent Beck, and David Heinemeier, called "<a href="http://martinfowler.com/articles/is-tdd-dead/">Is TDD Dead?</a>". The topic is a bit inflammatory, but there's some good stuff here.<div><br></div><div>Some major points discussed:</div><div><ul><li>Is there such a thing as test-induced damage to the architecture?</li><li>Should you expect your developers to practice TDD (i.e. does that workflow work for everyone)</li><li>Mocks vs. Integration (inside-out vs. outside-in testing)</li></ul><div>There's a lot to chew on here. Personally, I agree with what others have said in this thread: I think like most things in life, you need to find the middle-way and have both integration and unit tests. To know how healthy your testing ecosystem is, ask yourself these 3 questions:</div></div><div><ol><li>Which do I spend more time on: my changes, or writing tests for my changes?</li><li>Do I need to learn an entirely orthogonal way of interacting with my code for testing?</li><li>How many defects are getting through?</li></ol><div>Enjoying following this thread.</div></div><div><br></div><div>-</div><div>Katherine</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Sep 12, 2014 at 5:42 AM, Michael Foord <span dir="ltr"><<a href="mailto:michael.foord@canonical.com" target="_blank">michael.foord@canonical.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5"><br>
On 12/09/14 06:05, Ian Booth wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
On 12/09/14 01:59, roger peppe wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
On 11 September 2014 16:29, Matthew Williams<br>
<<a href="mailto:matthew.williams@canonical.com" target="_blank">matthew.williams@canonical.<u></u>com</a>> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Hi Folks,<br>
<br>
There seems to be a general push in the direction of having more mocking in<br>
unit tests. Obviously this is generally a good thing but there is still<br>
value in having integration tests that test a number of packages together.<br>
That's the subject of this mail - I'd like to start discussing how we want<br>
to do this. Some ideas to get the ball rolling:<br>
</blockquote>
Personally, I don't believe this is "obviously" a good thing.<br>
The less mocking, the better, in my view, because it gives<br>
better assurance that the code will actually work in practice.<br>
<br>
Mocking also implies that you know exactly what the<br>
code is doing internally - this means that tests written<br>
using mocking are less useful as regression tests, as<br>
they will often need to be changed when the implementation<br>
changes.<br>
<br>
</blockquote>
Let's assume that the term stub was meant to be used instead of mocking. Well<br>
written unit tests do not involve dependencies outside of the code being tested,<br>
and to achieve this, stubs are typically used. As others have stated already in<br>
this thread, unit tests are meant to be fast. Our Juju "unit" tests are in many<br>
cases not unit tests at all - they involve bringing up the whole stack,<br>
including mongo in replicaset mode for goodness sake, all to test a single<br>
component. This approach is flawed and goes against what would be considered as<br>
best practice by most software engineers. I hope we can all agree on that point.<br>
</blockquote>
<br></div></div>
I agree. I tend to see the need for stubs (I dislike Martin Fowler's terminology and prefer the term mock - as it really is by common parlance just a mock object) as a failure of the code. Just sometimes a necessary failure.<br>
<br>
Code, as you say, should be written as much as possible in decoupled units that can be tested in isolation. This is why test first is helpful, because it makes you think about "how am I going to test this unit" before your write it - and you're less likely to code in hard to test dependencies.<br>
<br>
Where dependencies are impossible to avoid, typically at the boundaries of layers, stubs can be useful to isolate units - but the need for them often indicates excessive coupling.<span class=""><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
To bring up but one of many concrete examples - we have a set of Juju CLI<br>
commands which use a Juju client API layer to talk to an API service running on<br>
the state server. We "unit" test Juju commands by starting a full state server<br>
and ensuring the whole system behaves as expected, end to end. This is<br>
expensive, slow, and unnecessary. What we should be doing here is stubbing out<br>
the client API layer and validating that:<br>
1. the command passes the correct parameters to the correct API call<br>
2. the command responds the correct way when results are returned<br>
<br>
Anything more than that is unnecessary and wasteful. Yes, we do need end-end<br>
integration tests as well, but these are in addition to, not in place of, unit<br>
tests. And integration tests tend to be fewer in number, and run less frequently<br>
than, unit tests; the unit tests have already covered all the detailed<br>
functionality and edge cases; the integration tests conform the moving pieces<br>
mesh together as expected.<br>
<br>
As per other recent threads to juju-dev, we have already started to introduce<br>
infrastructure to allow us to start unit testing various Juju components the<br>
correct way, starting with the commands, the API client layer, and the API<br>
server layer. Hopefully we will also get to the point where we can unit test<br>
core business logic like adding and placing machines, deploying units etc,<br>
without having to have a state server and mongo. But that's a way off given we<br>
first need to unpick the persistence logic from our business logic and address<br>
cross pollination between our architectural layers.<br>
<br>
</blockquote>
<br></span>
+1<br>
<br>
Being able to test business logic without having to start a state server and mongo will make our tests soooo much faster and more reliable. The more we can do this *without* stubs the better, but I'm sure that's not entirely possible.<br>
<br>
All the best,<br>
<br>
Michael<div class="HOEnZb"><div class="h5"><br>
<br>
-- <br>
Juju-dev mailing list<br>
<a href="mailto:Juju-dev@lists.ubuntu.com" target="_blank">Juju-dev@lists.ubuntu.com</a><br>
Modify settings or unsubscribe at: <a href="https://lists.ubuntu.com/mailman/listinfo/juju-dev" target="_blank">https://lists.ubuntu.com/<u></u>mailman/listinfo/juju-dev</a><br>
</div></div></blockquote></div><br></div>