Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
assertYourself - Breaking the Theories and Assumptions of Unit Testing in Flex
1. assertYourself()
Breaking All of the Theories and Assumptions of
Unit Testing in Flex
Michael Labriola
Jeff Tapper
Digital Primates
2. Who are you?
Michael Labriola
Senior Consultant at Digital Primates
Jeff Tapper
Senior Consultant at Digital Primates
Flex Geeks - Team Mentors
Fans of Working Code
3. What is this session about?
Automated Testing.
However, because we expect a mix of people at
different levels of commitment to the idea of
testing we need to cover a few major areas
4. Topics I
Why Test Code – If you don’t know why this
matters, you aren’t really going to care about
the rest
Writing Testable Code – 99% of writing good tests
is good architecture.
5. Topics II
Writing Unit Tests – How do you go about writing
and executing unit tests
Introducing Theories and DataPoints – verifying
functionality over a larger set of values
Writing Integration Tests – Integrate your units
and let the real fun begin
6. The sad facts
Software Errors cost a lot of money and time
• A 2002 NIST study found that software errors cost
the US economy .6% of the US GDP yearly[1]
• That sets the net loss today at about 79.8 billion
dollars a year
Who pays that?
• Half of that is absorbed by people who buy software
• The other half is absorbed by people who create
software
7. More sad facts
Software errors are also the majority of development
cost
• The same study found that, on average, 80% of
development costs are spent on identifying and
correcting defects
• So, the majority of the development time is spent
creating software that still causes almost 80 billion in
issues
8. The important part
The cost of fixing these errors is correlated to when
they are found[2]
• A requirements error found after release can cost 10
– 100 times as much to fix as during the
requirements gathering phase
• An architecture error found after release can cost 25-
100 times as much to fix this late in the process
• The point.. Finding issues early == good. Finding
issues late == bad.
9. Why Test Automatically?
It allows us to test much more often than we could do so
manually
• There are only so many hours in the day.
• Code that hasn’t been exercised in a while is always
suspect
• When you’re tired, do you test as effectively?
Computers tend not to get tired.
10. Why Test Automatically?
It is cheaper than hiring teams of QA folks (or spending
your time) to execute manual tests continually
• Automated tests cost money to write and money to
maintain, however, once a test is written, you can run
it forever for a near zero cost.
• Manual testing which costs little in the beginning, but
re-occurs every time you wish to test
11. Why Test Automatically?
It reduces the time to find and quash bugs
• Automated tests can run continuously
– When you create a new bug, it is likely to be caught in a very
short period of time.
– When you have context, you fix issues more quickly
– The longer you wait to resolve a bug, the more likely it is that
more code will need to be touched
12. Why Test Automatically?
It allows you to change and rewrite code without fear of
breaking something else
• How do you know that a seemingly innocuous change in
a piece of code today doesn’t have repercussions in
some rarely run portion of the project?
• With sufficient tests you can change code and sleep
better
13. Why Test Automatically?
It increases the quality of the software you write
• If you write tests for your code, you tend to ensure the
architecture can support testing… generally that also
means you architected it at least mostly okay
• Code with a lot of automated tests will have been
tested thousands of times in the course of development
• Bugs will still exist, but they are less likely to be
fundamental and immediately noticeable
14. Last but not..
We appear to be more effective developers
When you deliver solid code that works the first time you
are perceived as effective
15. Types of Testing
Unit
• Taking the smallest piece of code, isolated from any
other factors and determining if it behaves as you
expect.
Integration
• Assembling already tested units and ensuring the
behavior and interaction between those units are
correct.
16. More Testing
Functional
• Translating functional requirements of an application
into test cases, which can be run to ensure
requirements have been met.
A million or so more varieties
• Performance, acceptance, etc., etc.
17. Coding for Testing
This is most of the battle. If you write code that follows these
general architectural principals, testing it is viable and less
stressful.
If you don’t, well, good luck
18. Coding for Testing
Separate construction and application logic
protected function doSomeStuffWithSomeClass():void {
//does stuff
var x:SomeClass = new SomeClass();
//does more stuff
}
protected function doSomeStuffWithSomeClass(
someClass:SomeClass ):void {
//does stuff
//does more stuff
}
19. Coding for Testing
Use interfaces!
protected function positionThing(
component:UIComponent ):void {
}
protected function positionThing(
component:IUIComponent ):void {
}
20. Coding for Testing
Don’t reach through another object for its
properties
protected function doThing():void {
someObject.someProperty.someObj.method();
}
21. Coding for Testing
Avoid global state in things you wish to test
protected function doThing():void {
addValue( mySingleton.getInstance().firstVal );
}
22. Coding for Testing
New objects made through composition are easier
than those created through inheritance
Composed objects can be substituted with
different composition at runtime. You can’t
change your parents.
23. Coding for Testing
Separate concerns
Classes which need the word *and* to explain
them are hard to test
public function
createObjectsAndPositionThem():void;
24. Writing Unit Tests
What methods/classes should you write unit tests
for?
• Anything that could possibly break
• Any method that can’t be verified by simple inspection
When writing tests you are either checking a
return value or looking for a side-effects
created by a method.
– If a method doesn’t do either, what in the world does it do?
25. Fakes, Stubs and Mocks
A unit test needs to test an isolated unit. Fakes,
stubs and mocks are techniques for isolating
the unit under test.
For our purposes Fake object, stub and mock
objects are objects that are instantiated
instead of real implementations when an object
under test expects to interact with other
objects.
26. Fakes, Stubs and Mocks
Fakes and stubs are generally dumb objects which
may respond or fulfill the requirement but do
little else.
Mock objects allow you to set expectations of
how they will be ‘touched’ during the test and
then make assertions based on those
expectations
27. Theories and DataPoints
What happens when we might need to write a
test over a potentially infinite dataset of
possibilities?
What if you need to test objects in multiple
states with different data points?
28. Integration Tests
You have diligently tested all of the units you
could; now how do you test them together?
Integration tests are less likely to use mocks, and
more likely to test all real units involved
29. Integration Tests
In the simplest case, things look just like unit
tests, call some methods, do assertions.
In more complicated situations, you may need to
deal with asynchronous aspects
In even more complicated situations, you may
need to do a fair amount of setup to get to the
point needing a test
31. Play and Vote
Take a look at the latest beta bits:
http://opensource.adobe.com/wiki/display/flexunit/FlexUnit
If you think the new features are important to your
workflow, let Adobe know:
https://bugs.adobe.com/jira/browse/FB-18873