For only making tests codes (mochitest), I think it's good that we introduce the way to write async test uniformly.
However, I seem we need consider about it for some reason. 1. We have already task.jsm modules in our source tree. It's promises based design and it has been used in our code. the difference of styles will causes some problem and it's not good for project. Even if we need to mix some different paradigms for async code, we separate a paradigm per each modules. 2. We may need to consider DOM Future http://dom.spec.whatwg.org/#futures and the discussions on es-discuss about introducing Future pattern to ECMAScript standards. This is the tide which we cannot ignore about. If ECMAScript or DOM Standard adopt them as formal standards, its design pattern will be main stream and following it will be benefits. 2013/5/7 Mike de Boer <mdeb...@mozilla.com>: > TLDR; in bug 867742 I requested to adopt two JS modules, Async.jsm and > AsyncTest.jsm, in mozilla-central/toolkit/modules. The whole story can be > read below as well as at https://gist.github.com/mikedeboer/5495405. I posted > about this subject before on firefox-dev: > https://mail.mozilla.org/pipermail/firefox-dev/2013-April/thread.html#268 > > ... > The thing I always do when I encounter a large code base, is roam though it > and make a mental map of the structure; the good parts and ones that would > benefit from some TLC. A part I noticed did not yet receive the amount of > attention it deserves are unit tests and asynchronous code handling. I'll be > blunt about it, here's what I did: I ported the async NodeJS library to a > Mozilla-style module and on top of that I built a unit testing library, > inspired by Mocha (among others). I can imagine that the fellas I just > mentioned don't make you recall anything, so here are two links: > > https://github.com/caolan/async > https://github.com/visionmedia/mocha > First of all, the Github numbers will show you that they are crazy popular > NodeJS libraries. And well-documented. And well-written. And awesome. > > Here's the thing I ended up with: https://github.com/mikedeboer/mozAsync The > lib folder therein contains two files: > > Async.jsm - the port of the async library > AsyncTest.jsm - the unit testing library The test folder contains the unit > tests (erm, duh) and also serve as great examples of how to use the two > modules! > Ok, example time! I really like this one from the async module: > > // Sorts a list by the results of running each value through an async > iterator. > Async.sortBy(["file1", "file2", "file3"], function(file, callback){ > fs.stat(file, function(err, stats){ > callback(err, stats.mtime); > }); > }, function(err, results){ > // results is now the original array of files sorted by > // modified date > }); > Note: this one uses a NodeJS API, but you can mentally replace that with an > async MozFile one. > > I've told some of you before that I'm not a big fan of Promise libraries (if > not, please read the 10 reasons to NOT use a Promise library: > https://gist.github.com/mikedeboer/5305020). However, this library is not > meant to replace them, but to augment the ecosystem with another option. > There are many developers out there that feel uneasy about using Promises as > long as they're not a first-class primitive in SpiderMonkey. If that's you, > you can use this: a minimalistic, functional utility library. > > What about them unit tests? > > Design goal: create a simple, minimalistic framework that provides a clear, > unified API to create unit tests that is as easy to use for sync code flows > as for async ones. Rationale: unit tests are 'hot' code. They are modified as > often - perhaps even more - as functionality it covers changes, especially in > TDD environments. They serve as documentation for the code they cover. When > tests fail, they usually don't on 'your computer', but somewhere else, like > on the build infrastructure. When that happens, someone will open the unit > test and try to understand what is going on. In all these cases it is hugely > beneficial to a) know that most of the unit tests are written in the same > structure and b) are structured in such a way that they're easy to read by > someone other than you. > > This is an example of a minimal test: > > AsyncTest([ > { > name: "Minimal Test", > reporter: "tap", > tests: { > "it should execute this test": function(next) { > Assert.equal(typeof next, "function", "'next' should be a callback > function"); > next(); > }, > > "! it should NOT execute this test": function(next) { > Assert.ok(false, "BAM!"); > next(); > }, > > "it should be aware of the correct context": function() { > Assert.ok(this["it should execute this test"], "The function ought to > be accessible"); > } > } > } > ]); > There are a couple of interesting things going on here: > > You can pass an Array of test suites or just one Object > Suites can have names > Tests can be described freely > It mixes fine with ANY assertion style (Mochi or XPCShell) > Prefix a test with ! to exclude it from the suite. This is something that is > practically useful when doing TDD. > Prefix a test with > to only run that test and ignore the others. It is meant > to signal out a test case and run only that specific one. This is something > that is practically useful when doing TDD. > If the test is sync, you can forget about the next function (callback) > completely - the library takes care of it; you can even mix async and > non-async tests > You can choose the style of reporting by setting the reporter property to dot > or tap. The reporters progress and spec are under development. More > information about what 'TAP' is can be found at: http://testanything.org > But more importantly, there are several things that usually need to happen > before a test can be run, like opening a tab, load a page and wait for it to > load, etc. AsyncTest unifies scenarios like this in the following way: > > Each suite may have one or more of the following functions: > setUpSuite - run only once before any test is executed > setUp - run once before each test > tearDownSuite - run only once when all tests are done > tearDown - run once after each test > These functions are executed in the context of the tests, so the this is the > same as the this in test functions > This takes care of all the flows a test suite might need to implement. > > For another example, please take a look at the following two files: > > https://github.com/mikedeboer/mozAsync/blob/master/examples/browser_aboutHome.orig.js > https://github.com/mikedeboer/mozAsync/blob/master/examples/browser_aboutHome.js > This is the browser_aboutHome.js unit test code vs. a rewritten version with > AsyncTest. > > The NLOC difference is minimal (~100 lines), but the more significant > improvement here is the structure that is proposed as uniform. > > To top this off, you can set a flag in each suite: notify: true to present > you with a Growl notification once the suite is done to report the results! > > That shows that this library is meant to bring back the fun into creating > unit tests. > > > Mike de Boer. > _______________________________________________ > dev-platform mailing list > dev-platform@lists.mozilla.org > https://lists.mozilla.org/listinfo/dev-platform > -- saneyuki_s saneyuki.s.s...@gmail.com _______________________________________________ dev-platform mailing list dev-platform@lists.mozilla.org https://lists.mozilla.org/listinfo/dev-platform