Sunday, 28 August 2016

Busted or LuaUnit?

Having decided to learn Lua and testing Lua at the same time, I need to decide on a testing framework. There seem to be quite a large number available. I was guided to look at Busted and LuaUnit. Both seem active, professional and have good documentation. They have quite different approaches and it is hard to chose between them without any experience of them. 

I have decided to use them both whilst learning Lua. That decision will, no doubt, slow my learning a little but it should give a greater depth to what I learn.

To get started quickly, a took a function from a Prag Prog Magazine  article "a-functional-introduction-to-lua" and created a module to put it in and wrote both Busted and LuaUnit tests for it.

Here is the module and function:

    local learnLua = {}

    function learnLua.namesOf (things)
      local names = {}
        for index, thing in pairs(things) do
    names[index] = thing.name
  end
      return names
    end

    return learnLua

Here's the Busted test:

    require 'busted.runner'()
    local ll = require 'learnLua'

    describe("Flames with Lua", function()
      describe("namesOf", function()
        it("extract string names", function()
          local cats = {
            { name = "meg", breed = "persian" },
      { name = "mog", breed = "siamese" }
          }
          assert.equal("meg", ll.namesOf(cats)[1])
          assert.equal("mog", ll.namesOf(cats)[2])
          assert.equal(2, # ll.namesOf(cats))
        end)
      end)
    end)

Here's the LuaUnit test:

    luaunit = require 'luaunit'
    ll = require 'learnLua'

    local cats = {
      { name = "meg", breed = "persian" },
      { name = "mog", breed = "siamese" }
    }

    function testNameExtract() 
      local cats = {
        { name = "meg", breed = "persian" },
  { name = "mog", breed = "siamese" }
      }
      local names = ll.namesOf(cats)
      luaunit.assertEquals(names[1], "meg")
      luaunit.assertEquals(names[2], "mog")
      luaunit.assertEquals(# names, 2)
   end

  os.exit( luaunit.LuaUnit.run() )

Both tests pass:
    $ luajit learn-unit.lua            
    . 
    Ran 1 tests in 0.000 seconds, 1 success, 0 failures    OK

    $ luajit learn-busted.lua    
    1 success / 0 failures / 0 errors / 0 pending : 0.000617 seconds

Not a lot to chose between them when testing such a simple function. I need to work up to something more complex to really see the differences between them.

I'd be happy to learn about improvements in style or form that I could make in writing Lua, Busted tests and LuaUnit tests.

There is some early feedback on Busted and LuaUnit in Test Doubles and you can read my conclusion in Busted or LuaUnit? Answered

Installing LuaJIT and Luarocks on OS X

Thanks to Homebrew, installing Lua on OS X is easy. I wanted to install the LuaJIT version as that is the one that I'm likely to be using in the future. It was just a matter of:

    $ brew install luajit

I also wanted to install the Luarocks package manager. My first attempt failed.

Then I found the very helpful instructions at Mesca's Homebrew-Luarocks page

Sadly, it is no longer available via Homebrew. I need to find a new method to install Luarocks to use with Luajit

Learning Lua

It looks as though I may be working on a project using Lua and I thought it would be a good idea to start learning the language ahead of time. I know JavaScript and Red which like Lua are influenced, either directly or indirectly, by Scheme. I'm hoping my knowledge of them will help me in understanding both the concepts and philosophy of Lua.

The most common way of learning a new language, especially one with a command line interpreter, seems to be to experimenting with coding whilst reading or going through a tutorial. Once you've learnt the language, you go on to learn about its environment - modules (or packages), testing and the like. 

I'm going to adopt a different approach to learning Lua and try to use things  such as modules and testing from the outset. Over the next few months, we'll see how well it works for me.