TestLogger wraps an IMessageLogger and adds various utility methods for sending messages. Since the IMessageLogger is only provided when the discovery and execution objects are called, we use two-phase construction. Until Initialize is called, the logger simply swallows all messages without sending them anywhere.