I'm wondering if there are other approaches, old or new, to writing unit tests, and how viable they are, other than the traditional and tdd unit testing approaches.

I know there is behavior-driven development, which also uses test-first, but the tests themselves can be used as specification. What others?

closed as too broad by gnat, Bart van Ingen Schenau, user40980, GlenH7, amon Dec 10 '14 at 19:54

Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. Avoid asking multiple distinct questions at once. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 3
    You mean besides the old standards: "don't write unit tests", "write big, unmaintainable, slow, fragile, and possible non-deterministic 'unit' tests", and "write code that satisfies our code coverage requirement without actually testing anything"? Seriously though, I'm not sure what you're asking. – Telastyn Dec 3 '14 at 2:47
  • I mean, "acceptable" ways to write your unit tests, and when/how to do this. For example, unit tests used with BDD in mind, are written slightly different than TDD, although both use test-first approaches. I'm looking general practices, such as BDD and TDD, not specific things like using design patterns. – user7253 Dec 3 '14 at 2:57
  • The statement "unit tests used with BDD in mind are written slightly different than TDD" is a logical trap. It is not a question of either BDD or TDD. It is a question of whether we combine TDD and BDD or don't. (And in my opinion we should.) – Christian Hujer Dec 3 '14 at 5:50
  • I often use alternative approaches to the standard TDD: (1) write several tests at once and then implement the code making all tests pass (instead of iterating test - code - refactor), (2) implement code and then write tests (helps avoid writing tests for code you are going to throw away five minutes later). – Giorgio Dec 8 '14 at 10:44
up vote 5 down vote accepted

I think there's not much more, you might be "close" to the complete picture (at least the picture that I'm aware of), so I'll give you a list of buzz-words.

  • no testing: Don't use!
  • test-last: old crap from the past, like doctors not washing their hands or accountants attempting to skip double-entry book keeping. Better than no testing, but still don't use.
  • test-first: The thing to do, but do it right, see TDD.
  • TDD: Formalized approach to test-first, based on the 3 Laws of Test-Driven Development, driving us through a Red-Green-Refactor cycle.
  • ATDD: Application of test-first on acceptance tests. The 3 Laws are changed from "write" to "pick", as we usually don't want to wait with writing further acceptance tests for the current acceptance tests to pass.
  • Transformation Priority Premise: Sequence of transformations that we should keep in mind in order to know with which tests to start and which tests to write (TDD) or pick/add (ATDD) next.
  • 3 A's: Arrange, Act, Assert - the three major steps of a test case.
  • 4 A's: Extension of 3 A's: Arrange, Act, Assert, Annihilate. Let's not forget cleaning up.
  • BDD: Mapping of the 3 A's to good names givenArrangement, whenAction, thenAssertion, ideally in a file format that's readable by non-technical humans, like Gherkin.
  • Single-Assert-Rule: Only one logical assertion per test-case. Manifestation of the SRP in testing.
  • Mocking: The substitution of components/classes/objects with by test-doubles. Used to cover the required interface towards the substituted thing on which the component/class/object under test depends. Also used to speedup tests (i.e. a fake in-memory db will be faster than a real SQL db). Also helps with design, especially decoupling, to decrease immobility and improve re-usability. Ontology: mock extends spy extends stub extends dummy extends abstract test double; fake extends abstract test double. But only use mocking when it helps you, for example, speeds up tests by replacing external dependencies. Don't mock because you can, only mock when you actually need to.
  • Integration testing: Testing the combined interaction between components/classes/objects. Currently the field where the industry is lacking most, as it seems nobody knows yet how to get this part right. If you want to get famous, fix this topic.

And finally, what are tests? Tests are the actual requirements specification. What ppl used to call requirements specification actually is not a requirements specification, it's a requirements model (simplified and incomplete). When we're releasing software, we're not looking at the code on one screen and the requirements document on the other screen, going through it like a checklist - instead we're running tests. Therefore, the tests are the true requirements specification.

As with all guidelines and laws, use judgement when to not follow them. You don't want to tell your customers that their credit cards were stolen because you first had to write a test for that SQL injection bug that one of your clients found. But you also don't want to tell your clients that their credit cards were stolen because after fixing that SQL injection bug you didn't write tests to verify the fix and look for more bugs like that.

Not the answer you're looking for? Browse other questions tagged or ask your own question.