Though generally good advice, I have to disagree with a few points.
The first is the “test one thing” aspect. Even accounting for variability in what “one thing” means I don’t think you should not be able to test multiple things in one test. Say you have to test the sequence of events A B C D. What you’re suggesting is that you have to write a test for A, one for A B, one for A B C, and one for A B C D. In such cases it makes far more sense to simply write one test that builds from the previous setup.
If we add “Stress/Performance Test” to your list of test types then it should be clear that “avoiding repetition” is not an option. Even aside from such testing repetition is often a very good form of testing at the integration level. Code has internal state, and quite often simply running a test in succession twice will cause it to fail. While it certainly shouldn’t be overdone, repeating the same test in sequence, on a given setup, can be quite valuable.
“Don’t hide the setup” is also quite general. At the unit test level this is perhaps a good approach, but at the integration test level you really do have to hide this. Once a running system involves a large number of modules and a very complex setup there is simply too much work to do each time you wish to test some feature. So many of your tests should be using some common setup, some expected platform on which to run. Quite often high-level feature tests can even be written by people who do not understand, and need not understand, everything involved in the setup process.
Test one thing will depend on the context. In a particular context, one thing is a tiny detail. In another context, one thing may be involving a large set of details.
One example could be testing the constructor of an object and verify that a certain field was set properly. Another example could be testing adding an order to sale system, adding an order might be one thing but will most likely involve an entire chain of objects that interact.
Whenever you feel that you want to call the test something that contains the word ‘and’, see it as a warning sign that you might not be testing one thing.
Stress testing a system without using repetitions might be challenging. I didn’t even think about stress testing when I wrote this blog. Maybe I should say that.
Hiding setup is also all about context and the abstraction level you currently are working on. If you are working on an integration test that need the entire database setup properly, you would probably want to work with an abstraction level that let you state setup database with one particular customer instead of explicit setting up each row in the database.
I agree in many parts of what you say, but it all depends on context and abstraction level.