-
Unit Testing (
ng test)- Unit Testing Guide
- Test runner: Karma (deprecated, migrating to Jest or Web Test Runner)
-
End-to-End Testing (
ng e2e) -
Comparison:
ng testvsng e2e- Unit Testing (
ng test)- Pros:
- Fast execution
- Isolates individual components
- Easier to debug
- Cons:
- Limited scope (doesn't test integration)
- May miss issues that only appear in a full application context
- Requires extensive mocking, especially for Angular services and dependencies
- Pros:
- End-to-End Testing (
ng e2e)- Note here that e2e in this context is specifically about
ng e2eand not the wider meaning of end-to-end testing. The main difference is the application is rendered to a browser as a user would use it. We will run these tests as part of CI. We will only mock the external dependencies like authentication and API calls. - Pros:
- Tests the entire application flow
- Catches integration issues
- Simulates real user interactions
- Easier to set up with tools like Playwright
- Cons:
- Slower execution
- More complex to maintain
- Harder to debug
- Note here that e2e in this context is specifically about
- Unit Testing (
-
Front-End Unit Testing Considerations
-
Should the DOM be included in unit tests?
- Pros:
- Ensures components render correctly
- Catches issues related to template bindings and directives
- Provides more realistic test scenarios
- Cons:
- Slower test execution
- Increased complexity in test setup
- Harder to isolate component logic from presentation
- Pros:
-
When to add tests:
- TDD: Write tests first, then implement features.
- For each task in Jira, update or delete tests as needed.
- When the component's scope is stable and unlikely to change significantly.
-
Building iteratively without full scope:
- Frequent test updates may be required.
- Initial tests might have incomplete coverage.
- Increased maintenance due to constant changes.
- Potential for redundant work on tests for features that change or are removed.
- Strategies:
- Incremental testing: Update tests as scope evolves.
- Modular design: Keep components decoupled.
- Communication: Stay updated with stakeholders.
- Flexible testing: Combine unit and end-to-end tests.
-
Focus unit tests on reasonably complex logic:
- Avoid writing tests for trivial code.
- Prioritize testing critical and complex parts of the application.
- Use end-to-end tests to cover broader application behavior.
-
-
Pragmatic Unit Testing Guidelines for the Front-End
- When to Write Unit Tests:
- Complex Business Logic: Test components or services with complex logic.
- Critical Functionality: Focus on critical parts of the application.
- Reusable Components: Ensure reusable components work in different contexts.
- Edge Cases: Cover likely edge cases that are hard to test manually.
- When to Skip Unit Tests:
- Simple Components: Skip tests for trivial components.
- Rapid Prototyping: Focus on features first, add tests later.
- Low-Risk Areas: Skip tests for low-risk, stable parts of the application.
- Balancing Unit and End-to-End Tests:
- Use unit tests for isolated logic and small components.
- Use end-to-end tests for user flows and integration points.
- Code Review Practices:
- Discuss the need for tests during code reviews.
- Focus on the value of tests rather than enforcing strict rules.
- Front-End vs. Back-End Unit Testing
- Front-End Unit Testing:
- Focuses on user interface components and interactions.
- Often requires mocking of services and dependencies.
- Tests may include DOM manipulation and rendering.
- More prone to changes due to evolving UI requirements.
- Back-End Unit Testing:
- Focuses on business logic, data processing, and APIs.
- Typically involves less mocking as dependencies are more stable.
- Tests are more stable and less likely to change frequently.
- Often easier to isolate logic without dealing with UI complexities.
- Different Rules for Front-End and Back-End:
- Front-end tests should prioritize critical and complex UI logic.
- Back-end tests should cover business logic and data integrity.
- Avoid enforcing the same testing rules for both; tailor strategies to the specific needs of each layer.
- Front-End Unit Testing:
- Additional Interesting Thoughts:
- TDD, Where Did It All Go Wrong (Ian Cooper): Even though this talk is about TDD and not specifically about the front end, the concepts are universal and it is a fantastic talk. Highly recommended.
- Kent C. Dodds – Write tests. Not too many. Mostly integration: Kent is a very well-known developer/educator mostly in the React world. He is also the creator of the Epic Web Stack.
- Grug on Testing: If you are not familiar with this legendary website, you should find a quiet afternoon and read the whole thing. It is hilarious and worth the time just for the laughs you are going to have.
- When to Write Unit Tests:
- Guidelines for Writing Unit Tests in Angular:
- Focus on Business Logic:
- Write unit tests for services and components that contain significant business logic.
- Ensure that critical calculations, data transformations, and decision-making processes are thoroughly tested.
- Test Reusable Components:
- Prioritize testing for components that are reused across the application.
- Verify that these components work correctly in different contexts and with various inputs.
- Mock Dependencies:
- Use Angular's testing utilities to mock services, HTTP calls, and other dependencies.
- Focus on testing the component's logic rather than the behavior of its dependencies.
- Avoid Over-Testing Simple Components:
- Skip unit tests for trivial components with minimal logic, such as simple display components.
- Rely on end-to-end tests to ensure these components render correctly within the application.
- Use TestBed for Complex Components:
- Utilize Angular's
TestBedto set up and configure the testing environment for complex components. - Include necessary declarations, providers, and imports to mimic the real application environment.
- Utilize Angular's
- Leverage Angular Testing Tools:
- Use tools like
JasmineandKarmafor writing and running unit tests. - Consider migrating to
JestorWeb Test Runnerfor improved performance and features.
- Use tools like
- Maintain Test Readability:
- Write clear and concise test cases that are easy to understand and maintain.
- Use descriptive names for test cases to indicate their purpose and expected outcome.
- Integrate Testing into CI/CD:
- Ensure that unit tests are part of the continuous integration and deployment pipeline.
- Run tests automatically on code changes to catch issues early in the development process.
- Preference for End-to-End Testing:
- Prioritize end-to-end tests for comprehensive coverage of user flows and integration points.
- Use unit tests selectively for critical and complex logic that cannot be effectively tested through end-to-end tests.
- Balance the use of both testing types to achieve thorough and efficient test coverage.
- End-to-end tests are more resilient to refactoring, as they focus on user interactions and overall application behavior rather than internal implementation details.
- Prefer Adding Tests When Reasonable:
- Add tests when they provide significant value in catching bugs or ensuring critical functionality.
- Avoid enforcing tests for every piece of code, especially trivial or low-risk areas.
- Encourage developers to use their judgment to determine when tests are necessary.
- Focus on Business Logic: