NEW From the makers of Ta-da List: Highrise — it's an online address book, contact manager, task list, and more. Try it free!

Testing Anti-Patterns

Ideas for testing anti-patterns. Just collecting ideas here and will possibly edit down for an article or talk later. Send suggestions to @jimweirich or email to jim.weirich@gmail.com. Thanks.

bullet Testing for exact class (should check behaviour, not implementation)
bullet Overmocking, leading to fantasy testing
bullet Huge setup method (via @paytonrules)
bullet God tests -- Testing everything end to end and specifying the behaviour along the way (via @kevinclark)
bullet Mocking the object under test -- essentially testing that you have have mocked (via @hgimenez)
bullet conjunction examples (should do this and this and this) - testing too many things at once (via @brentsnook)
bullet lots of code to setup the SUT. Use factories, fixtures, or moms. If SUT setup is hard then it's too hard to test and reason with (via @matthew)
bullet Testing an algorithm with an algorithm - eg. date calculations by, calculating dates (via @haruki_zaemon)
bullet mixed state and interaction based assertions in a single example (via @brentsnook)
bullet multiple assertions in a single example (via @brentsnook)
bullet Relying on state from a previous test as setup (via @haruki_zaemon)
bullet Assertions/expectations involving ephemeral values/quantities: eg real-time, precise elapsed-time, disk sizes, disk locations (via @haruki_zaemon)
bullet testing private methods: If you want to test them, make them public (perhaps as part of another class)(via @haruki_zaemon)
bullet stating interaction in example name rather than behaviour - "should call User finder" vs "should retrieve User by name" (via @brentsnook)
bullet tests that talk about more than one functional concept, tests with too much setup, nested mocks, too many mocks (via @dastels)
bullet 1-1 test-method or TestCase-Class correspondance (@via dastels)
bullet Failing to spec edge cases. Underspecification. (via @hgimenez)
bullet False description: test description falls out of sync with test example. (via @elight)
bullet Narrative tests. Setup and assert, then modify and assert, then modify some more and assert.
bullet Overmacroing -- leads to seemingly readable tests backed by so much code that the tests are no longer immediately comprehensible (via @elight)
bullet Using fixtures (via @elight)
bullet Refining @brentsnook's, s/interaction/implementation. Using implementation details in test name/description. (via @elight)
bullet Corrollary to @hgimenez (and to point out that anything other than path testing is "art"), "Testing too much: Overspecification" (via @elight)
bullet Testing private methods via send (via @bgswan)
bullet overly DRY tests that sacrifice comprehension and hence the documentation value (via @bmabey)
bullet Setting expectations that private methods get invoked, e.g. test_class.should_receive(:some_private_method) (via @bgswan)
bullet Implementation-Driven Testing. (Read: code first, test later). Symptoms include "hard to test", "too much setup", "hard to mock" (via @dbrady)
bullet Using wooly words like 'should' instead of "MUST", but maybe that's from a mis-spent youth reading RFCs. :) (via @mathie)
bullet Higher level abstraction for tests - Based on the notion that with anti-patterns, assertions and expectations become implicit. (via @bigdaddytee)
bullet Maybe this one's controversial: testing declarative has_many macro with an assert_has_many macro. Doesn't really test behavior. (via @usergenic)
bullet *not* mocking third party services (the classic "am I testing my own code or am I testing X -- where X is often Rails ;-) ) (via @elight)
bullet overmocked: a test that verifies the mocks it's created, rather than the code it's supposedly checking (via @cflipse)
bullet test-later specs that verify the bugs already present (via @cflipse)
bullet Restatement of overmacroing: OverDRYing tests at expense of readability. (via @elight)
bullet Testing the framework, not the code that uses it (via @mikewoodhouse)
bullet Saying your testing one thing, then testing another (via @paulanthonywils)
bullet Excessive meta-programming in the test code base.
bullet @model.predicate?.should be_true rather than @model.should be_predicate
bullet Expecting that a certain implementation is used (i.e., User.should_receive(:find_all_by_name).with(a_name)) which handicaps refactoring (User.find(:all, :conditions => { :name => a_name }) is logically the same).