Testing
Rainer Stropek | @rstropek
Introduction
Rainer Stropek
- Passionate software developers for 25+ years
- Microsoft MVP, Regional Director
- Trainer, Teacher, Mentor
- 💕 community
Tic Tac Toe
Let's build a (slightly over-engineered 😜) TicTacToe game and learn about unit testing strategies on the way.
Sample code is available on GitHub
Ubiquitous Language, Rules
- We play on a board
- A board consists of 3 x 3 squares
- The content of each square can be empty, X or O
- A game is played by two named players
- Player 1 starts and turns an empty square into X
- Player 2 follows and turns an empty square into O
- This is repeated until one player has three in a row, in a column, or in a diagonal line. This player is the winner.
- If there are no empty squares left and there is no winner, the game is a draw.
Learnings
- No unit testing without good requirements
- Tests should reflect requirements
- Ubiquitous language
- Acceptance criteria
- Developers shouldn't have to fill in the blanks
- Missing or unclear requirements lead to over-engineering
- Over-engineered code is hard to test
- Missing acceptance criteria, test data etc. is a productivity killer for deverlopers
Level 1: Project
Setup, Basic
Tests
Demo
Time!
Avoid Unnecessary Testing
- Use the full power of the C# compiler
- Don't ignore warnings
- Nullable references
- Code Analysis
- You don't need to write tests for errors that the compiler finds
- Check code on build servers, not just on your local machine
- Apply good coding practices to test code, too
- Avoid over-engineering (e.g. invent testing frameworks)
- Tests the tests: Write tests for complex testing code
Demo
Time!
House Rules
- Use descriptive names for tests classes and methods
- Remember: Use ubiquitous language
- Avoid inventing new terms and abbreviations
- Add documentation to clarify what each test verifies
- Remember: Code is more often read than written
- Unit tests must be fast!
- Remember: There are other test categories, too (e.g. integration tests, end-to-end tests, perf benchmarks, manual tests, etc.)
- Here: Focus on unit tests
Level 2: Writing
Tests With
xUnit
Demo
Time!
Tips
- Do not make members public to make them available to unit tests
- Prefer InternalsVisibleTo
- Use proper xUnit assertions
- Consider additional assertation libraries (e.g. Fluent Assertations)
- Use theories instead of facts where appropriate
- Generate demo data
- Consider generating services (e.g. https://mockaroo.com/) and NuGet packages (e.g. Bogus)
- Write tests for happy cases and error cases
- Validate exceptions, in particular for public members
- Check test coverage
- Built-in VS feature
- Coverlet, Fine Plugin
- Consider VS Live Unit Testing
Level3:
Fixtures, Mocking,
Integration Tests
Demo
Time!
Shared Test Context
- Initialize tests in constructor
- xUnit runs constructor for each test
- Cleanup (if necessary) in IDisposable
- Use Fixtures for sharing context across tests
Demo
Time!
Mock Objects
- Use interfaces or virtual methods for isolating workloads
- Here: IBoardContent
- Examples:
- Test logic, not dependencies between classes/modules
- Test logic without backing DB or cloud services
- Discuss: What is a unit in unit testing?
- Use a mocking framework (e.g. Moq)
Demo
Time!
Testing 🤘
Rainer Stropek | @rstropek
Unit Testing With xUnit and Moq
By Rainer Stropek
Unit Testing With xUnit and Moq
- 583