What is test driven development? Starting a development by writing test and write the minimum amount of code to make the test pass. Automatated testing grows with the project and give feedback loop. Used on very large project and work pretty well. It makes live better.

write failing feature test
write minimal code
check if everything work and keep the right track
refactor the code, it makes you all time to make it clear.

TDD keeps make you forward and not distract by other things. Lot of people don't like to write test because its painful. We have too many tools, its even a nightmare sometimes.

Keep it simple. Only include what your test need and your program need. The minimum viable toolset by (re)using already existing framework. Next add new tools only if needed, if you feel pain during test development (e.g. model generator, test generator).

Make it easy to understand. We need to organize test files, based on filename conventions, matching the directory structure of the application. Page modules encapsulates interactions with the browser (Pages, forms, header). A function name must return a boolean for page module insertions.

Eliminate pain points. It is easy to break tests into multiple files. A file should focus on one single aspects of a test or a functions. You should avoid using monolith test case. Assertions are more than checks, assertions give you understandable errors, you can use intermediate assertions when you check list of properties.

Make it simple by using factories to build automatic/random data (e.g. ex_machina), factories can also act as documentation for the model. You should also reduce the dependencies about the data generated.

if you have complex scenario to configure, a good way to solve the problem is to use helpers functions, as a global one or just a local one.

Acceptance tests can be hard to understand, the solution is to write the test that tells the user's story and the way they will act. These tests can easily document the expected way of the user should use the application but also define the user experience.

Mix test has useful options, like --trace, --stale, or --only.

You should limit the use of setup blocks, if you use this, you will take long time to refator your tests.

You should use asynchronous (browser) testing. It is now easy to make those test in parallel and concurrently.