Unit Testing Apache Flex Applications Justin Mclean Class - - PowerPoint PPT Presentation

unit testing apache flex applications
SMART_READER_LITE
LIVE PREVIEW

Unit Testing Apache Flex Applications Justin Mclean Class - - PowerPoint PPT Presentation

Unit Testing Apache Flex Applications Justin Mclean Class Software Email: justin@classsoftware.com Twitter: @justinmclean Blog: http://blog.classsoftware.com Who am I? Programming for 25 years Developing and creating web


slide-1
SLIDE 1

Unit Testing Apache Flex
 Applications

Justin Mclean Class Software Email: justin@classsoftware.com Twitter: @justinmclean Blog: http://blog.classsoftware.com

slide-2
SLIDE 2

Who am I?

  • Programming for 25 years
  • Developing and creating web applications for

15 years

  • Apache Flex PMC, Incubator PMC, Apache

member

  • Release manager for Apache Flex, FlexUnit,

Tour De Flex, Squiggly

  • Run IoT meetup in Sydney Australia
slide-3
SLIDE 3

There are many factors that can contribute to software rot. The most important one seems to be the psychology, or culture, at work on a project. It's all too easy to slip into the mindset of "All the rest of this code is crap, I'll just follow suit.” Andy Hunt + David Thomas

Software Decays

slide-4
SLIDE 4

In the last 40 years we have written billions of lines

  • f code that will keep programmers employed for

trillions of man hours in the next few thousand years to clean up this mess we’ve made. Joe Armstrong

The Mess We’re In

slide-5
SLIDE 5

Teams take serious chances when they try to make large changes without tests. It is like doing aerial gymnastics without a net. It requires incredible skill and a clear understanding of what can happen at every step. Michael Feathers

Risk

slide-6
SLIDE 6

Code without tests is bad code. It doesn’t matter how well written it is; it doesn’t matter how pretty

  • r object-oriented or well-encapsulated it is. With

tests, we can change the behaviour of our code quickly and verifiably. Without them, we really don’t know if our code is getting better or worse Michael Feathers

Bad Code

slide-7
SLIDE 7

Refactoring

slide-8
SLIDE 8

Legacy Code

slide-9
SLIDE 9

Why Write Unit Tests?

  • Fast way to find bugs
  • Document code and share knowledge
  • Find regression issues
  • Quickly and confidently make changes
  • Speed up development
slide-10
SLIDE 10

Unit Tests vs Other Tests

  • Are fast to run (1/10 sec or less!)
  • Give consistent results
  • Are self checking
  • Show where errors are
  • Can be automated
slide-11
SLIDE 11

Not Unit Tests

  • Code that:
  • Makes network calls
  • Touches the file system
  • Queries a database
  • But still useful tests
  • Aim for 80%/20% split
slide-12
SLIDE 12

It is better to write and run incomplete tests than not to run complete tests. Martin Fowler

Start Small

slide-13
SLIDE 13

XUnit Style Tests

  • Multiple language and IDE support
  • One test class tests a unit (usually a class)
  • Setup and teardown methods
  • Multiple tests
  • Tests via asserts
slide-14
SLIDE 14

Apache FlexUnit

  • Based on JUnit 4
  • Donated to Apache by Digital Primates
  • Apache release 4.2 in April 2014
  • Stable and mature
  • Has IDE, ant and maven support
slide-15
SLIDE 15

Mustella

  • Used to test Flex SDK
  • Stable
  • Minor improvements since coming to Apache
  • Good for testing events and UI
slide-16
SLIDE 16

Differences from JUnit

  • A few extra bits - Fluent and Hamcrest
  • Takes care of the asynchronous nature of Flex
  • UI impersonators and Sequences
slide-17
SLIDE 17

Test Suites

  • Array of test cases to run
  • A way to organise groups of test cases
  • Can have multiple suites
  • IDE support
slide-18
SLIDE 18

Test Suite

public function currentRunTestSuite():Array { var testsToRun:Array = new Array(); testsToRun.push(tests.AppTests); testsToRun.push(tests.PeopleTests); testsToRun.push(tests.PersonDetailTests); testsToRun.push(tests.PersonTests); testsToRun.push(tests.SelectPersonTests); return testsToRun; }

slide-19
SLIDE 19

Basic Tests

  • Uses metadata to define tests
  • [Before] runs before test
  • [After] runs after test
  • [Test] defines a test to be run
slide-20
SLIDE 20

Basic Test

[Test]

public function checkPerson():void { assertTrue("Name is correct",
 person.name == "Justin Mclean"); assertTrue("Email is correct",
 person.email ==
 "justinmclean@apache.org"); assertTrue("ID is correct",
 person.apacheID == "jmclean"); }

slide-21
SLIDE 21

Testing Exceptions

  • Can test for exception via metadata
  • expects=[error thrown]
slide-22
SLIDE 22

Exception Test

[Test(expects="Error")] public function loadBadXML():void { people.loadXML("unknown.xml"); }

slide-23
SLIDE 23

Flex is Asynchronous

  • Loading XML, web service calls
  • Timers and events
  • UI Components
slide-24
SLIDE 24

Async Class

  • Used for testing asynchronous code
  • Static Methods:
  • proceedOnEvent
  • failOnEvent
  • handleEvent
slide-25
SLIDE 25

failOnEvent Test

[Test(async)] [Test(expects="Error")] public function loadBadXML():void { Async.failOnEvent(this, people,
 Event.COMPLETE, 1000); people.loadXML("unknown.xml"); }

