Скачать презентацию Using x Unit as a Swiss-Army Testing Toolkit Скачать презентацию Using x Unit as a Swiss-Army Testing Toolkit

3b35e94dcd7f0b49a663407895d801b8.ppt

  • Количество слайдов: 31

Using x. Unit as a Swiss-Army Testing Toolkit (Does ‘Unit’ Size Matter? ) ACCU Using x. Unit as a Swiss-Army Testing Toolkit (Does ‘Unit’ Size Matter? ) ACCU Conference 2011 Chris Oldwood [email protected] co. uk

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

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

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

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

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

‘Unit’ Evolution All Regression System Component Unit Feedback Dependencies Integration ‘Unit’ Evolution All Regression System Component Unit Feedback Dependencies Integration

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

Test == Specification public void Execute_Should_Elide_Agreement_When_No_Trades_Match() { var trades = new List<Trade> { new 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 Preparation. Task(trades, agreement); var result = task. Execute(s_services); Assert. That(task. Agreement, Is. Null); }

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

Minimises Dependencies External Service File System Mock External Service Mock File System IExternal. Service Minimises Dependencies External Service File System Mock External Service Mock File System IExternal. Service IFile. System My. Service Database Mock Database IDatabase

Promotes Arbitrary Code Execution public void Prepare_Should_Elide_Agreement_When_No_Trades_Match() { var trades = new List<Trade> { 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 Preparation. Task(trades, agreement); var result = task. Execute(s_services); Assert. That(task. Agreement, Is. Null); } EXE Stub Debugger Test Runner Custom Test Harness Library. Tests

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

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

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

x. Unit Abuse • Fight the Shadow Cache • Invoke Tear. Down from Set. x. Unit Abuse • Fight the Shadow Cache • Invoke Tear. Down from Set. Up • Test/build failure isn’t absolute

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

File-System (Writing) • TEMP directory • Output directory File-System (Writing) • TEMP directory • Output directory

Database • • • Per-user / per-branch workspace Only need schema not data (Integration) 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

Database Asserts public void Add. Customer_Should_Persist_The_Customer () { const id = 1234; const name Database Asserts public void Add. Customer_Should_Persist_The_Customer () { const id = 1234; const name = "name"; var customer = new Customer(. . . ); using (var connection = Acquire. Connection()) { Customer. Data. Mapper. Add. Customer(customer , connection); Assert. That(Row. Exists("dbo. Customer ", " Customer. Id = {0}" + " AND Customer. Name = '{1}'", id, name), Is. True); } }

Database Set. Up/Tear. Down [Test. Fixture, Test. Category. Database. Test ] public class Some. Database Set. Up/Tear. Down [Test. Fixture, Test. Category. Database. Test ] public class Some. Entity. Tests : Database. Test. Base { [Test. Fixture. Set. Up] public void Fixture. Set. Up { using(var connection = Acquire. Connection()) { connection. Execute("insert into thingy_table values(1, 2, 3)"); connection. Execute("test. Insert. Thingy(1, 2, 3)"); } } [Test. Fixture. Tear. Down] public void Fixture. Tear. Down { using(var connection = Acquire. Connection()) { connection. Execute("delete from thingy_table"); connection. Execute("test. Delete. All. Thingys "); } } }

Helper Base Class public class Database. Test. Base { public ISql. Connection Acquire. Connection() Helper Base Class public class Database. Test. Base { public ISql. Connection Acquire. Connection() { return. . . }. . . public bool Row. Exists(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 = Acquire. Connection()) { var reader = connection. Execute. Query(sql ); return (reader. Get. Int("Count") == 1); } }. . . }

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

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

System Architecture Market Database Trade Data The System 42 Analytics Services System Architecture Market Database Trade Data The System 42 Analytics Services

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

Addressing External Risks External Market Data Service API External Trade Data Service API External 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

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

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

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

“The Oldwood Thing” http: //chrisoldwood. blogspot. com Chris Oldwood gort@cix. co. uk “The Oldwood Thing” http: //chrisoldwood. blogspot. com Chris Oldwood [email protected] co. uk