Why Make Gets Confused by Files
Make was designed to build files. When you run make test, Make looks for a file named test in the current directory. If that file exists and is newer than its dependencies, Make concludes the target is already up to date and prints:
make: 'test' is up to date.
Your tests never run. This is not a bug — it is Make doing exactly what it was designed to do. The problem is that in DevOps usage, our targets are abstract tasks, not files. A directory named build/, a file named clean, or a folder named deploy will silently break your workflow.
Declaring Phony Targets
The .PHONY special target tells Make: "These targets are abstract task names, not filenames. Always run their commands, regardless of what exists on disk." Every task-style target in the file — build, test, deploy, clean, lint, and so on — gets listed there in one declaration.
Best practice: Declare every task-style target in .PHONY. Put the .PHONY declaration at the top of the file so it is immediately visible. The cost of declaring a target phony when it doesn't need to be is zero. The cost of forgetting is a silent failure that is extremely hard to debug.
Interviewers sometimes ask: "Why would make test print 'up to date' and not run anything?" The answer is that a file or directory named test exists in the project root, and the target was not declared .PHONY. The fix is to add .PHONY: test. This question tests whether you understand Make's original file-tracking purpose versus its modern task-runner usage.