Presentation is loading. Please wait.

Presentation is loading. Please wait.

Using xUnit as a Swiss-Army Testing Toolkit (Does Unit Size Matter?) ACCU Conference 2011 Chris Oldwood

Similar presentations


Presentation on theme: "Using xUnit as a Swiss-Army Testing Toolkit (Does Unit Size Matter?) ACCU Conference 2011 Chris Oldwood"— Presentation transcript:

1 Using xUnit as a Swiss-Army Testing Toolkit (Does Unit Size Matter?) ACCU Conference 2011 Chris Oldwood

2 Stream of Consciousness Developer Driven Testing The Essence of (x)Unit Testing Those Pesky Dependencies Code & Test Evolution in Practice

3 Stream of Consciousness Developer Driven Testing The Essence of (x)Unit Testing Those Pesky Dependencies Code & Test Evolution in Practice

4 Text Book Test string[][] tests = { { "3", "4", "+", "7" }, { "9", "1", "-", "8" }, { "2", "3", "*", "6" }, { "9", "3", "/", "3" }, }; void run_tests() { var calculator = new Calculator(); foreach(var test in tests) { var lhs = test[0]; var rhs = test[1]; var op = test[2]; var result = calculator(lhs, rhs, op); assert(result == test[3]); }

5 Exercise Left for the Reader External System 1External System 2External System 3 The System 42 Services Database

6 Unit Integration System Component Stress Lexicon of Testing End-to-End Regression White Box Black Box Characterisation Exploration

7 System Integration Component Unit Dependencies Feedback Unit Evolution All Regression

8 Stream of Consciousness Developer Driven Testing The Essence of (x)Unit Testing Those Pesky Dependencies Code & Test Evolution in Practice

9 Test == Specification public void Execute_Should_Elide_Agreement_When_No_Trades_Match() { var trades = new List { new Trade("trade-id", "product-a") }; var agreement = new Agreement("product-b"); var task = new PreparationTask(trades, agreement); var result = task.Execute(s_services); Assert.That(task.Agreement, Is.Null); }

10 Consistent Style public void a_c_sharp_test() { var arrangement = new Arrangement(); var result = arrangement.action(); Assert.That(result, Is.EqualTo(expectation)); } create procedure a_sql_test as declare arrangement varchar(100), result varchar(100) exec = = result exec "expectation" go

11 Minimises Dependencies MyService External ServiceDatabaseFile System Mock External Service IExternalServiceIFileSystemIDatabase Mock File System Mock Database

12 Promotes Arbitrary Code Execution public void Prepare_Should_Elide_Agreement_When_No_Trades_Match() { var trades = new List { new Trade("trade-id", "product-a") }; var agreement = new Agreement("product-b"); var task = new PreparationTask(trades, agreement); var result = task.Execute(s_services); Assert.That(task.Agreement, Is.Null); } LibraryEXE Stub Test RunnerLibraryTestsDebugger Custom Test Harness

13 Automated Testing Lowers the barrier to running tests Regression testing is implicit Build server watches your back

14 Stream of Consciousness Developer Driven Testing The Essence of (x)Unit Testing Those Pesky Dependencies Code & Test Evolution in Practice

15 Pesky Dependencies External System 1External System 2External System 3 The System Service 2 Service 1 File-System Database

16 xUnit Abuse Fight the Shadow Cache Invoke TearDown from SetUp Test/build failure isnt absolute

17 File-System (Reading) Source Control directory Build server directory Resource files

18 File-System (Writing) TEMP directory Output directory

19 Database Per-user / per-branch workspace Only need schema not data (Integration) Can reuse existing unit test database Use same code revision for compatibility Use transactions to avoid residual effects Fake tables with CSV files

20 Database Asserts public void AddCustomer_Should_Persist_The_Customer() { const id = 1234; const name = "name"; var customer = new Customer(...); using (var connection = AcquireConnection()) { CustomerDataMapper.AddCustomer(customer, connection); Assert.That(RowExists("dbo.Customer", " CustomerId = {0}" + " AND CustomerName = '{1}'", id, name), Is.True); }

21 Database SetUp/TearDown [TestFixture, TestCategory.DatabaseTest] public class SomeEntityTests : DatabaseTestBase { [TestFixtureSetUp] public void FixtureSetUp { using(var connection = AcquireConnection()) { connection.Execute("insert into thingy_table values(1, 2, 3)"); connection.Execute("test.InsertThingy(1, 2, 3)"); } [TestFixtureTearDown] public void FixtureTearDown { using(var connection = AcquireConnection()) { connection.Execute("delete from thingy_table"); connection.Execute("test.DeleteAllThingys"); }

22 Helper Base Class public class DatabaseTestBase { public ISqlConnection AcquireConnection() { return... }... public bool RowExists(string table, string where, string params[]) { string filter = String.Format(where, params); string sql = String.Format( "select count(*) as [Count] from {0} where {1}", table, filter); using (var connection = AcquireConnection()) { var reader = connection.ExecuteQuery(sql); return (reader.GetInt("Count") == 1); }... }

23 External Systems Verify API behaviour Test internal façade Reliability varies (DEV vs PROD)

24 Stream of Consciousness Developer Driven Testing The Essence of (x)Unit Testing Those Pesky Dependencies Code & Test Evolution in Practice

25 System Architecture Market DataTrade DataAnalytics The System 42 Services Database

26 Initial System Test Market Data Service Trade Data Service Analytics Service Calculator Test Runner System Tests [Test, TestCategory.SystemTest] public void Calculate_Answer() {... var result = c.calculate(); Assert.Equal(result, 42); }

27 Addressing External Risks External Market Data Service API External Trade Data Service API External Market Data Service Tests External Trade Data Service Tests Test Runner

28 Internal Service Design External Service API External Service Tests Internal Service External Service Facade Internal Service Tests Mock External Services Performance Test Runner Mock Service

29 Data Access Layer Database Public Interface Database Unit Tests Data Access Layer Data Access Layer Tests Database API Mock Database API Mock Data Access Layer

30 Database Public Interface External Analytics Service External Market Data Service API External Market Data Service API System Evolution Mock Market Data Service Mock Trade Data Service Mock Analytics Service Calculator Test Runner Unit / Integration / System Tests [Test, TestCategory.SystemTest] public void Calc_Answer_For_ABC_Plc() {... var result = c.calculate(); Assert.Equal(result, 41.75); } Mock Data Access Layer Market Data Service Trade Data Service Analytics Service Data Access Layer

31 The Oldwood Thing Chris Oldwood


Download ppt "Using xUnit as a Swiss-Army Testing Toolkit (Does Unit Size Matter?) ACCU Conference 2011 Chris Oldwood"

Similar presentations


Ads by Google