• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Testable code
 

Testable code

on

  • 1,352 views

 

Statistics

Views

Total Views
1,352
Views on SlideShare
1,143
Embed Views
209

Actions

Likes
1
Downloads
6
Comments
0

1 Embed 209

http://focuslikealaser.com 209

Accessibility

Categories

Upload Details

Uploaded via as Apple Keynote

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • I want to talk about future development opportunities for the adbuilder,\nmore premium engaging forms of advertising, and how to use html as an\noption for ad deployment.\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • - doesnt interact with class data\n- users passed in to method\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n

Testable code Testable code Presentation Transcript

  • Designing Testable Codeby Bjorn Schultheiss Topic Presenter Designing Testable Code Bjorn Schultheiss
  • Who am I?Bjorn SchultheissDeveloperAdslotFront end developerFlash, Flex and now even some JavascriptLarge projects including http://www.adchamp.com Topic Presenter Designing Testable Code Bjorn Schultheiss
  • Recent thoughts about Flash Topic Presenter Designing Testable Code Bjorn Schultheiss
  • Find your passion Topic Designing Testable Code Presenter Bjorn Schultheiss
  • Testable code you sayThis presentation will cover • How to look at OO • Static methods and Global State • Separation of object construction and logic • Constructor Injection vs Setter Injection • Presentation Model Topic Presenter Designing Testable Code Bjorn Schultheiss
  • Sorry I’m busy dude Topic Designing Testable Code Presenter Bjorn Schultheiss
  • And why would I be interested?This presentation is targeted at • Any developer creating heavy client side applications • Focused specifically on Flex but the same principals apply to other web languages and frameworks • you love that feeling from watching a test pass Topic Presenter Designing Testable Code Bjorn Schultheiss
  • Tell me about Flex UnitThis talk is not about Flexunit • Flex developer’s best friend • Created by the community • Endorsed by Adobe (integrated in FB) • Easy to get started with Topic Presenter Designing Testable Code Bjorn Schultheiss
  • Topic PresenterDesigning Testable Code Bjorn Schultheiss
  • What are unit tests? Topic Presenter Designing Testable Code Bjorn Schultheiss
  • I knew you cowboys were here Topic Designing Testable Code Presenter Bjorn Schultheiss
  • • They are written by software engineers, not test engineers.• They are better written as you code, not after you’ve finished Topic Presenter Designing Testable Code Bjorn Schultheiss
  • The only good excuse not to be writing them is becauseyou don’t know how. Topic Presenter Designing Testable Code Bjorn Schultheiss
  • So what do i need to know? Topic Presenter Designing Testable Code Bjorn Schultheiss
  • How to think about OO• OO is about the relationship between data and code• data represents the state of an object• code modifies that state Topic Presenter Designing Testable Code Bjorn Schultheiss
  • Procedural public class ImageEditor { public function crop(image:Bitmap, size:Rectangle):Bitmap { // do something } Topic Presenter Designing Testable Code Bjorn Schultheiss
  • Better public class ImageEditor { private var _image:Bitmap; public function ImageEditor(image:Bitmap) { _image = image; } public function crop(size:Rectangle):void { // do something } } Topic Presenter Designing Testable Code Bjorn Schultheiss
  • Global State• Object state is subject to garbage collection• Global state is subject to life of the session Topic Presenter Designing Testable Code Bjorn Schultheiss
  • Global Statea = new X() --> Topic Presenter Designing Testable Code Bjorn Schultheiss
  • Global State Ya = new X() --> Z X Q Topic Presenter Designing Testable Code Bjorn Schultheiss
  • Global State Ya = new X() --> Z X Qb = new X() --> Topic Presenter Designing Testable Code Bjorn Schultheiss
  • Global State Ya = new X() --> Z X Q Yb = new X() --> Z X Q Topic Presenter Designing Testable Code Bjorn Schultheiss
  • Global State Ya = new X() --> Za.doSomething(); X Q Yb = new X() --> Z X Q Topic Presenter Designing Testable Code Bjorn Schultheiss
  • Global State Ya = new X() --> Za.doSomething(); X Q Yb = new X() --> Zb.doSomething(); X Q Topic Presenter Designing Testable Code Bjorn Schultheiss
  • Global State Ya = new X() --> Za.doSomething(); X Qa == b Yb = new X() --> Zb.doSomething(); X Q Topic Presenter Designing Testable Code Bjorn Schultheiss
  • Global State Ya = new X() --> Za.doSomething(); X Q GSa == b Yb = new X() --> Zb.doSomething(); X Q Topic Presenter Designing Testable Code Bjorn Schultheiss
  • Global State• Inconsistent results• Order of tests matter• Something the tester doesn’t control Topic Presenter Designing Testable Code Bjorn Schultheiss
  • Singletons Topic Presenter Designing Testable Code Bjorn Schultheiss
  • Singleton’s are pathological liars Topic Designing Testable Code Presenter Bjorn Schultheiss
  • Singletons• Singletons use global state Topic Presenter Designing Testable Code Bjorn Schultheiss
  • package{ public class AppSettings { private static const _instance:AppSettings = new AppSettings(Lock); private var _state1:Object; private var _state2:Object; private var _state3:Object; public static function get instance():AppSettings { return _instance; } public function AppSettings(lock:Class) { if (lock!=Lock) throw new Error("cannot unlock"); } }}internal class Lock {} Topic Presenter Designing Testable Code Bjorn Schultheiss
  • Singletons• Singletons use global state• the test doesn’t control the instantion of the process Topic Presenter Designing Testable Code Bjorn Schultheiss
  • package{ public class AppSettings { private static const _instance:AppSettings = new AppSettings(Lock); private var _state1:Object; private var _state2:Object; private var _state3:Object; public static function get instance():AppSettings { return _instance; } public function AppSettings(lock:Class) { if (lock!=Lock) throw new Error("cannot unlock"); } }}internal class Lock {} Topic Presenter Designing Testable Code Bjorn Schultheiss
  • Singletons• Singletons use global state• the test doesn’t control the instantion of the process• secret collaborators Topic Presenter Designing Testable Code Bjorn Schultheiss
  • public class CreditCard { private var _gateway:PaymentGateway; public function CreditCard() { gateway = ServiceLocator.getInstance().gateway; } public function chargeCard(value:Number):void { gateway.performTransaction(value); } } var cc:CreditCard = new CreditCard(); cc.chargeCard(10); Topic Presenter Designing Testable Code Bjorn Schultheiss
  • Singletons• Singletons use global state• the test doesn’t control the instantion of the process• secret collaborators• you may know the dependencies, but anyone that comes after you is baffled! Topic Presenter Designing Testable Code Bjorn Schultheiss
  • Law of DemeterObject.getSomething.theProperty Topic Presenter Designing Testable Code Bjorn Schultheiss
  • Law of DemeterObject.getSomething.theProperty Topic Presenter Designing Testable Code Bjorn Schultheiss
  • Law of DemeterObject.getSomething.thePropertysomething.theProperty Topic Presenter Designing Testable Code Bjorn Schultheiss
  • Locator in action class House { public function House(locator:Locator) { // what needs to be mocked in test? } } Topic Presenter Designing Testable Code Bjorn Schultheiss
  • Use revealed class House { private var _door:Door; private var _roof:Roof; private var _window:Window public function House(locator:Locator) { API gave us _door = locator.getDoor(); _roof = locator.getRoof(); no help _window = locator.getWindow(); } } Topic Presenter Designing Testable Code Bjorn Schultheiss
  • An API that helps class House { private var _door:Door; private var _roof:Roof; private var _window:Window public function House(door:Door, roof:Roof, window:Window) { _door = door; _roof = roof; _window = window; } } Topic Presenter Designing Testable Code Bjorn Schultheiss
  • Similar Anti-PatternsI didn’t ask for that!! • aka Locator • aka Context • aka Manager • Hides true dependencies • Breaks law of demeter Topic Presenter Designing Testable Code Bjorn Schultheiss
  • Constructor vs Setter injection• An order of instantiation Topic Presenter Designing Testable Code Bjorn Schultheiss
  • Setter example<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark"> <fx:Script> <![CDATA[ import mx.collections.ArrayCollection; import mx.collections.IList; import mx.rpc.AsyncToken; public var userService:Service; public function findUsers():void { userService.findAll(); userService.addEventListener("onResult", onResult); } public function onResult(result:Object):void { users.dataprovider = new ArrayCollection(result); } ]]> </fx:Script> <s:Button label="find all users" click="findUsers();" /> <s:List id="users" /></s:Group> Topic Presenter Designing Testable Code Bjorn Schultheiss
  • Constructor example public class ShowUserModel { [Bindable] public var users:IList; private var _service:Service; public function ShowUserModel(service:Service) { _service = service; _service.addEventListener("onResult", onResult); } public function findUsers():void { _service.findAll(); } private function onResult(result:Object):void { users = new ArrayCollection(result); } } Topic Presenter Designing Testable Code Bjorn Schultheiss
  • Instantiation example [Test] public function testShowUsersComponent():void { var service:Service = new Service("Users"); var component:ShowUsersComponent = new ShowUsersComponent(); component.service = service; component.findUsers(); } [Test] public function testShowUsersModel():void { var service:Service = new Service("Users"); var model:ShowUsersModel = new ShowUsersModel(service); model.findUsers(); } Topic Presenter Designing Testable Code Bjorn Schultheiss
  • How does this relate to unittesting? Topic Presenter Designing Testable Code Bjorn Schultheiss
  • How does this relate to unittesting? Unit testing as the name implies you test a Class (unit) in isolation Topic Presenter Designing Testable Code Bjorn Schultheiss
  • If your class mixes Objectconstruction and logic you willnever be able to achieveisolation Topic Presenter Designing Testable Code Bjorn Schultheiss
  • In order to unit test you need to separate yourobject graph construction from the logic into 2 different classes Topic Presenter Designing Testable Code Bjorn Schultheiss
  • The end goal is to have classes with either logic or “new”operators Topic Presenter Designing Testable Code Bjorn Schultheiss
  • Construction and logic mixed public class House { private var _kitchen:Kitchen = new Kitchen(); private var _isLocked:Boolean; public function get isLocked():Boolean { return _isLocked; } public function lock() { _kitchen.lock(); _isLocked = true; } } Topic Presenter Designing Testable Code Bjorn Schultheiss
  • Injection example public class House { private var _kitchen:Kitchen; private var _isLocked:Boolean; public function House(kitchen:Kitchen) { _kitchen = kitchen; } public function get isLocked():Boolean { return _isLocked; } public function lock() { _kitchen.lock(); _isLocked = true; } } Topic Presenter Designing Testable Code Bjorn Schultheiss
  • Construction example function build():House { return new House(new Kitchen( new Sink(), new Dishwasher(), new Refrigerator()) ); } Topic Presenter Designing Testable Code Bjorn Schultheiss
  • lets look at writing a unit test Topic Presenter Designing Testable Code Bjorn Schultheiss
  • Writing a unit testto test a method first you need to instantiate an object • Specifically the class or component to be tested • Any collaborators (real or mock). Topic Presenter Designing Testable Code Bjorn Schultheiss
  • [Test] public function testHouse():void { var kitchen:Kitchen = new Kitchen(); var house:House = new House(kitchen); house.testMethod(); } Topic Presenter Designing Testable Code Bjorn Schultheiss
  • Testing UI Components Topic Presenter Designing Testable Code Bjorn Schultheiss
  • Spare me Topic Designing Testable Code Presenter Bjorn Schultheiss
  • Testing UI ComponentsPossible but generally a pain, why? • test a style is applied • mimic user interaction • logic is is mixed with view Topic Presenter Designing Testable Code Bjorn Schultheiss
  • [Before(async,ui)]public function setUp() : void{ myButton = new MyButton(); Async.proceedOnEvent( this, myButton, FlexEvent.CREATION_COMPLETE, 100 ); UIImpersonator.addChild( myButton );}  [Test(async,ui)]public function myButton_myStyle_defaultValue() : void{ Assert.assertEquals( myButton.getStyle( "myStyle" ), "expectedDefaultValue" );} Topic Presenter Designing Testable Code Bjorn Schultheiss
  • UI Codefendants• UIImpersonator• invalidationModel• [Async] proceedOnEvent()• displayList hierarchy Topic Presenter Designing Testable Code Bjorn Schultheiss
  • Presentation Modelshttp://martinfowler.com/eaaDev/PresentationModel.htmlRepresent the state and behaviour of the presentation independently of the GUI controlsused in the interface • uses Binding to interact with view • also handles events from view • a pattern used in popular frameworks • great for unit testing Topic Presenter Designing Testable Code Bjorn Schultheiss
  • Presentation Model example<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"> package presentation <fx:Script> { <![CDATA[ [Bindable] import presentation.HelloWorldModel; public class HelloWorldModel [Bindable] { public var model:HelloWorldModel; public var label:String = "Hello"; ]]> </fx:Script> public function clickHandler():void <s:Label text="{ model.label }" {click="model.clickHandler();" /> trace("Is it me your looking for?");</s:Group> } } } Topic Presenter Designing Testable Code Bjorn Schultheiss
  • Business logic and PM’sLeave me out of it! • Presentation Models and Views have a 1 to 1 relationship • Business logic is best separated from PM’s • PM’s know about Business/Application classes, those classes know nothing about PM’s Topic Presenter Designing Testable Code Bjorn Schultheiss
  • Well on your way Topic Designing Testable Code Presenter Bjorn Schultheiss
  • Thanks, questions? Topic Presenter Designing Testable Code Bjorn Schultheiss