Test Driven Development - In test driven development the software is written to a test, if the test fails then the software is either not complete or not correct. In TDD the programmer knows what the result of an action is supposed to be (store or retrieve user information, do a calculation, generate a report, etc.) so they write the test that says the success scenario is x. If they immediately run the test, the test will fail since no software has been written to pass the test. They then write the software to do what they want, and run the test, until the test passes when the produced software meets the requirements of the test. This is useful because at the end the programmer knows the software at least does what was planned from the start.
Abstraction principle (don't repeat yourself) - This principle relates to code only being written once and shared between objects, instead of repeating code to replicate functionality across multiple objects. If code is repeated and something needs to be changed, it means that everyplace the code is replicated will need to be updated and changed. This makes it very easy to fail to make all changes to every piece of software since one component could be missed. It also opens up the possibility for more mistakes, as the more code that needs to be changed the more likely it is that a mistake will be made and not noticed. All of this could result in code that doesn't compile properly, or software that doesn't work right either doing things incorrectly, or crashing and not really working at all. When code only exists in once place and is used for multiple components, it means that it only has to be updated once for everything to change.
Single responsibility principle - Under this principle an object should only be responsible for a single unit of work. If an object has multiple responsibilities they could negatively impact one another causing the software to fail. This is similar in a way to the abstraction principle, since a single responsibility makes the class more robust as it can be applied whenever it's singular function would be useful. With multiple responsibilities a class may do too much to be useful in a certain situation, another class would have to be created. Furthermore if there are two responsibilities and one of them needs to be updated or changed, this could cause the other task to no longer work either correctly or at al.
Separation of concerns - Not entirely distinct from SRP and DRY, SoC is where a computer program is broken up into specific features while attempting to minimize any overlap in functionality. This makes it easier for work to be done on individual pieces of the system, helps with re-usability and maintainability, improves understanding of the system, and makes it easier for new features to be added in the future.