Other comments have pointed out that test-driven design was actually born in the Smalltalk community, which sort of answers your question, by implication, at least: it's standard operating procedure to write a lot of tests as you go.

Indeed, in my experience, any expression I write in the repl is more likely than not to be a test, or part of a test.

The way I normally work is with a running Lisp image and one or more files open in editors. For greenfield development I usually create a project and write a loadfile to load any library dependencies I expect to use. Once that's loaded, I write some expressions to build some test data, and then some more expressions to operate on the test data. I evaluate the test-data constructors and then fiddle with operations on the data to assure myself that what happens is what I expect to happen. Basically, I start with an idea of how to accomplish something, sketch out the data structures and APIs I think I'll need, and start exercising them to see what I got wrong, what I need to add or change.

The contents of those source files gradually become the source code of my program and of the test suite that go with it. When the project is new and small, the sources are a few files with a small number of lines of code, and the organization is minimal and loose. As I flesh out the program, the source files grow more numerous and more formally organized.

As a project gets complex, I may choose to save working images at points where I'm confident that the state of the system is good. Such images enable me to start the Lisp environment with all of my code already loaded and ready to use. I can then work from that point in the same way that I've described.

The normal way I work on anything, unless the tools I have to use prevent it, is to have a work-in-progress running, and use variable references and function calls in the repl to query the and modify the dynamic state. For any expression more complicated than a short one-liner, I actually write it in a source file and copy it to the repl (actually, I usually use Emacs with SLIME, so "copying it to the repl" really means typing a keystroke or two in the source file).

One of the differences between old-fashioned Lisp and Smalltalk systems and newer systems with repls is that the old Lisp and Smalltalk repls are capable of doing every part of program development--defining and redefining functions and data structures, running and debugging code, inspecting dynamic state, catching, inspecting, and modifying erroneous code, and building the finished app for deployment--all by typing expressions at the repl.

To put it another way, the entire language and development tools and all of your application's internals are always in memory and completely accessible from the repl.

It's not that you would normally do all your development in the repl, although you could if you wanted. Rather, the important point is that, because the repl can do anything the language and development tools can do, there are no artificial limitations on what you can do from the repl. Outside old Lisp and Smalltalk systems, every repl I've used always imposes some restrictions--some things you can't do from the repl. Invariably the way I discover this is by needing to do something in the repl and finding that it won't let me.