Re: [gnome-shell-ext] Unit testing approach



Only a heads up on this, I have solved most of the issues by using Webpack:

  1. Imports mechanism is replaced with ES6 imports, by defining the target library to UMD for webpack this should be a problem. Webpack creates a single extension file with all the needed configurations.
  2. Since we are using ES6 imports now, there's no problem while testing. Karma has to be setup with support for webpack though.
  3. The GS polyfill is still needed for tests to run correctly.
  4. The GS API remains, although I found a library for tracking signals online, it was not documented and the repository for it was actually removed.
  5. Integration testing is still not possible.
  6. Tests run now on PhantomJS. For this, I had to use a transpiler (babel) with webpack. This has the added benefit of generating JS code that is backwards compatible between GS versions, while allowing us to use ES6 features.
  7. This was all integrated with Travis CI (see the github repo for reference).

NOTE: I had to keep classes that extend native GS classes using Lang.Class instead of ES6 classes, because there were some problems with the transpiled code when calling super constructors. If you are not using a transpiler for releases, all classes can be refactored to ES6.

I hope this helps anyone trying to provide quality code for GJS/GSE.

Regards.


On 27/11/17 11:08, Edgar Merino wrote:

Hello:

    Recently, while solving some problems with an extension I created when upgrading gnome shell, I realized there's no way to actually perform tests on GSE code. I'm an agile advocate, so for most of the work I do I always rely on tests (unit tests and integration tests mostly). So, I spent the last couple of days working on refactoring the code for the extension, and I introduced unit testing using npm/karma/jasmine/firefox. You can see the whole code in this github repository:

https://github.com/emerinohdz/power-alt-tab

    There where a couple of issues I encounter:

  1. GS uses an "imports" mechanism, in order to include a script into another. This was solved by using a really simple "class finder" (defined under utils.js). The implementation is not really pleasant, it requires so called "classes" to be manually declared (and they should be declared according to order of use). The idea is that you can use something like 'const MyClass = Utils.use("gs.MyClass")' to include MyClass into your current script. It would be wonderful if GS included this sort of functionality out of the box, and maybe include something like "autoloaders" which can be defined depending on the environment where the code is being run (e.g. under firefox for unit testing or under real GS enviroment). Or maybe implementing something like AMD?
  2. For unit testing (with karma), all the code is read when tests run, this presented a problem with the way GS loads scripts, because using "const" globally presented problems when running under karma, while it was needed for GS. What I did here consisted on using self executing functions to provide a narrower scope for each script, so now "const" could be declared on every script without problems when running under karma.
  3. For unit testing to work fine, I had to include a GS polyfill (test/polyfill_gs.js). This polyfill only covers what I needed, the way I needed it, mostly mocking every global GS object needed.
  4. I've worked on a really small GS API (which is by no means complete), located under "src/gs". The idea here is to have a higher level API to work with, which will handle most of the low level stuff. This additional layer would help with changes made to the lower level APIs, since extensions can be coded against this higher level GS API which should not change often. I only included a GS screen wrapper and a signal tracker (for tracking signal connect/disconnect). Things like keybinding could be included in the API too, and many other facilities I'm not using with my extension too. This should be an additional effort, but well worth it IMO.
  5. Integration testing was not possible, this would be a huge step forward. Right now it is becoming harder to test the extension on a real GS environment, you have to revert to some sort of virtual environment, specially if using Wayland (where restarting GS is not possible). Providing some type of test API where things could be integrated and tested before moving to production would mean faster delivery of new functionality IMO. This is of course the greatest challenge.
  6. I had to use firefox, in order to use some of the ES6 features, but things can be worked out to include an ES5/5 polyfill to use PhantomJS (not tested).

NOTE: I used constructor functions instead of Lang.Class to define so called "classes" for most of my code, but it's not a problem to use Lang.Class, as you can see here "src/nuevebit/workspace_switcher_popup.js".

    I don't know if this is something the GSE devs are interested in taking a look at, I would be more than glad to contribute to this project if needed.


Regards.

Edgar Merino




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]