As opposed to PrematureAbstraction
What abstractions do you usually consider necessary and above YouArentGonnaNeedIt? Too many programmers seem to use YouArentGoingToNeedIt as an excuse to simply write bad code.
Outside of OnceAndOnlyOnce, "bad code" is something that is hard to pin down except as individual opinions and assumptions about the likely change paths of the future.
One perspective
Abstraction becomes necessary when you need to provide OnceAndOnlyOnce. Thus, start with YouArentGonnaNeedIt, make the tests pass, refactor to get OnceAndOnlyOnce, and then you will have some effective and useful abstraction for going forward.
Another perspective
An abstraction is a particular way of vewing reality that singles out particular elements which you're interested in. You don't know what's worth singling out, in terms of making things simpler for programmers, until you have at least two things to abstract across. Test + Functionality can be viewed as two things, and abstracting on that basis will improve the quality of your programming interface. That's one of the positive aspects of TestDrivenDevelopment. But truly useful abstractions have to be tied to external usage. There's no such thing as a NecessaryAbstraction.