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.
------------------------------------------------------------------------
r10 | feithar | 2009-02-07 19:26:28 +0000 (Sat, 07 Feb 2009) | 1 line
Changed paths:
A /tags/1.0.9 (from /trunk:9)
Tagging as 1.0.9
------------------------------------------------------------------------
r9 | feithar | 2009-02-07 17:40:11 +0000 (Sat, 07 Feb 2009) | 2 lines
Changed paths:
M /trunk/WoWUnit.lua
WoWUnit:
- message when an assertEquals test fails now includes the correct code line instead of the line within the assertEquals function.
------------------------------------------------------------------------
r8 | feithar | 2009-02-07 17:20:08 +0000 (Sat, 07 Feb 2009) | 2 lines
Changed paths:
M /trunk/WoWUnit.lua
WoWUnit:
- Assert message now prints the table field that differs when comparing tables.
------------------------------------------------------------------------
r6 | feithar | 2009-02-07 15:26:43 +0000 (Sat, 07 Feb 2009) | 2 lines
Changed paths:
M /trunk/WoWUnit.lua
M /trunk/WoWUnitTests.lua
WoWUnit:
- assertEquals now correctly handles table comparisons.
------------------------------------------------------------------------
r4 | feithar | 2009-02-07 00:38:06 +0000 (Sat, 07 Feb 2009) | 2 lines
Changed paths:
M /trunk/WoWUnit.lua
WoWUnit:
- Fixed error in assertEquals that would result in a false positive if either of the values being tested was nil.
------------------------------------------------------------------------
r2 | feithar | 2009-01-27 04:12:46 +0000 (Tue, 27 Jan 2009) | 2 lines
Changed paths:
M /trunk
A /trunk/.pkgmeta
A /trunk/WoWUnit.lua
A /trunk/WoWUnit.toc
A /trunk/WoWUnitConsole.lua
A /trunk/WoWUnitGUI.lua
A /trunk/WoWUnitGUI.xml
A /trunk/WoWUnitTests.lua
WoWUnit:
- Initial import.
------------------------------------------------------------------------
r1 | root | 2009-01-27 02:09:48 +0000 (Tue, 27 Jan 2009) | 1 line
Changed paths:
A /branches
A /tags
A /trunk
"wowunit/mainline: Initial Import"
------------------------------------------------------------------------
Installation Guide
- Exit "World of Warcraft" completely
- Download the mod you want to install
- Make a folder on your desktop called "My Mods"
- Save the .zip/.rar files to this folder.
- If, when you try to download the file, it automatically "opens" it... you need to RIGHT click on the link and "save as..." or "Save Target As".
- Extract the file - commonly known as 'unzipping'
Do this ONE FILE AT A TIME!
- Windows
- Windows XP has a built in ZIP extractor. Double click on the file to open it, inside should be the file or folders needed. Copy these outside to the "My Mods" folder.
- WinRAR: Right click the file, select "Extract Here"
- WinZip: You MUST make sure the option to "Use Folder Names" is CHECKED or it will just extract the files and not make the proper folders how the Authors designed
- Mac Users
- StuffitExpander: Double click the archive to extract it to a folder in the current directory.
- Verify your WoW Installation Path
That is where you are running WoW from and THAT is where you need to install your mods.
- Move to the Addon folder
- Open your World of Warcraft folder. (default is C:\Program Files\World of Warcraft\)
- Go into the "Interface" folder.
- Go into the "AddOns" folder.
- In a new window, open the "My Mods" folder.
- The "My Mods" folder should have the "Addonname" folder in it.
- Move the "Addonname" folder into the "AddOns" folder
- Start World of Warcraft
- Make sure AddOns are installed
- Log in
- At the Character Select screen, look in lower left corner for the "addons" button.
- If button is there: make sure all the mods you installed are listed and make sure "load out of date addons" is checked.
- If the button is NOT there: means you did not install the addons properly. Look at the above screenshots. Try repeating the steps or getting someone who knows more about computers than you do to help.
Translations
When you download a mod, please be sure that the mod is compatible with your translation of wow. Some mods only work on the US versions, while some only work on some of the various European versions. These variations are called "Localizations".
TOC Numbers (Out of Date Mods)
When Blizzard patches WoW, they change the Interface number. This means that all mods will be "out of date" unless or until the author releases a new version for that interface. Some people go into the .toc files and update the numbers themselves, but this is STRONGLY advised against as it will cause problems locating possible incompatibilities addons. When you log into WoW after a patch, you DO NOT have to delete your interface directory. All you have to do is simply tell WoW to ignore the interface numbers and load all the mods anyway. All you have to do is, while at the "character select" screen, look in the lower left corner and click on the "addons" button. A window will pop up listing all your installed mods.
If you look in the upper left corner of that window there should be a box that says "Load Out of Date AddOns". You want to CHECK this box. Now simply go into WoW normally and all your mods should load. As of the 1.9 patch, you will have to do this after EVERY patch/update that Blizzard posts! If you encounter any problems with a mod after a patch, please be sure to let the author of the mod know so they can fix it.
See also: About "Out Of Date AddOns"
Mac Support
WoW addons are not platformed based. As such, they can be used on either Mac or PC. You can extract both .zip and .rar files on a Mac using StuffitExpander.
Directory Structure
World of Warcraft
|_ Interface
|_AddOns
|_*AddonName*
|_ *AddonName*.toc
|_ *AddonName*.xml
|_ *AddonName*.lua
|_ (possibly others as well)...