{"id":15598423,"url":"https://github.com/fluffynuts/tdd-101","last_synced_at":"2025-06-30T11:34:14.822Z","repository":{"id":66060582,"uuid":"239947660","full_name":"fluffynuts/tdd-101","owner":"fluffynuts","description":null,"archived":false,"fork":false,"pushed_at":"2022-01-19T15:08:26.000Z","size":253,"stargazers_count":2,"open_issues_count":0,"forks_count":7,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-02T10:43:53.561Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fluffynuts.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-02-12T07:02:00.000Z","updated_at":"2022-01-18T07:02:42.000Z","dependencies_parsed_at":null,"dependency_job_id":"97d04bdd-9de3-4fa4-8a7a-db5f8584bb7c","html_url":"https://github.com/fluffynuts/tdd-101","commit_stats":{"total_commits":19,"total_committers":1,"mean_commits":19.0,"dds":0.0,"last_synced_commit":"d2da98707ff2fd3d037f12356d5c1d14ce57e2f8"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/fluffynuts/tdd-101","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fluffynuts%2Ftdd-101","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fluffynuts%2Ftdd-101/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fluffynuts%2Ftdd-101/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fluffynuts%2Ftdd-101/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fluffynuts","download_url":"https://codeload.github.com/fluffynuts/tdd-101/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fluffynuts%2Ftdd-101/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262766090,"owners_count":23361031,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-03T01:39:36.306Z","updated_at":"2025-06-30T11:34:14.808Z","avatar_url":"https://github.com/fluffynuts.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# TDD 101\n(this document should be split up at some point)\n\n## Introduction\n### Summary:\n- What is TDD?\n- Why bother doing it?\n- The testing pyramid\n    - unit tests vs integration tests\n- The TDD cadence: Red, Green, Refactor\n- TDD \"gears\"\n    - low gear\n        - when you're new at TDD\n        - when the problem space isn't well known\n    - high gear\n        - when you know your way around quite well\n        - when the problem space is quite well known\n- Unit testing in .NET with NUnit\n    - Running tests\n        - Rider / Resharper\n        - Command line\n    - [TestFixture]\n    - [Test]\n    - [TestCase]\n    - [TestCaseSource]\n    - Setup and teardown\n    - [Ignore] vs [Explicit]\n\n[full notes](01-introduction.md)\n\nWorkshop: [DateTimeProvider](workshops/01-datetime-provider/readme.md)\n\n# Diving in\n- Anatomy of a “good test”\n    - descriptive name\n        - Given / When / Then\n    - SHOULD\n        - inspired by Javascript testing\n        - using sub-fixtures in NUnit\n    - Tells you exactly what broke when it fails\n    - A(V)AA\n        - Arrange\n            - set up everything required to have your test run\n        - Validate (optional)\n            - perform any initial validations that check that the test environment is\n                correctly set up\n        - Act\n            - perform the action to be tested\n            - ideally only one line\n        - Assert\n            - assert that the correct result was received / behavior was enacted\n            - ideally few asserts for a focused test\n            - if you find you're doing lots of asserts, rather copy/paste the\n                test and split the asserts up. Rename each variant with what is\n                _actually_ being tested\n    - Assertions\n        - NUnit Assert\n        - NExpect\n    - as few layers as possible (integration → unit)\n    - self-contained\n    - naming\n        - SUT\n        - variables which decide flow\n            - “customer1”, “customer2” vs “inactiveCustomer”, “activeCustomer”\n    - factory function to create SUT\n        - DRY\n        - future-proofing your tests\n\n[full notes](02-diving-in.md)\n\nWorkshop: [String Calculator](workshops/02-string-calculator/readme.md)\n\n## More advanced\n- Which tests are best? Integration or Unit?\n    - Strive towards unit test\n        - faster\n        - simpler\n        - more accurate errors\n    - Integration tests are also valuable\n        - still try to keep the scope as small as possible\n        - validate that code works against dependencies\n            - SQL engines\n            - File systems\n            - Remote APIs\n                - can be brittle\n                - mark with [Retry]\n                    - Only works on NUnit assertion failures!\n                - tag with a [Category]\n                - mark [Explicit(“with a reason why”)]\n    - Random values\n        - think less, test more\n        - free fuzzing\n        - what to do when tests fail\n            - random values are random: make sure the range of randomness is valid\n            - congratulations! perhaps you've found a bug in your production code?\n\n[full notes](03-more-advanced.md)\n\nWorkshop: [CRUD](workshops/03-crud/readme.md)\n\n## Testing more complex systems\n- Finding boundaries\n    - Interface all the things!\n- Gearing up\n    - Fakes, Mocks and Stubs\n        - what's the difference? does it really matter? (short answer: no; longer answer: chances are good you're mocking and stubbing at the same time, so, no.)\n            - more here: https://www.martinfowler.com/articles/mocksArentStubs.html\n        - why?\n        - substitutes with NSubstitute\n    - Test arenas\n        - when you have to set up a lot of stuff to get a test working\n        - prefer an arena over state in the test fixture\n            - prevents test interactions\n\n[full notes](04-testing-more-complex-systems.md)\n\nWorkshop: [WebApi Controller](workshops/04-webapi-controller/readme.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffluffynuts%2Ftdd-101","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffluffynuts%2Ftdd-101","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffluffynuts%2Ftdd-101/lists"}