BTD
build-test-deploy Development Environment

Comprised of one class :

TestIup.lua
In Lua it is easy to override any function. This is also possible for libraries (as is the IUP framework) and because of the mechanics of the require function, it is even possible to do this before the library is actually called in the GUI program. The way this works is as follows :
- setup (in TestIup.lua)
  • Remove all IUP classes from the global environment
  • Load IUP (again ?)
  • Replace the iup.MainLoop and iup.SetIdle functions
  • Subsequent require's of IUP will not load the library anymore (just run it).
- run test
The test class will require the GUI program. This will (load and) run it. Since the iup.MainLoop is not active anymore the GUI will not start. In this stadium it is possible to verify that all required GUI interface elements are loaded and/or to test methods in the GUI program.
It is also possible to test the GUI dynamically. For example :
-----------------------------------------------------------------------------
-- Demo unit test for iuptree2.wlua
-- Same test function 'new style' (all local variables)
-- @release 0.0.0
-----------------------------------------------------------------------------
local test = require('btd.lua.testapi')
local testIup = require('btd.lua.testiup')
                    
TestIupTree2New = {}
                    
function TestIupTree2New:setUp() -- start GUI program on every test method
	dofile('btd/lua/test/iuptree2.wlua')
end
                    
function TestIupTree2New:test_createNewStyle()
	local function idleLoop(t) -- exit GUI after 2 s
  	return function()
    	if (os.clock() - t) < 2 then
      	return iup.DEFAULT
      else
      	return iup.CLOSE
      end
    end
  end
  test.equals(tree.name0,'Animals') -- check presence of GUI elements
  test.equals(tree.name1,'Mammals')
  test.equals(tree.name2,'Horse')
  test.equals(tree.name3,'Whale')
  test.equals(tree.name4,'Crustaceans')
  test.equals(tree.name5,'Shrimp')
  test.equals(tree.name6,'Lobster')
  test.equals(tree.state0,'EXPANDED')
  test.equals(tree.state1,'EXPANDED')
  test.equals(tree.state4,'EXPANDED')
  local t = os.clock()
  testIup.iupLoop(idleLoop(t)) -- start GUI, do idle loop processing
  -- 'somehow' the 'Crustaceans' branch should be closed
  test.equals(tree.state4,'COLLAPSED')
end
The way testIup.iupLoop works depends on :
- no parameter (testIup.iupLoop())
The GUI program will start and will stop the first time idle loop processing is called for
- parameter and no idle loop in GUI program (testIup.iupLoop(idleLoop(???))
The GUI program will start and will, every time idle loop processing is called for, call the idleLoop function. The GUI program will stop when that function returns iup.CLOSE
- parameter and idle loop in GUI program (testIup.iupLoop(idleLoop(???))
The GUI program will start and will, every time idle loop processing is called for, call the GUI program idle loop function, followed by the test idleLoop function. The GUI program will stop when that last function returns iup.CLOSE
- test robot
Now, the testing side of the equation works. The means to statically and/or dynamically check a GUI are present. However, unless we want to condemn ourselves to manually activate the GUI while it is under 'automatic' test we need something more : a test robot. Ideally this would be part of the test environment itself :
  • Generate keyboard events (low level)
  • Generate mouse events (low level)
  • Generate time based keyboard and/or mouse events to be able to actually see what is happening or as a demo function (low level and/or lua)
  • Lookup coordinates of GUI elements and generate 'high level events' as 'click GUI button', 'enter GUI text',... (lua)
But this faces different problems :
  • The 'low level' parts (see above) can't be written in Lua (C or C++).
  • There is not only an operating system dependency, but also (or more so) a 'windowing environment' one.
  • Last but not least, this is (for now) only foreseen for IUP. At least port of the functionality is framework agnostic and there are several other frameworks.
  • This gives an 'interesting' :o) mix of posibilities, any ideas anyone ?
The best solution, for the time being, is to use an 'aplication automation' tool as there are several for different windowing environments. For example :
- record test events
  • Start the external event recording/generating tool
  • Fire up the GUI
  • Start recording
  • Perform the required GUI activation, equivalent to one test
  • Stop recording and save
This should be repeated for all tests.
- execute tests
This depends on the tool used. The best option being that the tool could be started from Lua with, as a command line option, the recording to be replayed. And sync this with the actual test methods.
Remarks
  • For the actual GUI testing part, the Serial flag should be used.
  • Since a GUI test can be quite long and repititive it can be considered to use the abort btd.lua.TestApi method.

Valid XHTML 1.0!

$Id: guitest.html