Question: Another name for this question could be: How to TDD the main function?

My situation: I'm writing a program from scratch that runs a sort of simulation, and I want to apply TDD to the whole development process. It seems straightforward to me when I think about the small detailed features, but at some point the program needs to *start*. For example, this is a rough outline of how the program will run:

1. Read data from a database.
2. Loop a bunch of times simulating the desired behavior.
3. Write the output somewhere.

I'm tempted to write a test like `testLoopProducesValidOutput` but that's basically just checking to see if the entire program ran correctly, which doesn't seem very unit-like for a unit test.

In the spirit of "don't write code unless you have a failing test", I don't quite understand what kind of test to write to actually get that initial high-level code written that isn't running the entire thing. How would one generally approach this kind of situation?

(Of course one solution is just to not strictly follow TDD for this part, but if there's another solution I'm open to learning before I give up. :) )

Answer: 
TDD isn't limited to unit tests, it can be applied at any granularity. What you're trying to do is covered by [acceptance test-driven development](https://en.wikipedia.org/wiki/Acceptance_test-driven_development) (ATDD) which adds an outer loop to the classic red-green-refactor cycle: you write a failing acceptance test first which should help you come up with a skeleton of your overall program, then you write failing unit tests before finally implementing the actual logic. The acceptance tests ensure that you are building the right thing and your various components are wired together correctly, while the unit tests ensure that your components are implemented correctly.

There is an excellent book on this topic called [Growing Object-Oriented Software, Guided by Tests](https://rads.stackoverflow.com/amzn/click/com/0321503627) that goes into detail about this process and includes a worked example of a GUI application built from scratch using TDD.
> 
> How to TDD the main function?
> 
> 
> one solution is just to not strictly follow TDD for this part
> 
> 
> 

For what it is worth, on my own authority this is precisely what I've given myself permission to do.

---

> 
> I conclude that there are two ways of constructing a software design: One way is to make it so simple that there are *obviously* no deficiencies -- [C.A.R Hoare, 1980](https://www.cs.fsu.edu/%7Eengelen/courses/COP4610/hoare.pdf)
> 
> 
> 

If we've written code that "obviously" has no deficiencies, are we really getting a good return on our investment trying to create tests to run in our refactoring loops?

Consider this sketch of a main method for a command line dice game:

```
// Java
public static void main (String [] args) {
    somethingMoreComplicatedButTestable(
        System.in,
        System.out,
        new Random()
    );
}

```

Do you really think an automated mistake detector targeting this code is going to pay for itself?

> 
> I get paid for code that works, not for tests, so my philosophy is to test as little as possible to reach a given level of confidence -- [Kent Beck, 2008](https://stackoverflow.com/questions/153234/how-deep-are-your-unit-tests/153565#153565)
> 
> 
> 

Here, the confidence comes from being disciplined about two rules

* code that is hard to test must be too simple to break
* code that is complicated must be easy to test in isolation

---

> 
> TDD is an awareness of the gap between decision and feedback during programming, and techniques to control that gap. -- *Test Driven Development by Example*
> 
> 
> 

Simplicity is a valid technique for controlling that gap.

---

See also: [Mark Seemann's answer from 2014](https://stackoverflow.com/a/22979208/54734)