Writing just another best practice list about unit testing is easy, but working according these recommendations is a more difficult task. In the project described in Library to Empirically Estimate Big-O Time Efficiency and Check Results of Analysis in JUnit Tests with Java 8 the following tips have been used. All the source code in this project has been developed with 100% TDD and applied most of the best practices. Just 'Use Parameterized Tests' and 'Structure All Test Cases' has not been applied, because it was not needed.
The order of execution has to be independent between test cases. This gives you the chance to rearrange the test cases in clusters (e.g. short-, long-running) and retest single test cases.
Each test should focus on one aspect of an isolated method and/or class. For integration test this goal may be difficult to achieve, but also here trying to focus on single aspects is helping.
This means that you usually have just one assert per test case. More than one asserts are always a hit that your test doesn't focus on one aspect or functionality.
Don't test too many different things at once! If you use just one Assert it's easier. This increases the number of test cases and the single test better to maintain. If one or more tests fail, you may find the root cause in a easier way.
A clear naming convention like: <Method-Name Under Test>_<Scenario>_<Expected-Outcome>. This helps to avoid comments and increases the maintainability and in the case a test fails you know faster what functionality has been broken.
Use separated blocks ("ARRANGE", "ACT" and "ASSERT") help to improve maintainability and use comments to mark these blocks. An alternative is the ("given", "when" and "then") style. This gives more structure to your unit tests.
Maybe @Test(expected = ArithmeticException.class) doesn't test what it claims to test. Sometimes it happens that the exception is thrown some were else in your code (this happened to me some time ago).
Like Short-/Long-Running, Integration-/Unit-tests, but don't use test suits to control order of execution. When you have hundreds of test cases you don't like to wait several minutes till all tests are ready. Especially integration test may be slow, so separate them from the unit tests.
Describe the WHY and not the WHAT, not like Assert.assertEquals( a, b, "must be equal"). This helps to avoid to much comments in the test cases and increases the maintainability.
Best indicator to find out what is not tested, but don't be to sure that the code works.
Also maintain your test code (especially when after refactoring the code under test).
In some cases absolutely necessary, but with better design stubs should be enough.
They can help avoid code duplication and the best is the business gives you the data.