Home  >  

5 Tips For Flash Unit Testing

Author photo
November 9, 2009 | | Comments (3)
AddThis Social Bookmark Button
aft_logo.jpg

Advanced Flash Tactics or AFTs are techniques that come from deep within the Flash Art Of War, the oldest Flash military treatise in the world. In this AFT I will go over - 5 Tips for Unit Testing. Unit Testing and Test Driven Development are a hot topics in the Flash community lately, especially on Twitter. A few weeks ago, after realizing how complex my F*CSS library was getting, I decided to go back and write FlexUnit test for the library in a hope to use TDD moving forward. Lets quickly talk about what TDD is:

Test-driven development (TDD) is a software development technique that relies on the repetition of a very short development cycle: First the developer writes a failing automated test case that defines a desired improvement or new function, then produces code to pass that test and finally refactors the new code to acceptable standards. Kent Beck, who is credited with having developed or 'rediscovered' the technique, stated in 2003 that TDD encourages simple designs and inspires confidence. - wikipedia

Now that we have that out of the way, allow me to share what I've learned while creating unit tests for F*CSS and how I began moving towards implementing TDD into my workflow.

Tip 1: Test Before You Code!!!!

I started writing my unit tests after I had a good part of my F*CSS code base up and running. I knew unit testing was the next logical step because it was becoming harder for me add/modify code without fear of breaking something else. Once I committed to testing, I stopped all development and went through each class, method by method, writing my tests. Once everything was looking good I went back to coding, paused to write a test and made sure it didn't break anything, then code and repeat. Little did I know I was making a fatal mistake.

When I started, I felt that if I began testing before I coded I would be bogged down in the test and not as productive on the coding side of things. Up until a few days ago I was actually planning on writing that I was having a good time with this processes, writing code first and testing after, even though it didn't follow the TDD definition. What changed my mind?

I noticed a small bug in the way F*CSS was caching styles. After I fixed the cache bug I noticed several of my tests were failing. This led me to believe that my cache fix was the cause of the problem so I started going through the parser line by line. At the end of my code audit I realized my fix for the cache was correct so my failing tests were actually lying; something that test shouldn't do. Sure enough, I had writing my test on code that had a bug in it so the test only passed when the bug was present.

When it came to fixing the problem, my first instinct was to fix the code and then update the test. Again this is the wrong approach. I went to the test first, modified it to do what I was expecting, then used the test to help me fix my code. I know this is a lot to take in but I hope you don't make the same mistake I did. If you test code that already exists you may not know there is a more serious bug until it is to late. This is also a great example of how multiple tests can help verify or expose an issue with your code if they test the same situation with different approaches.

Tip 2: Test One Assert At A Time

When I was getting started, I asked other developers what the best practices were for dealing with multiple asserts in a single test. Everyone had their own opinion. I admit, I tried out multiple asserts in a single test but noticed it was becoming more difficult to keep track of where my tests were failing. This made me believe the best way to really test your app, in a way that allows you to quickly find and fix a failing test, is to only do one assert at a time. The downside of course is larger test classes but I rather write lots of tests then have to deal with a single failure that forces me to try and track down the problem in a collection of asserts. Granted this isn't as bad as I am making it out to sound, but part of the added burden of writing unit tests revolves around maintaining them. If you have a hard time managing your tests, you are less likely to continue adding onto them.

The best example I have is the test I wrote for F*CSS's TextField Factory. This test makes sure that the factory is able to create a new TextField, request a style, and apply it properly. The TextFieldFactory takes advantage of another utility (TextFieldUtil) that knows whether to apply a style's property on a TextField or on a TextFormat. Since there are about 30 or so properties that need to be checked, I create a test for each property on the TextField and it's TextFormat to make sure they return exactly what I expected from the supplied style. All of this could have been done in a single test but I find separate tests cleaner and easier to maintain. Plus I can add additional logic, specific to a single property, in it's own test without affecting any of the other tests around it.

Tip 3: Test The Little Things

When setting up unit tests on large applications or frameworks it is easy to get lost in the big picture. A lot of the time there are simple tests you should be doing to make sure you have clean code. When I was going through F*CSS it dawned on me to check that methods and getters which returned Arrays were creating a copy of the Array and not an actual reference to it. When getting started in unit testing this may not be something you think to test but it is a common mistake you can make when quickly writing code. Sure enough, I found a few places where I was not returning a copy of the array. Now that I have corrected the problem in the code I feel a lot better knowing that public properties are better protected from accidental corruption.

Tip 4: Unit Tests Help When Refactoring

Towards the end of writing my unit tests for F*CSS I decided to go back and change a lot of the API names. Since I used a modified version of Flash Camo's css parser, some of the method and class names really didn't make sense as a standalone project. At this point I had 100 or so unit tests and was really feeling good about starting my refactor. I would use Flash Builder's refactor command to rename a method, run my test, see what failed, then go back and make the correct. When it came to the next method I wanted to rename, I would do the same thing; rename, test, then fix. I did this through all the methods that needed to be change. I have to say, relying on the unit tests while refactoring really helped me find "hidden" problems I wouldn't have normally noticed because they may not have shown an error in the editor.

Tip 5: Know When To Unit Test

A lot of my resistance to unit testing in Flash had revolved around my belief that unit testing visual applications is very difficult to do with traditional tests. After a few weeks of really using TDD I can better asses what parts of my app need to be tested. It is hard to break the mentality that every class or functionality should have a test. Parsers, data only classes (models), and even some display classes can be successfully tested. I also find unit testing to take the place of creating demo classes that verify that your code works. Now I use the same code I would have in each of my demos in the unit test. Unit testing allows me to feel comfortable that the example still works even though I don't have to see it working for myself. In the end, you need practice at identifying when and where to use unit tests. Eventually it will become second nature.

I hope this post will help you avoid making some of the beginner mistakes I have. It is important to be active in the community, ask questions, and share what you have learned. Most of us are learning more advanced development methodologies from other languages for the first time. I also want to share a few resources to help get you started and keep you on the right track.

Posts/Tutorials

People on Twitter to follow who talk about Flash TDD

Like always if you have any comments, suggestions or feel I got this wrong, please leave a comment below.

Read more from Jesse Freeman. Jesse Freeman's Atom feed TheFlashBum on Twitter

Comments

3 Comments

Damien said:

Well those tips aren't specifically for flash unit testing. They're for any unit testing.

Robert Penner said:

Nice article. Loved this quote:

"I had writing my test on code that had a bug in it so the test only passed when the bug was present."

That's the thing about testing after: you're already biased by your implementation.

sand said:

hahaha, me too =>

Leave a comment


Tag Cloud

iPad

What's your take on the iPad? (Putting aside the Flash/iPad flame war)

Answer

Latest Features

Recommended for You

@InsideRIA on Twitter

Archives

  • Or, visit our complete archive.  

About This Site

Welcome to the premiere community site for all things RIA sponsored by O'Reilly Media and Adobe Systems Incorporated.