Unit Testing
-
Upload
francois-camus -
Category
Technology
-
view
484 -
download
1
description
Transcript of Unit Testing
Unit Testing
François Camus
Advantages
Quick feedback loop Run all tests to know if something is broken
Less need to run application to debug production code Can debug from test method instead
Provides confidence Refactoring Releasing more often
Documents production code behaviour Serves as production code safety net Avoids Change And Pray syndrome (CPD)
Test Project Contains tests for a specific project Naming convention
To avoid confusion e.g. when browsing files e.g. when having lots of tabs
Library namespace e.g. OpenControl.Web.Mappers
Library Test Project namespace e.g. OpenControl.Web.Mappers.Tests
Test Class name e.g. ModelMapperTests
Test project to follow same structure as project being tested
Unit Testing frameworks Microsoft Test framework NUnit xUnit.net http://
xunit.codeplex.com/wikipage?title=Comparisons
Test Execution Lifecycle Initialization (before each test execution)
initialises dependencies and fields that are common to many tests
no setup here: each test does its own setup Easier to maintain test code Don’t want spaghetti test code all depending on a common setup
method Execution
Does local test setup Calls method to test passing parameters and storing result
if any Asserts something on result or behaviour
Cleanup (after each test execution) Dispose of initialized dependencies
Test Class initialisation and cleanup Usually used by custom testing framework
e.g. Tester base class containing test helpers Initialises before first test execution Cleans up after last test execution
Test method naming convention[Fact]
public void Method_Condition_Result() {}
1.Method being tested2.Condition to meet test result (optional)3.Test result
[Fact]
public void GetData_DataExists_ReturnsData() {}
Test method structure AAA: Arrange/Act/Assert
1. Arrange: local test setup2. Act: calls method to test3. Assert: asserts result or behaviour
Common structure to all tests Easier for other developers to maintain code Helpful when doing Test Driven Development
Interaction based Unit Testing Asserting expectation on method Couples to internal implementation Less flexible to do refactoring
Leads to fragile tests Easier when starting unit testing Unavoidable
Need them when unable to only test result e.g Testing that a void method was called
About 10% of tests http://programmaticallyspeaking.com/?p=713
State based Unit Testing Tests method result rather than expectation Easier to maintain
Only local test setup may need amendment Preferred form of unit testing
Testing internals Add attribute to production code assembly
info to make internals visible to specific library
[assembly: InternalsVisibleTo("OpenControl.ClassLibrary.Tests")]
http://ayende.com/Wiki/Rhino+Mocks+-+Internal+Methods.ashx
One assert per test Atomic Easier to understand Easier to maintain When refactoring production code, you get
better feedback on what breaks
Dependency Injection Constructor parameter injection Property injection
Mocking Mocking frameworks (all based on Castle Dynamic Proxy)
http://www.castleproject.org/projects/dynamicproxy/ Add attribute to production code assembly info:
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
NSubstitute Shorter but awkward syntax Less lambda so changing developers’ habits
Rhino Mocks Too big (“Does the coffee !” Manu) Confusion for new users on which syntax to use
Latest syntax is following state based unit testing approach But old syntax remains
Large community Moq
Smaller and simpler Large community
http://code.google.com/p/moq/wiki/QuickStart
Tools Test Driven .Net (visual studio extension)
Works with xUnit.net (may need to run xunit installer to add support to Test Driven .Net)
ReSharper... Jenkins
After build runs tests via plugin (xUnit plugin...) Need to upgrade Jenkins to support .NET 4+
Conclusion Questions ? TDD next time