Well if it's TDD, then tests are written first. But I do "cheat" on few occasions and write the code before writing the test(s).
IMO, the "TDD laws" can be bent sometimes but not too often and you need to be careful when.
But all in all, tests have to be written and cover as much logic as possible (though 100% coverage goal is not an option in reality).
Do you write pseudo code for the tests? Or are you thinking before you write your code that you know what will be there?
That's a good question. I usually follow a similar path as the one John mentioned, which is what TDD is all about from my perspective:
TDD doesn't eliminate the need for design consideration, quite the opposite.
TDD is about design and that's why your question is very important - it's not just the notion of writing tests first and code later.
Personally, I sketch out what functionality/logic I'll need (typically putting it down as checkboxes in a GitHub issue I've raised for whatever I'm working on) for the feature; I sort of concurrently build up both the production code and the associated unit test - fleshing out the latter's tests as the former calls for new error handling scenarios.
I'm still trying to get better at TDD and I'm pretty flexible with the "laws" in practice.
We're a place where coders share, stay up-to-date and grow their careers.
We strive for transparency and don't collect excess data.