implementing tdd in for .net core applications
TRANSCRIPT
TDDTest Driven Development
What is TDD ?
Test Driven Development (First test programming) Is a software development process It’s actually an approach to design and develop testable code It’s base on short 5 step cycles
1-Start with writing unit tests. Unit tests are written based on Specs and Failure conditions (e.g. boundary conditions, potential exceptions, ...)
2-Run the unit tests and confirm that they fail 3-Then implement the actual methods to pass the tests 4-Run tests and confirm they pass 5-Refactor your code (Clean up the code, remove duplications …)
Why TDD?
Automated testing (saves a lot of time for assuring code’s health) Facilitates debugging (saves a lot of time in detecting problems) Protects the code from breaking changes Facilitates Continuous Integration (CI) and Delivery Improves the app design and quality of the code Forces developers to comply with SOLID design principles
Single Responsibility, Open-Closed, Liskov substitution, Interface Segregation, Dependency inversion
Types of Tests Unit test
A unit test is actually a class that tests another app component (another class) A unit test method Only tests a single unit of work (a method) There should be no dependency to Database, File, Network or any other I/O
resources whatsoever. Everything should happen in the memory So they should pass all the time, otherwise something’s wrong with code
Integration test It’s a class that tests combination of multiple units of work It’s OK to have dependencies to I/O resources So Configuration of dependencies (e.g. connection string) could result in test failure
Functional Test (a.k.a E2E test) Manual tests (QA’s Job) Automated E2E tests
Unit Testing
Unit test classes Unit Test Methods
3 main sections : Arrange Initialize values, fake dependencies Act Run the System under test (SUT), actually the Method under test Assert Check the return value or system status against expected values/criteria
Example
Arrange
ActAssert
Unit Test Tools
Tools for Running Tests and Asserting results Unit Test Frameworks :
Back-end (C#.net): MS Test, xUnit.net, NUnit, MbUnit, etc. Front-end (JS/AngularJS2): Jasmine, Chai, QUnit , etc.
Tools for faking dependencies Isolation Frameworks :
Back-end (C#.net): Moq, NSubstitute, MS Fakes (Moles), JustMock, TypeMock, Rhino Mocks
Front-end (JS): Jasmine, SinonJs
Back-end Unit Testing FrameworksFeature MS Test (v2) XUnit.net
(v2.x)NUnit (v3) MbUnit
DNX/.net Core Support YES YES YES but in next version’s RC
NO
Community No Open Source community
50 Contributors3 Active Devs1144 StarsPart of .NET Foundation
74 Contributors8 Active Devs763 Stars
WeakLatest update Oct 2014
VS Integration YES YES (Through plug-ins) YES (Through plug-ins) YES (Through plug-ins)
Supported by CI Tools TFS, VS Online, Team City, Jenkins
TeamCity, Jenkins, VS Online, TFS
TeamCity, Jenkins, VS Online, TFS
TFS
Parallel Execution Support YES (Per Test Class) – newly added
YES (Per Test Method) Yes (Per Test Class) NO
Extensible (Through Attribute Inheritance)
NO YES YES but limited and not documented yet
NO
Parameterized Test YES YES YES YES
Performance Supposed to be slower Faster (due to parallelism) Fast No comments found
Other • Not as active as the others and Slower in releasing new versions
• The most modern, Part of .NET Foundation
• More TDD adherence• 1 instance per test
method• Resharper integration• Prevents bad habits• .NET Core’s Default
• Widely used, currently de facto FW, Posted from Java
• Parameterized tests• 1 instance for all test
methods• Resharper integration• Well Documented
Seems to be dying!
The most popular frameworks in .NET landscape :
Types of Isolation Frameworks
Constrained Constrained to .net Compiler restrictions as they generate .net code and
compile it at runtime Can only mock public, non static members, no sealed classes
Unconstrained They use unmanaged APIs (Profiling APIs). They wrapped around the
running instance of CLR and are able to manipulate the way that managed code works
They can fake almost everything, private members, static members, and even 3rd party stuff
Back-end Isolation FrameworksMoq (4.x) NSubstitute MSFakes
(Moles) TypeMock FakeItEasy
Framework Type Constrained Constrained Unconstrained Unconstrained (Commercial)Constrained (Free)
Constrained
Needs profiling to be enabled
NO NO YES YES (Commercial)No (Free)
NO
Can fake 3rd Party systems
NO NO YES YES(Commercial)No (Free)
NO
.net Core Support YES YES YES Not Yet NO
Community 44 Contributors6 Active Contributors1460 Stars
31 Contributors5 Active Contributors696 Stars
Not Open source Not Open source 24 Contributor6 Active Contributors595
Notes • The most popular one
• More Readable
• Less readability
Only for 3rd Party Components99% of cases
Conclusion
Test runner/Framework for .net : XUnit.net .net Core Support, well adopted by community and being a part of .NET Foundation Forces testing best practices (through 1 instance per method approach) Good performance NUnit could be an option if we care about the abundance of resources
(Stackoverflow, blog articles, …) but XUnit.net is future proof Isolation Framework for .net : Moq (for 99% of cases), MSFakes (just for
mocking non-mockable 3rd party components) Moq is widely used, well documented and mature enough. MSFakes is the only free unconstrained FW among major players
Use FluentAssertions for better test readability
Final Points
For a real production code unit testing is a must, not just a choice What matters more than tools and frameworks we’re using, is writing
a well-designed testable code and being committed to testing. Watching Code Coverage and keeping it high Code and Test Review to prevent cutting corners and maintain the
test and code quality In the front-end we need to do unit testing as well. As it’s got UI logic
in it and exactly because of design and clean code concerns De facto libs for testing AngularJS apps are : Jasmine (Unit test FW) ,Karma (Test Runner), Protractor (code driven End-to-End automated test for AngularJS 2) runs on top of Selenium Webdriver