title: Road to efficient testing class: animation-fade layout: true
.bottom-bar[ {{title}} ]
class: impact cover
---
class: impact subcover
Unit tests are typically automated tests written and run by software developers to ensure that a section of an application (known as the "unit") meets its design and behaves as intended. (Wikipedia)--
Unit tests test individual units (modules, functions, classes) in isolation from the rest of the program. (Kent beck)--
The term "unit test" is unfortunate. A unit is a small element of structure. The TDD discipline causes us to write tests for small elements of behavior; not small elements of structure. So a test per class is inappropriate. (Robert C. Martin)---
- Fast
--
- Isolated
--
- Repeatable
--
- Self-validating
--
- Timely
--
https://howtodoinjava.com/best-practices/first-principles-for-good-tests/ --- # Test a behavior, not an implementation
???
- No mock (don't mock what you don't own)
- Protected methods are not tested directly
??? getSubscribedEvents: other events can be added, priorities can be added... Test should not break
- Code coverage is a tool. It should not be the goal. - Unit test low-complexity methods may be discussed. - @covers annotation can help to mark as covered only code that is actually tested.
> If your unit tests cover 100% of your code, you're doing it wrong. Just my 2 cts. (Fabien Potencier) ??? - Controllers should not be unit tested - Static analysis now replaces some basic tests --- # Change Risk Anti-Patterns (CRAP) index
![Crap index](img/crap.png)
https://opnsrce.github.io/how-to-read-and-improve-the-c-r-a-p-index-of-your-code --- class: impact subcover
- Database
- Filesystem
- ...
But fake objects can also be used (fake api client, fake mail server...) --- # Fixtures
- Faker / Alice fixtures (rely on Faker) / Doctrine fixtures
- In memory database (sqlite)/In memory filesystem (tmpfs)
- Transactions (Doctrine test bundle)
- Database dumps / Read only fixtures (but involves to have shared fixtures)
???
- Generating and loading fixtures are often the bottleneck
- Avoid to share fixtures: a common base is possible but the base should be stable
- Don't rely on auto-generated identifiers: generators are incremented even when the transaction is cancelled (mysql, postgres...).
class: impact subcover
--
- Think like an end-user, user stories and acceptance tests are a good points to start
--
- Keep in mind critical paths to test (risk-based testing)
--
- Test UI against stable elements (find by aria roles, labels)
--
- Given: set the application state, magic only happens here
--
- When: the user action
--
- Then: inspect the output of the system (UI) not something deeply buried inside (database state...)
- Mutation testing (Infection...)
-
Performance tests (Blackfire...)
-
Stress tests (Gatling...)
-
Visual tests (Phantomcss...)
class: impact subcover