I’ve been saving this rant for a while now:
1. Test everything at the front-end, in exquisite detail – every project sponsor understands what tooltip 0 really means. Also a great idea if you like long-running and fragile tests that require deployments, browsers, testing frameworks and the kitchen sink. Testing at different layers, and perhaps even without a browser or (in java) a servlet container is for the weak.
2. Perform a database cleanup before and after every test, whether it needs to be done or not. For the truly adventurous add something about clearing out JMS queues and stopping scheduled tasks while you are running the cleanup tasks.
3. Always use the same data for tests, and better still use the same data for different tests. That way you will have do perform anti-pattern 2 with no questions asked. If anyone does ask about random or unique data just scoff sagely.
4. For those tied to java, run each test in its own JVM. If you happen to use a DI framework with lots of XML make sure it is initialised completely for each test. If anyone mentions forkmode=once just pretend to ignore them until they go away.
5. Write your application so that you need a JavaScript enabled browser before you can test anything at all. Progressive enhancement is only for those who cannot see.
Catharsis.
#1 by Matt McClure on 7 March 2010 - 2:07 am
Quote
Regarding #1, what *do* you suggest testing at the front end? Recognizing that you need to test *something* is step 1; testing too much and fragile tests usually result. Step 2: finding an appropriate way to test integration via the front end is significantly harder.
#2 by Graham on 7 March 2010 - 3:11 am
Quote
I can tell you have not lost your touch. Nice post!
#3 by Tom on 7 March 2010 - 2:00 pm
Quote
@Matt, I look at this like a shell game, or one of those neat little russian dolls (where one sits inside another). For this reply I’d like to assume a “relatively” standard web app architecture with a bounded context around a domain, with repositories at one boundary and controllers/endpoints/presenters at the other (acting as anti-corruption & translation layers).
I would test repository logic, type conversion, ORM, aggregation, query builders, etc at one end in their own tests without the front-end. It saddens me when I see repository tests that need the entire application to be up and running – on one project even the JMS queue had to be enabled to wire-up a single JDBC repository.
I would test the controller/endpoint/presenter marshalling/unmarshalling logic at the other end, with more of the application configured but still in their own unit tests. If you are not tied to JSPs in java, you can actually test any “logic” in your templates by trying to render them out with some canned data. In a spring-wired app (for example) its not that hard to do to initialise a spring framework dispatcher servlet directly and use it in your own tests via the spring framework mock requests & responses (check out my example-webapp project on GitHub). In Rails you can actually test views & controllers separately as well (take a look at the excellent Pragmatic Programmers book on RSpec).
That leaves testing page flows, AJAX-y goodness and goal based testing at the front end via a browser, HtmlUnit/HttpUnit, WebDriver, Selenium, etc. If you write your flows using simple post-redirect-get behaviour and then enhance them with JS later, you can even test the flows without a deployment or a browser. The big thing is that you don’t need to test fine-grained conditions at the front-end, you just have to pick where in the various layers of your system these conditions make sense to be tested. Is it a repository test, a service test, a controller test, a rendering test, a ScrewUnit JS test, or is it truly something that needs a “full stack”?
How much testing do we do at the front-end because its convenient to do so, rather than refactoring our applications to make it easier to test at various layers, and how much of our testing is really a belt & braces approach to a lack of trust/knowledge?