Testable code

1,531 views

Published on

Published in: Technology, Education
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,531
On SlideShare
0
From Embeds
0
Number of Embeds
210
Actions
Shares
0
Downloads
29
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide
  • 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

    1. 1. Designing Testable Codeby Bjorn Schultheiss Topic Presenter Designing Testable Code Bjorn Schultheiss
    2. 2. 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
    3. 3. Recent thoughts about Flash Topic Presenter Designing Testable Code Bjorn Schultheiss
    4. 4. Find your passion Topic Designing Testable Code Presenter Bjorn Schultheiss
    5. 5. 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
    6. 6. Sorry I’m busy dude Topic Designing Testable Code Presenter Bjorn Schultheiss
    7. 7. 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
    8. 8. 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
    9. 9. Topic PresenterDesigning Testable Code Bjorn Schultheiss
    10. 10. What are unit tests? Topic Presenter Designing Testable Code Bjorn Schultheiss
    11. 11. I knew you cowboys were here Topic Designing Testable Code Presenter Bjorn Schultheiss
    12. 12. • 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
    13. 13. The only good excuse not to be writing them is becauseyou don’t know how. Topic Presenter Designing Testable Code Bjorn Schultheiss
    14. 14. So what do i need to know? Topic Presenter Designing Testable Code Bjorn Schultheiss
    15. 15. 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
    16. 16. Procedural public class ImageEditor { public function crop(image:Bitmap, size:Rectangle):Bitmap { // do something } Topic Presenter Designing Testable Code Bjorn Schultheiss
    17. 17. 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
    18. 18. 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
    19. 19. Global Statea = new X() --> Topic Presenter Designing Testable Code Bjorn Schultheiss
    20. 20. Global State Ya = new X() --> Z X Q Topic Presenter Designing Testable Code Bjorn Schultheiss
    21. 21. Global State Ya = new X() --> Z X Qb = new X() --> Topic Presenter Designing Testable Code Bjorn Schultheiss
    22. 22. Global State Ya = new X() --> Z X Q Yb = new X() --> Z X Q Topic Presenter Designing Testable Code Bjorn Schultheiss
    23. 23. Global State Ya = new X() --> Za.doSomething(); X Q Yb = new X() --> Z X Q Topic Presenter Designing Testable Code Bjorn Schultheiss
    24. 24. Global State Ya = new X() --> Za.doSomething(); X Q Yb = new X() --> Zb.doSomething(); X Q Topic Presenter Designing Testable Code Bjorn Schultheiss
    25. 25. Global State Ya = new X() --> Za.doSomething(); X Qa == b Yb = new X() --> Zb.doSomething(); X Q Topic Presenter Designing Testable Code Bjorn Schultheiss
    26. 26. 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
    27. 27. Global State• Inconsistent results• Order of tests matter• Something the tester doesn’t control Topic Presenter Designing Testable Code Bjorn Schultheiss
    28. 28. Singletons Topic Presenter Designing Testable Code Bjorn Schultheiss
    29. 29. Singleton’s are pathological liars Topic Designing Testable Code Presenter Bjorn Schultheiss
    30. 30. Singletons• Singletons use global state Topic Presenter Designing Testable Code Bjorn Schultheiss
    31. 31. 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
    32. 32. Singletons• Singletons use global state• the test doesn’t control the instantion of the process Topic Presenter Designing Testable Code Bjorn Schultheiss
    33. 33. 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
    34. 34. Singletons• Singletons use global state• the test doesn’t control the instantion of the process• secret collaborators Topic Presenter Designing Testable Code Bjorn Schultheiss
    35. 35. 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
    36. 36. 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
    37. 37. Law of DemeterObject.getSomething.theProperty Topic Presenter Designing Testable Code Bjorn Schultheiss
    38. 38. Law of DemeterObject.getSomething.theProperty Topic Presenter Designing Testable Code Bjorn Schultheiss
    39. 39. Law of DemeterObject.getSomething.thePropertysomething.theProperty Topic Presenter Designing Testable Code Bjorn Schultheiss
    40. 40. Locator in action class House { public function House(locator:Locator) { // what needs to be mocked in test? } } Topic Presenter Designing Testable Code Bjorn Schultheiss
    41. 41. 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
    42. 42. 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
    43. 43. 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
    44. 44. Constructor vs Setter injection• An order of instantiation Topic Presenter Designing Testable Code Bjorn Schultheiss
    45. 45. 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
    46. 46. 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
    47. 47. 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
    48. 48. How does this relate to unittesting? Topic Presenter Designing Testable Code Bjorn Schultheiss
    49. 49. 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
    50. 50. If your class mixes Objectconstruction and logic you willnever be able to achieveisolation Topic Presenter Designing Testable Code Bjorn Schultheiss
    51. 51. 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
    52. 52. The end goal is to have classes with either logic or “new”operators Topic Presenter Designing Testable Code Bjorn Schultheiss
    53. 53. 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
    54. 54. 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
    55. 55. Construction example function build():House { return new House(new Kitchen( new Sink(), new Dishwasher(), new Refrigerator()) ); } Topic Presenter Designing Testable Code Bjorn Schultheiss
    56. 56. lets look at writing a unit test Topic Presenter Designing Testable Code Bjorn Schultheiss
    57. 57. 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
    58. 58. [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
    59. 59. Testing UI Components Topic Presenter Designing Testable Code Bjorn Schultheiss
    60. 60. Spare me Topic Designing Testable Code Presenter Bjorn Schultheiss
    61. 61. 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
    62. 62. [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
    63. 63. UI Codefendants• UIImpersonator• invalidationModel• [Async] proceedOnEvent()• displayList hierarchy Topic Presenter Designing Testable Code Bjorn Schultheiss
    64. 64. 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
    65. 65. 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
    66. 66. 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
    67. 67. Well on your way Topic Designing Testable Code Presenter Bjorn Schultheiss
    68. 68. Thanks, questions? Topic Presenter Designing Testable Code Bjorn Schultheiss

    ×