WoWUnit

4.8k Downloads
WoWUnit is a unit testing framework for addon developers to use when creating addons.

What is Unit Testing?

(quoted from Wikipedia: http://en.wikipedia.org/wiki/Unit_testing) In computer programming, unit testing is a method of testing that verifies the individual units of source code are working properly. A unit is the smallest testable part of an application. In procedural programming a unit may be an individual program, function, procedure, etc., while in object-oriented programming, the smallest unit is a method, which may belong to a base/super class, abstract class or derived/child class.

Features

WoWUnit contains the following features:
  • Allows addon developers to create and execute test suites.
  • Allows WoW API calls to be simulated by allowing the developer to create mock functions that override API calls during the tests.
  • Set up and tear down methods in the test suite can be used to define a consistent context in which tests are run.
  • Enables regression testing by helping to ensure that finished pieces of code are broken by a recent change.
  • Console based user interface that doesn't get in the way any addons being developed.

Usage

Developers should first make WoWUnit an optional dependency for their addon. They can then create a test suite and register the suite with WoWUnit. Test suites can be run by typing "/wowunit <test suite>" at the console. WoWUnit will then run the tests and display the results in the console window. Test suites contain one or more tests, as well as optional setUp and teardown functions, and a mocks table to define global functions and variables that should be mocked during the tests.

Example

The following is a simple test suite example:
local SampleSuite = {
	mocks = {
		UnitName = function(arg)
			return "Soandso";
		end;
	};
	setUp = function()
		return {};
	end;
	tearDown = function()
		-- no tear down required
	end;
	testExample = function()
		assert(UnitName("player") == "Soandso", "Expected player name to be 'Soandso'");
	end;
	testFailure = function()
		assert(UnitName("player") == "Feithar", "Expected player name to be 'Feithar'");
	end;
}
The mocks table defines any global functions that will be mocked. In this case, we want the API function UnitName to return the name "Soandso" when we're running our test, regardless of what argument is passed into the function. Mocked functions will be reset back to whatever they were originally defined as after each test is run. The setup function should return a table that will be passed as an argument into all the test cases defined in the suite. Any setup that needs to be done should be placed here, and will be executed prior to running each test in the suite. The teardown function will likewise be run after each test in the suite. The mock, setup, and teardown entries in the test suite are optional, and do not need to be defined if they are not needed. Any function defined in the suite that has a name that starts with 'test' will be considered a test that should be executed as part of the suite. In this case, we have two tests, testExample and testFailure. testExample checks to see if the player's name is "Soandso". Since we defined a mock function above to replace the standard WoW API UnitName function, this test should pass, even if our character name isn't "Soandso". testFailure should fail, even if the developer logged into WoW as Feither, since the mocked UnitName function will report that the player's name is really "Soandso". One the test suite is defined, it needs to be registered with WoWUnit with the following line of code:
WoWUnit:AddTestSuite("WoWUnitExample", WoWUnitTests);
This registers the suite and names it "WoWUnitExample". Now, the suite can be run in game by typing the following in a chat window:
/wowunit WoWUnitExample
WoWUnit will then run the tests, and display the output in the main chat window:
WoWUnit: Running 2 tests from suite WoWUnitExample...
WoWUnit: FAILED: WoWUnitExample:testFailure
WoWUnit: Interface\Addons\WoWUnit\WoWUnitTests.lua:23: Expected player name to be 'Feithar'
WoWUnit: Passed 1 of 2 tests.