Titanium Community Questions & Answer Archive

We felt that 6+ years of knowledge should not die so this is the Titanium Community Questions & Answer Archive

Unit testing support

I have been trying to figure out a way to write automated unit tests for the JavaScript code in the mobile app I am working on. However, because there is no actual JavaScript library behind the JavaScript Titanium.* APIs, all tests I try to write blow up because 'Titanium' cannot be found.

Given how difficult it is to interactively debug mobile apps written for this framework (and how programmatic breakpoint-style debugging is impossible), it would be immensely helpful if there was support for writing unit tests for application code that interacts with Titanium APIs. Having a skeleton of the entire JavaScript API would be a great help because it would allow developers to mock out all calls to the framework so that they could just write tests for their own code.

Are there any plans to help application developers improve their ability to write automated tests for Titanium apps?

— asked March 11th 2010 by Mario Aquino
  • unit test
  • unit testing
0 Comments

9 Answers

  • Here is an easy receipt to start with unit testing. I have just made a unit testing framework successfully execute in a Titanium Mobile project today. It is called jsUnity and is an xUnit-type framework as per Wikipedia, so if you already know an xUnit-type framework then you'll be familiar with it immediately.
    The jsUnit framework is also context-agnostic, which means it does not rely on any specific context for writing its messages to. Rather, you can override its "log" method with something that fits into your specific context. For Titanium, we can make use of this feature and write a log method that simply uses Titanium.info().

    Here are the steps:

    1. Get jsunity-0.6.js from jsUnity.com and place it into the Resources directory of your Titanium project (or in a subdirectory, depending on your project).
    2. Create a new file, named, for example, TitaniumUnity.js. Add this code to the file:
      ~~~
      Titanium.include("jsunity-0.6.js");

    jsUnity.log = function(message) {
    Titanium.API.info(message);
    };

    This overrides jsUnity's log function with a function that writes all test output to Titanium Developer's emulator console.
    
    3. Create your unit test suites in a separate file, e.g. **`DataTest.js`**:
    

    Titanium.include("TitaniumUnity.js");

    var DataTestSuite = {

    suiteName: "Data Test Suite",
    
    setUp: function() {
        ...
    },
    
    tearDown: function() {
        ...
    },
    

    // add your test functions:

    testInit: function() {
        ...
    },
    
    testQuery: function() {
        ...
    }
    

    };

    Titanium.UI.currentWindow.addEventListener(
    'focus',
    function(e) {
    jsUnity.run(DataTestSuite);
    });

    
    4. Add a window to your application that runs the unit tests:
    

    var win1 = Titanium.UI.createWindow({
    url: 'DataTest.js',
    title:'Data Unit Test'
    });

    Make your app switch to this window when launching, or add a tab or a button to open this window. The unit test runs each time this window gets the focus.
    Don't forget to remove this window (or the button or tab) from your final app :-)
    
    That's it. You are now ready for testing your objects and modules. All test output goes to the Titanium console, like this:
    

    [INFO] Application started
    [INFO] Running Value Test Suite
    [INFO] 2 tests found
    [INFO] 2 tests passed
    [INFO] 0 tests failed
    [INFO] 2 milliseconds elapsed
    ~~~

    There may be more sophisticated test suites out there (for example, JSpec looks quite impressive); however, I was searching for a test suite that was easiest to integrate with Titanium, and jsUnity's context-agnostic approach just met this requirement best.

    — answered June 20th 2010 by Christoph Berger
    permalink
    3 Comments
    • Any thoughts on testing async functionality with jsunity?

      — commented June 19th 2011 by James Sapara
    • I would just tweak:

          jsUnity.log = function(msg) 
          { 
              if      ( msg.indexOf('[FAILED]') == 0 ) console.error(msg);
              else if ( msg.indexOf('[PASSED]') == 0 ) console.debug(msg);
              else                                     console.log  (msg);
          };
      

      BTW, any idea why jsUnity barks when you setUp the variables using var?

      It gives me ReferenceError: Can't find variable: {nameOfVariable}

      — commented January 7th 2014 by JC Guerrero
    • I've created a TestSuite recreating the var issues See the comments

      — commented January 7th 2014 by JC Guerrero
  • Hi there,

    I recently developed a unit testing framework for Titanium Mobile based on Jasmine BDD framework. It's very easy to use and works like a charm.

    The source code and documentation are on GitHub: http://github.com/guilhermechapiewski/titanium-jasmine

    — answered April 6th 2011 by Guilherme Chapiewski
    permalink
    3 Comments
    • Nice work Guilherme! Great to see Jasmine working with Titanium Mobile!

      — commented April 29th 2011 by Todd Huss
    • I can confirm this compiles and runs with Titanium SDK 1.8.0.1 and iOS SDK 5.0. Thanks!

      — commented January 27th 2012 by Christopher Hiller
    • Christopher, thanks for that hint!

      — commented March 8th 2012 by N N
  • I've recently gotten qunit to work inside Titanium (with a slight patch). The full version of how to make it work and code is available at: http://github.com/lukaso/qunit

    You can get all the source by executing:

    git clone git@github.com:lukaso/qunit.git

    The README explains how to use it.

    In the process, I've also figured out how Titanium.include works. It appears that when a new window is created

        var unit = Titanium.UI.createWindow({
            url: 'runner.js', 
            title:'Unit Test'
        });
    

    The location of the file, (in this case runner.js) becomes the 'home' directory for all the includes inside that file. Here 'runner.js' comes from the top level directory so the directory will be Resources.

        var unit = Titanium.UI.createWindow({
            url: 'something/runner.js', 
            title:'Unit Test'
        });
    

    Here the Titanium.include directory will be Resources/something.

    I couldn't get Titanium.include('../../file.js'); to work, so I highly recommend opening all your windows with urls in the top level directory (Resources).

    — answered August 3rd 2010 by Lukas Oberhuber
    permalink
    1 Comment
    • @Lukas. Great work on this. I have your fork running on an app, still failing that one pesky test but letting me test my models.

      On a side note, I'm actually very surprised at the lack of concern over the absence of any real testing in the Titanium community.

      Even the internal testing Drillbit falls short for their own tests. Ideally tests would run outside of the app instead of hacking an extra tab together and would not impact the UI of the app being developed in any way.

      — commented September 21st 2010 by Jonathan Spies
  • This thread is very old, but there is current (June 2012) information on this topic…take a look at this blog post by Olivier Morandi on Jasmine-Node.

    Its very simple to get up and running. Best of all it supports the commonJS modules you might already have.

    — answered June 27th 2012 by Henning Glatter-Gotz
    permalink
    1 Comment
    • Thanks for this! Very interesting blog post

      — commented August 6th 2012 by Joe Lee
  • With 2.1 a new framework (Anvil) was released. From the release notes (http://docs.appcelerator.com/titanium/release-notes/?version=2.1.0.GA):

    New unit test framework. This release includes the first version of the new Anvil unit test framework. Anvil is designed as a replacement for the existing Drillbit unit test framework, which is based on Titanium Desktop. Anvil is written in JavaScript using Node.js, and is designed to allow for test automation. If you are currently using Drillbit and you are interested in using Anvil, see the driver/README file in the Titanium Mobile GitHub repo.

    Anvil supports the same basic types of tests as Drillbit, but each test suite is defined as a CommonJS module. See driver/harnessTemplate/Resources/suites for examples of Anvil test suites.

    Will take a look today as I'm keen on adding unit testing to my app.

    — answered August 19th 2012 by Dario Marcelino
    permalink
    2 Comments
    • @Dario Marcelino have you tried using anvil.. can you help me setting it up or guide me how to get it working..

      — commented November 21st 2012 by Ajeet pratap Maurya
    • Hi Ajeet, no, I never got around using Anvil but I will be using Tho's solution (https://github.com/tsteur/titanium-alloy-jasmine-testing) which seems perfect for what I want/need.

      — commented November 30th 2013 by Dario Marcelino
  • Found an easy solution to write tests for Titanium/Alloy apps using Jasmine see https://github.com/tsteur/titanium-alloy-jasmine-testing . The main advantages of this solution are:

    • They run under Windows, MacOSX and Linux
    • Fast build time and very fast execution time
    • No iOS/Android-SDK required
    — answered June 29th 2013 by Tho Ste
    permalink
    4 Comments
    • Thank you very much Tho, this is exactly the kind of solution I was looking for! Namely, the below items were at the very top of my wishes:

      • Tests won't be packaged within the app
      • You do not need an iOS Simulator or Android Emulator

      I've tried it and it works seamlessly.

      — commented November 30th 2013 by Dario Marcelino
    • Tho, did you manage to get around the "Syntax Error: unexpected token "function"" on tests.js l.30? Everything seems to work fine but when I run my app I always get the popup saying that errors exist. Thanks!

      — commented November 30th 2013 by Dario Marcelino
    • Nice work Tho. One question I have; is there any way to control what specs get run? When unit testing I want to run only the tests for the class that I'm working on.
      Thanks

      — commented December 31st 2013 by Clifford Wollam
    • Not work for me. It is too old I think, and the document may be out of date.

      Also I want an solution for android/ios, but not mobile-web.

      currently there are 2 candidates for me: tishadow, or tiuita. TiShadow could perfectly run unit tests on android/ios, but http://tiuita.tk is still need to test( I am waiting for their response). I will give my updates once I get tiuita.

      — commented February 20th 2015 by Siwei Shen
  • I am interested in this as well. I tried to "vote up" this question, but the forums seem broken. Ideally, Titanium could be shipped with some sort of UT framework. Failing that, you would have to do what you mention and stub out the whole freakin' library: not fun.

    — answered April 6th 2010 by Donnie Tognazzini
    permalink
    0 Comments
  • Here is my current solution, and I am working on integrating jasmine with a console logger also

    Simple Unit Testing in Appcelerator Titanium Alloy http://www.slideshare.net/aaronksaunders/behave-alloy

    — answered February 6th 2013 by Aaron Saunders
    permalink
    2 Comments
    • Hi Aaron, haven't tried yet but from the slides it looks very good and promising! Thank you

      — commented February 8th 2013 by Dario Marcelino
    • here is a repo i posted https://github.com/aaronksaunders/ci.behave.test

      — commented February 8th 2013 by Aaron Saunders
  • TiUiTA: Titanium UI Test Automation http://tiuita.tk/

    — answered April 9th 2014 by Guillermo Zunino
    permalink
    0 Comments
The ownership of individual contributions to this community generated content is retained by the authors of their contributions.
All trademarks remain the property of the respective owner.