|
From: creedon <icr...@us...> - 2005-08-22 00:42:30
|
Update of /cvsroot/frontierkernel/odbs/frontierRoot/suites/fUnit In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11007 Added Files: Tag: fUnit_Suite-branch suiteName readMe menu documentation init unregisterTestSuite registerTestSuite getTempTableAdr Log Message: fUnit Suite initial import --- NEW FILE: getTempTableAdr --- (This appears to be a binary file; contents omitted.) --- NEW FILE: menu --- FrontierVcsFile:1:mbar:suites.fUnit.menu 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 --- NEW FILE: documentation --- FrontierVcsFile:1:optx:suites.fUnit.documentation fUnit fUnit is a Unit Testing framework for the Usertalk environment in Frontier. It is modelled around the standard xUnit framework, for example as seen in JUnit and PyUnit, and adapted for Frontier to take advantage of its unique strengths. About Unit Testing (Unit Testing Advocacy) Unit testing boils down to a series of call to a variety of "assert" functions that "assert" that various things are true at testing time, organized in a particular way that allows a "Unit Testing Framework" to fully automatically execute the tests upon demand, and give a "pass/fail" for the test run. (fUnit also adds an "abort" category which is very useful but commonly missing from xUnit implementations.) The advantages of Unit Testing are: Organization: Unit tests are organized in a way that makes them easy to write, easy to keep around, and easy to execute again and again. *Everybody* writes test scripts, but test scripts are frequently discarded, and even if they are kept around, each developer writes their own. In fact, this suite ships with testSuperStress, where "SuperStress" is just such a salvaged test suite. Now that it is in the framework, we can use all of the framework features, and easily run it at will, in conjunction with other test suites. Framework: fUnit provides a framework with useful features that you don't have to implement yourself. fUnit collects test results in a standard fashion, and allows to use pre-supplied renderers for those (such as the one that displays the results as HTML) or easily write your own. It supplies common functions for testing, such as "assertErrors", and a function to retrieve a stack dump and output it in a standard format in the test results. This way, features can be added to all the test suites at once (like maybe running from a network) without changing the tests. Automatically: Nobody runs tests manually unless it is as easy as pushing a button. Ideally, a project should get it to the point where it doesn't even require that, running tests automatically on commits or periodically. For that, you need standardized tests. Network effects: These advantages combine multiplicatively, not additively, and cause other effects. One of the most exciting is how much easier Unit Testing makes it to refactor code, with confidence that the relevant properties are retained. The first time you massively refactor code and all the old unit tests pass, plus a batch of new ones, you will be a convert. The other exciting one is they save you much, much more time than they cost you ... Unit testing... just try it once for a significant project. Some people push "Test First Development", where you write the tests first and then write the code. I think this is less useful in a dynamic environment like Frontier where it is easy to move functions around, and you're writing experimental code, which stuff in Frontier commonly is. Still, it is worth a try to see if it will work for you. Test Structure fUnit structures its tests in the following manner: "Test Cases" are scripts that start with the word "test", and make use of the various "assert" functions provided by the framework. They can not be run directly. "Test Suites" are Frontier tables that start with the word "test" that contain a collection of test cases. In addition to the test cases, test suites may also contain the following in the table: A string attribute "name", which will be used as the human name of the test case. By default, the name of the table will be used, but it can be inconvenient to have spaces and such in the table name. A string attribute "description", which will be used as the description of the test suite when it is run. By default, this is empty. Another Test Suite. Addresses that point at other Test Suites will be regarded as being an included test suite. (This is useful for aggregating multiple test suites together with needing them to be close in the ODB.) Addresses that point at Test Cases will be regarded as test cases for this suite. A script named "setup" can be included to set up a testing environment that will be used by multiple scripts. The return value of setup will be passed to the test case to use as it wills. Note this script is called for every individual test case, not once for each suite. Errors in this script will halt the execution of the test suite, and teardown will not be called on that run; depending on the contents of the script you may need to manually validate the state of the resources "setup" was responsible for. A script named "teardown" can be included which will be passed the parameter created by "setup" (if any) and can be used to uninitialize any resources like sockets used by the test. Errors in this script will halt the execution of the test suite; depending on the contents of this script and "setup" you may need to manually validate the state of the resources "setup" and "teardown" were responsible for. A "Test Runner" is something that knows how to run tests, and displays the output in some format. Most people won't need to write these. fUnit ships with two Test Runners by default, described in children. Writing a new test runner is easy; run "runTestSuite" with the desired parameters and process the resulting result table or scriptError (in case of setup, teardown, or fUnit code failures). Change the Test Runner fUnit use by default in its menu commands by either setting user.fUnitRunner to the address of your desired Test Runner script, or use the fUnit menu to select one via the "Select Default Runner" option. The "default" test runner simply displays the results table on the screen. You can see the results as they are collected. The "HTML" test runner will output the results of the test as an HTML page and use webbrowser.displayText to display it. It will also nicely format stack traces, when thread.getStackDump is fixed. Generally speaking, a Test Runner is used to interpret the run of a Test Suite, which runs other Test Suites and Test Cases. The relevant menu options in the fUnit menu all use the Test Runner you specify in user.fUnitRunner. Along with the user test suites, fUnit maintains a global test suite which can be used to run all registered tests at once. To register your test suite, call "fUnit.registerTestSuite" with the address to your test suite. All future runs of "fUnit.runAllTests" will now include your test suite. You can call "fUnit.unregisterTestSuite" with the same address to unregister your suite later. (Menu commands for both of these are included for your convenience.) Note that anything included in a test suite that does not match the rules above will be ignored by fUnit, so you can use the suites to store test data or other scripts for use by your test cases. Creating Your Own Test Suite To create your own test suite, create a table starting with the word "test", which I will refer to as "testSuite" for the remainder of this section. (The test suite created by following these directions is available in fUnit.testSuiteSkeleton, which you can also copy and paste.) Create a string value named "name" and enter the name of your suite. Create a string value name "description", and enter a description for your suite. Create a script named "setup", taking no parameters. Create a script named "teardown", taking one parameter, the value returned by setup. Create a test script, starting with the word "test", taking an opitional parameter from the setup script. Use the "Assert Functions", documented below, to test various things. If you install the menu for fUnit, you can now successfully run this test case and see one passed test. menu.install(@fUnit.menu) // hit CTRL-/ while this line is focused to install the menu Testing By Example The tests decribed here are included in the table fUnit.exampleUnitTests, and are already included in the fUnit global test suite when shipped. testSimple testSimple is basically the simplest possible test that has both a failing line and a successful line. It looks like this: on testSimple (setupParam = nil) assert(1 == 1) assert(1 == 2, "Who could ever think 1 == 2?") scriptError("Never get here.") Note the "setupParam = nil" part of the script definition. This test suite does not have a "setup" script, so there is no setupParm passed to "testSimple". However, someday you may add a "setup" script. Using "setupParm = nil" future-proofs your test against that eventuality. The next line calls "assert" with the value "true", which is what 1 == 1 evaluates to. (Try it; put the cursor in the child node of this one and hit "CTRL-/", and Frontier will evaluate the node and show the result as a comment.) Since assert was called with a true value, it immediately returns and does nothing. 1 == 1 After that, assert is called with 1 == 2, which is false. This means "assert" will fail, and the test script will terminate. The second optional parameter is the message which will be sent back out to the test system as the reason the test failed. (Note there is currently a rather small limit on how large that message may be.) 1 == 2 Since the test stops execution after a failed assert, the third "scriptError" line will never be executed. This test shows as a failure, as a result of the second line. testSuperStress SuperStress provides examples of a lot of nitty-gritty Frontier testing. Running Test Suites or Test Cases Test Suites or Test Cases should be run by running one of the scripts in fUnit.runners. fUnit.runners.run will use the user's declared preference (an address to a runner script at user.fUnitRunner), so it should be used unless there is a good reason not to. Runners have the following signiture: run(suiteAdr, testCaseToRun = nil, allowErrorsOut = false) suiteAdr is the address of the test suite to run. testCaseToRun is an optional address of a specific test case to run. It should come from the suite defined by suiteAdr, but this is not checked for. If not given, all test cases and suites will be run. allowErrorsOut is a parameter that allows you to prevent the framework from catching the errors generated by the test suites. This allows them to propogate all the way out to the user level, where you can use the usual "Error Info" dialog box to diagnose the problem. (See "Debugging Hints" at the end of this document.) Assert Functions assert(booleanResult, message = nil) assert is the basic assertion function for test suites. The first parameter is a boolean result, usually of some relatively complicated expression that evaluates to a boolean, not true or false directly. message is a string that will be used as the reason for failure, if one is given. Otherwise, a generic error message will be used. When assert(false) is called, the test case ceases running; put any necessary cleanup in "teardown". Examples: assert("abcdefg" contains "abc") // succeeds assert("23" contains "4", "The digit '4' is not in '23'") // note Frontier has no access to the expression, so make your error messages count assertEqual(value1, value2, message = nil) assertEqual checks that the two values it is passed are equal. If they are not, execution of the test case terminates. This is a convenience function for a common case; it allows the test framework to include value1 and value2 in the resulting error message. If the optional message parameter is passed, it will be used in addition to the default message. Example: assertEqual(1, 2, "1 is not equal to 2") assertNotEqual(value1, value2, message = nil) Same as assertEqual, just inverts the test. Example: assertNotEqual(1, 2, "1 is equal to 2?!?") assertErrors(scriptAdr, errorFragment = nil, failMessage = nil) assertErrors validates that some piece of code correctly throws a scriptError. scriptAdr is the address of a script to test, which will be called with no arguments. This is typically an embedded function; see example. errorFragment is an optional string which will be looked for in the resulting error; if it is not found, the test will fail even if the script errors. This allows the test framework to ensure the correct error is thrown, and its use is highly recommended. Otherwise, any error will be accepted as a passing assert. failMessage will be added to the error report produced by assertErrors if the assertion fails. Note that scriptErrors are limited in length, and with everything this function tries to jam into the error message, it may overflow that length. Example: Test for "division by 0" error on divideByZero() 1 / 0 assertErrors(@divideByZero, "divide by zero") scriptError It is permissible for a test to fail with a normal scriptError, and the text of the error thrown will be used as the reason the test failed in the results. However, fUnit will not be able to obtain the stack dump for the scriptError you throw, and your test may miss out on later such features fUnit adds for error testing, such as convenient jumping to the error. scriptError should be used as a last resort, or possibly for importing other test scripts into an fUnit test suite with a minimum of changes. abort(reason) Calling abort in a test case will terminate the execution of the test case, just like a failed assert. The first argument is the reason for the abort. Abort should be used for tests that are not applicable to the current environment, or can not be run in the current environment. An aborting test indicates to the person running the tests that they should look at the reason given for the abort to see if it can be corrected, or if it is acceptable. Examples for aborting include: Platform specific tests being run on a different platform (see testSuperStress.testMacFileHandling), or tests that require access to a password protected resource which can not be distributed with a password for security reasons, requiring the user to set up a password somewhere, such as Manila XML-RPC client testing. Other Shipped Functions registerTestSuite(adr) Registers a test suite in the global test suite, run when the "Run Global Suite" option in the menu is chosen. unregisterTestSuite(adr) Unregisters a test suite registered with registerTestSuite. getTempTableAdr() Returns the address of a table that can be used as a temporary table. The table returned by this function will be automatically deleted at the end of the test suite execution, so it can be safer to use than alternative table creation mechanisms. fUnit Menu The fUnit menu can be installed by executing the following command: menu.install(@fUnit.menu) // CTRL-/ while the cursor is on this line will execute it The fUnit menu includes convenience functions to run the currently focused test suite or test case (with or without immediate errors), add the test suite to the global test suite, set the default runner, or run the global test suite in an infinite loop. Debugging Hints Two debugging hints that took me a while to learn: The Error Info dialog box, if you hold the mouse button over the "Go To" button, will give you a stack trace, which can be used to jump anywhere in the call stack. This is especially useful in the context of fUnit where the error always occurs in the test case, which isn't terribly useful information. While debugging a script, the Quick Script window is in the context of the script being currently debugged. You can run expressions from "inside" the script and see the results. --- NEW FILE: suiteName --- FrontierVcsFile:1:TEXT:suites.fUnit.suiteName fUnit --- NEW FILE: unregisterTestSuite --- FrontierVcsFile:1:scpt:suites.fUnit.unregisterTestSuite on unregisterTestSuite (adr) { delete(@fUnit.testGlobalSuite[string(adr)])} --- NEW FILE: readMe --- FrontierVcsFile:1:wptx:suites.fUnit.readMe This is the fUnit suite. Created by Jeremy Bowers who wants the Frontier Community to maintain and improve fUnit. [Why I Wrote It] [What It Does] [Things To Watch Out For] --- NEW FILE: init --- (This appears to be a binary file; contents omitted.) --- NEW FILE: registerTestSuite --- FrontierVcsFile:1:scpt:suites.fUnit.registerTestSuite on registerTestSuite (adr) { fUnit.testGlobalSuite[string(adr)] = adr} |