Out of the box, it's very similar to early JUnit. Like all XUnit ports, it's based on creating testing classes and defining methods that are tests. There's setup, teardown, and all the usual features you expect from XUnit ports.
There's a FlexUnit swc (library) that assists in creating a test swf file, which runs all the tests in the browser. There's a few blog entries that give details on how to generate an XML file from the test swf, so breaking a build or reporting results is possible. I haven't bothered to go that far, but others have successfully blazed that trail.
In general, testing Flex is not great, but I rarely find myself concerned or unhappy. Here's a few reasons why.
- There's little logic in my views anyway, the current app is Flex front end to Rails resources.
- Anything that's annoying, I move out of my way by generating with some ruby scripts (for example: creating the file that lists all the test cases). -- more on this later
- Anonymous objects in flex have been 'good enough' stubs
I'm not a fan of manually adding tests to my test suite, but just like Paul Gross, we dynamically create ours. So it's not a problem. We didn't stop there though, we also generate the package and class name; therefore, our test classes stay pretty clean. The code below is an example of an entire test file (the ones that we work with).
public :void {
var smartListCriteria:* = new SmartListCriteria();
smartListCriteria.addLimitCriteria({order:"an order"});
assertEquals("an order", smartListCriteria.toXml().sort.order);
}
public :void {
var smartListCriteria:* = new SmartListCriteria();
smartListCriteria.addLimitCriteria({field:"a field"});
assertEquals("a field", smartListCriteria.toXml().sort.field);
}Those methods wouldn't do much in isolation, but if you generate the surrounding (tedious) code, they work quite well. Here's the rake task that I use.
desc "Generate test files"
task :generate_tests do
tests = Dir[File.dirname(__FILE__) + "/../../test/flex/tests/**/*Test.as"].each do |file_path|
file_path = File.expand_path(file_path)
package = File.basename(File.dirname(file_path))
emit_file_path = (File.dirname(file_path) + "/" + File.basename(file_path, ".as") + "Emit.as").gsub(/tests/,"generated_tests")
File.open(emit_file_path, "w") do |file|
file << <<-eot
package generated_tests. {
import flexunit.framework.TestCase;
import flexunit.framework.TestSuite;
import uk.co.company.utils.*;
import uk.co.company.smartLists.*;
import mx.controls.*;
public class extends TestCase {
}
}
eot
end
end
endAs you can see, I generate test files and which are later used as source for the test swf. It's a few extra steps, but I never see those steps, I just write my test methods and run
rake test:flex when I want to execute the tests. The one catch is that I can't run individual tests, which is terrible.There are no mocking frameworks that I've seen, so that's kind of a bummer. Though, in practice I haven't found myself reaching for a mock anyway, but that will probably depend on your style. Again, I don't have much behavior in my views, so I don't need rich testing tools. Of course, I'd love to have them if they were available, but I don't find their loss to be a deal breaker. I do reach for stubs fairly often, but anonymous classes seem to work fine for that scenario.
There is one huge win that I'll conclude with. When using HTML & Javascript you have to test in browser to ensure that it works. This isn't true of Flex since there aren't browser issues. So, I can test my application using FlexUnit, and be confident that it just works. Removing the need for a (often slow and fragile) Selenium suite is almost enough to make me ditch HTML & Javascript forever.