The design of some software, even in substantial detail, is not sufficient to design tests of an implementation. Good tests can be completely dependent on the implementation details far below the level of design because those implementation details determine how the thing you are testing can even be measured. How it is measured isn’t actually important. You can get closer with extreme (over-)specification of the implementation, which almost no one does because it comes with an inordinate cost, but even that can fail because software properties are also a function of the hardware it runs on. To some extent, modeling the interaction of software on hardware for the purposes of building good tests is by actually measuring running code on real hardware.
Hardcoding specific implementation detail assumptions into the design of complex non-trivial systems so that you can write a test is a brittle way to go about writing software. There is a reason that waterfall-style never seems to produce good systems in a reasonable amount of time or money.
I write non-trivial greenfield systems and put inordinate amounts of design work into them (literally years in some cases). I have never found a case where that allowed me to write useful tests prior to implementation. At a minimum you need a complete architectural skeleton that runs and has had its non-functional properties verified analytically before you can write tests that you’ll likely use.
I’m not against writing tests. I invest far more in testing than most devs due to atypically high reliability and robustness requirements. I’m against the complete waste of time that would be writing tests before there is sufficient implementation to design maximally efficient and appropriate tests. Testing of some software is extremely expensive in both time and money, so optimizing test effectiveness and efficiency becomes valuable.