Also, it is a paradigm shift from “convention over configuration” to “configuration over convention”.
In “convention over configuration”, you name things in a certain way, or you drop them in a certain directory, and they “click together” because of that, but you need to know the locations, the rules, etc.
Also, the system falls apart if you try to move things around, even if you don’t change them.
This is very bad for testing and maintainability, because the rules are not enforced statically, but it’s some sort of “meta-language” defined by the framework of choice, and a framework change can break everything.
In “configuration over convention” you map things, and your configuration is authoritative. The configuration is then read from the tooling and used to assemble/run things. This means that you can write different configurations for different contexts (such as testing, as mentioned by Greg).
While more cumbersome, this makes it hard for things to break unless configuration interpretation changes (which should not happen).
Hope that helps