Being a real Test-Driven junkie, I usually try to create a basic test API with all of the basic things that I find myself doing every time I write tests. I then use it to write tests to test and implement some of the more common algorithms that I find myself using most often.
If I can't find good support for a test framework in the xUnit style, I'll add some basic comparisons to my test API, and if I can't find a BDD API, I'll try and create something to get me close syntactically to StoryQ or something similar.
As I find myself building the test API, I very quickly start to create my tests using the Test API to effectively test itself, and in the early stages, I'll write tests to examine unfamiliar language features. When all of that is done I move onto a simple project that I have been waiting to work on. Something low risk but useful so that it encourages me to try harder to make it work, rather than assuming I'm simply going to throw away whatever I learn with. If something is particularly hard to work out in the language, I'll spike the problem as I usually would, but with a focus on learning the language more than solving a specific problem.
So to sum up my answer in terms of the OP's question, I use a collection of apps and tasks that are familiar to me, but simple enough to be useful in and of themselves, and while the core test approach is a constant, the Apps themselves will vary as needs arise so that I don't lock myself down to something that feels to easy to do.