slide-26
SLIDE 26

handleEvent Test

[Test(async)] public function loadXML():void { Async.handleEvent(this, people,
 Event.COMPLETE, xmlLoaded, 1000); people.loadXML(); }

slide-27
SLIDE 27

Testing loading XML

  • Setup()
  • Create instance
  • tearDown()
  • null instance
  • Asynchronous Test
  • [Test(async)]
  • proceedOnEvent or handleEvent
slide-28
SLIDE 28

SetUp

[Before] public function setUp():void { people = new People(false); }

slide-29
SLIDE 29

tearDown

[After] public function tearDown():void { people = null; }

slide-30
SLIDE 30

Async Test and Handler

[Test(async)] public function loadXML():void { Async.handleEvent(this, people, Event.COMPLETE,
 xmlLoaded, 1000); people.loadXML(); } public function xmlLoaded(event:Event, data:*):void { // Asserts go here }

slide-31
SLIDE 31

Testing UI and Data Binding

  • Setup()
  • Create instance and addChild on

UIImpersonator

  • tearDown()
  • removeChild and null instance
  • Test in normal way
slide-32
SLIDE 32

SetUp

[Before(async,ui)] public function setUp():void { … Async.proceedOnEvent(this, personDetails,
 FlexEvent.CREATION_COMPLETE, 100); UIImpersonator.addChild(personDetails); }

slide-33
SLIDE 33

tearDown

[After] public function tearDown():void { UIImpersonator.removeAllChildren(); personDetails = null; person = null; }

slide-34
SLIDE 34

Test

[Test] public function initialSelected():void { assertTrue("Name correct",
 personDetails.personName.text
 == "Justin Mclean"); assertTrue("Email correct",
 personDetails.email.text
 == "justinmclean@apache.org"); assertTrue("ApacheID correct",
 personDetails.apacheID.text == "jmclean"); }

slide-35
SLIDE 35

Testing Components

  • setup() and teardown() same as previous tests
  • Async timeouts and failure callbacks
  • Async handleEvent data passing
  • May need to create helper classes to simulate

user interactions

slide-36
SLIDE 36

SetUp

[Before(async,ui)] public function setUp():void { … Async.proceedOnEvent(this, selectPerson,
 FlexEvent.CREATION_COMPLETE, 100); UIImpersonator.addChild(selectPerson); }

slide-37
SLIDE 37

tearDown

[After] public function tearDown():void { UIImpersonator.removeAllChildren(); selectPerson = null; people = null; }

slide-38
SLIDE 38

Async Test and Handler

[Test(async,ui)] public function onChange():void { Async.handleEvent(this, selectPerson,
 PersonEvent.SELECT_PERSON, personSelected, 100); helper.changeList(selectPerson.persons, people[2]); } public function personSelected(event:PersonEvent,data:*):void { assertTrue("Event contains correct person",
 event.person == people[2]); }

slide-39
SLIDE 39

Sequences

  • Allow easy chaining of events together
  • Part of Fluint
  • Setup up a series of steps then run steps
  • Code easy to read - avoids nested callbacks
  • Debugging can be a little tricky
slide-40
SLIDE 40

Sequences

  • Create new SequenceRunner
  • Call addStep passing each step
  • Type of Steps include:
  • SequenceSetter
  • SequenceWaiter
  • SequenceEventDispatcher
  • SequenceCaller
slide-41
SLIDE 41

Sequences

var seq:SequenceRunner =
 new SequenceRunner(this); seq.addStep(new SequenceCaller(…)); seq.addStep(new SequenceWaiter(…)); seq.addStep(new SequenceCaller(…)); seq.addStep(new SequenceWaiter(…)); seq.run();

slide-42
SLIDE 42

Fluent

  • Provides all the Async functionality
  • Support for UI component testing
  • Sequences support
slide-43
SLIDE 43

Hamcrest

  • Allows matching of rules
  • More descriptive failure messages
slide-44
SLIDE 44

Matching Rules

[Test] public function testGreaterThan():void { assertThat(11, greaterThan(3)); } [Test] public function isItInHere():void { var array:Array =
 [ 'a', 'b', 'c', 'd', 'e', 'f' ]; assertThat(array, hasItems('b', 'c')); }

slide-45
SLIDE 45

Advanced Testing

  • Test coverage
  • Mocks and Spies
  • Parameterised testing
  • Theories
slide-46
SLIDE 46

Continuous Integration

  • Create ant build file using FlexUnit task
  • Test ant script
  • Setup in Jenkins
slide-47
SLIDE 47

Get Involved

  • Download and have a play give us feedback
  • Sign up and contribute to the mailing list
  • Look through JIRA there’s fair amount of

simple issues to fix

slide-48
SLIDE 48

Links

  • Apache Flex site


http://flex.apache.org

  • Apache Flex Unit


http://flex.apache.org/download-flexunit.html

  • Tutorial


http://flex.apache.org/flexunit/tutorial/

  • Further Information


https://cwiki.apache.org/confluence/display/FLEX/ FlexUnit

  • Apache Flex GitHub mirror


https://github.com/apache/flex-flexunit

slide-49
SLIDE 49

Ask now, see me after the session,
 follow me on twitter @justinmclean


  • r email me at justin@classsoftware.com.

Slides can be found at Conference Site. Code can be found at GitHub
 https://github.com/justinmclean/ ApacheConFlexExample

Questions?