Contents
Phase 2
Andrew Dalke (with contribution by Andrew Kuchling) converted the test suite to nose, and made some improvements.
See: http://groups.google.com/group/akara-dev/browse_thread/thread/5519a8ecf38e6fc
You can still run the test suite as follows:
cd $AMARASRC/test sh testall.sh
Phase 1
This effort was pretty much completed by early 2009, thanks to help from the community. These notes are obsolete, but preserved for the record.
We'll be migrating the test suites from the old Ft.Lib.TestSuite infrastructure to unittest, and porting tests from Amara 1.x tests to match the new APIs.
We'll need plenty of help. If you're up to help, please notify the core developers. Start by joining the Akara dev mailing list and reviewing Amara/Developer_notes
Contents
Running tests
On UNIXy systems, you should be able to just tun test/testall.sh .
Suggested order of migration
This is a broad view, but most of the action will be in specific, present assignments, tracked in the next section.
4Suite:test/lib -> test/lib
4Suite:test/Xml/Core -> test/tree
4Suite:test/Xml/Borrowed -> test/tree
Amara:bindery -> test/bindery
4Suite:test/Xml/XPath/Core -> test/xpath
4Suite:test/Xml/XPath/Borrowed -> test/xpath
4Suite:test/Xml/Xslt/Core -> test/xslt
4Suite:test/Xml/Xslt/Exslt -> test/xslt
4Suite:test/Xml/Xslt/Borrowed -> test/xslt
Current test suite assignments and wish-list
The test suite from Amara 1.x bindery --claimed by LM Morillas
A *new* test suite (in test/tree) incorporating API details listed in the document http://wiki.xml3k.org/Amara2/Whatsnew --claimed by Chimezie Ogbuji
Some portion of the 4Suite XSLT ("borrowed" tests):
tests starting with "a" through "c" --claimed by L Stedman
tests starting with "d" --claimed by G Higgins
tests starting with "e" through "i" --claimed by G Higgins
tests starting with "j" through "l" --claimed by G Higgins
tests starting with "m" --claimed by G Higgins
tests starting with "n" through "r" --claimed by G Higgins
tests starting with "s" through "t" --claimed by G Higgins
tests starting with "u" through "x" --claimed by JL Clark
Any of the above selections can be done in a few hours' work.
General notes on test support for Amara 2.x
We will need to provide a test support module because unittest's loader is pretty dumb out of the box. It's probably enough to just pull in Pythons ( http://svn.python.org/view/python/branches/release25-maint/Lib/test/test_support.py?rev=60337&view=markup ). Until we sort that out top-level test suites will not automatically run, but please don't avoid them for that reason.
Update: we now have amara.test, which handles this. Just use:
from amara.test import test_main, test_case
#Test code here...
class a_test_suite(unittest.TestSuite):
class a_test_case(test_case):
def test_method(self):
self.assert_(True)
if __name__ == '__main__':
test_main()
the entire module is wrapped in a TestSuite with the declared TestSuite subclasses added in alphabetical order followed by any amara.test.test_case (unittest.TestCase subclasses) added after that also sorted likewise.
Note: The amara.test.test_case subclasses in the TestSuite subclass are added in alphabetical order; their corresponding suite test methods are already added sorted by unittest, so we just extended that idea for amara.test.test_case
General notes on migration process
For Amara the main task is to update imports. For 4Suite we also need to port from the old Ft.Lib.Test machinery to unittest.
Each inner startGroup...groupDone will become a new class that subclasses amara.test.test_case, which in turn subclasses unittest.TestCase.
Each outer level startGroup...groupDone becomes either an instance of unittest.TestSuite or a new test module file, depending on your judgment. Additional levels of groups become nested TestSuite or further broken-down files. You can add either a amara.test.test_case or a nested TestSuite to a TestSuite.
Everything from tester.startTest to tester.testDone will become a test function (a method that starts with test).
The description string passed into startTest will become the first line for a docstring of the new test function.
tester.compare will map to one of the assert... functions of unittest, based on your judgment.
An example:
tester.startGroup('file:/// and file://localhost/ equivalence')
tester.startTest('equivalent key in UriDict')
uris = Uri.UriDict()
uris['file:///path/to/resource'] = 0
tester.compare(True, 'file://localhost/path/to/resource' in uris, 'RFC 1738 localhost support failed')
tester.testDone()
tester.startTest('value of 2 equivalent keys')
uris = Uri.UriDict()
uris['file:///path/to/resource'] = 1
uris['file://localhost/path/to/resource'] = 2
tester.compare(2, uris['file:///path/to/resource'], 'RFC 1738 localhost support failed')
tester.testDone()
tester.groupDone()
would become:
class test_file_uri_localhost_equiv:
'''file:/// and file://localhost/ equivalence'''
def test_uri_dict(self):
'''equivalent key in UriDict'''
uris = Uri.UriDict()
uris['file:///path/to/resource'] = 0
self.assert_('file://localhost/path/to/resource' in uris, 'RFC 1738 localhost support failed')
return
def test_equiv_keys(self):
'''value of 2 equivalent keys'''
uris = Uri.UriDict()
uris['file:///path/to/resource'] = 1
uris['file://localhost/path/to/resource'] = 2
assertEqual(2, uris['file:///path/to/resource'], 'RFC 1738 localhost support failed')
This is part of the port from
http://cvs.4suite.org/viewcvs/4Suite/test/Lib/test_uri.py?rev=1.34&view=markup
to
http://hg.4suite.org/amara/trunk/file/tip/test/lib/test_iri.py
In the old test suite we often used parameter-driven tests with the like of an (input, expected) tuple over which we iterated. Here is a suggestion for how to port those
Before:
tester.startGroup("PercentEncode and PercentDecode")
for unencoded, encoded in percentEncodeTests:
if len(unencoded) > 10:
test_title = unencoded[:11] + '...'
else:
test_title = unencoded
tester.startTest(repr(test_title))
tester.compare(encoded, Uri.PercentEncode(unencoded))
tester.compare(unencoded, Uri.PercentDecode(encoded))
tester.testDone()
...
tester.groupDone()
After:
from amara.test import test_main, test_case
class Test_percent_encode_decode(test_case):
'''PercentEncode and PercentDecode'''
#def test_percent_encode(self):
@classmethod
def create_test_percent_encodes(cls):
'''Percent encode'''
for count, (unencoded, encoded) in enumerate(percent_encode_tests):
#print "Creating test", "test_percent_encode_%i"%count
def test_percent_encode_template(self, count=count, unencoded=unencoded, encoded=encoded):
if len(unencoded) > 10:
test_title = unencoded[:11] + '...'
else:
test_title = unencoded
self.assertEqual(encoded, iri.percent_encode(unencoded))
self.assertEqual(unencoded, iri.percent_decode(encoded))
setattr(cls, "test_percent_encode_%i"%count, test_percent_encode_template)
return
Test_percent_encode_decode.create_test_percent_encodes()
Another approach to migrating batch tests
The new test
http://hg.4suite.org/amara/trunk/file/tip/test/xpath/test_expressions.py
Is basically a roll-up of
http://hg.4suite.org/amara/trunk/file/tip/test/xpath/test_basic_expr.py (ported from http://cvs.4suite.org/viewcvs/*checkout*/4Suite/test/Xml/XPath/Core/test_literal_expr.py )
http://hg.4suite.org/amara/trunk/file/tip/test/xpath/test_core_functions.py (ported from http://cvs.4suite.org/viewcvs/*checkout*/4Suite/test/Xml/XPath/Core/test_function_calls.py )
http://hg.4suite.org/amara/trunk/file/tip/test/xpath/test_nodeset_expr.py
http://hg.4suite.org/amara/trunk/file/tip/test/xpath/test_boolean_expr.py
http://hg.4suite.org/amara/trunk/file/tip/test/xpath/test_numeric_expr.py
You can run it, and it delegates to each of the other modules in turn (these can still be run individually). It's also an example of aggregating multiple modules into a single TestSuite.
Basically this approach uses metaclasses instead of @classmethod. As Jeremy puts it: "lots of fun with metaclasses!"
treecompare
Amara comes with a markup-savvy comparison function, smart enough to ignore order of attributes and such. For a comprehensive example of usage, see the _assert_result function in amara/test/xslt/init.py . The basic usage, for XML comparison, is:
diff = treecompare.xml_diff(out, ATOMENTRY1)
diff = '\n'.join(diff)
self.assertFalse(diff, msg=(None, diff))
Notes for specific assignments
amara2/test/xslt (especially "Borrowed")
The old Xml/Xslt/Borrowed tests will be ported to a new source/transform/expected trio of files.
Here is an example of an already ported test case (Xml/Xslt/Borrowed/af_2000922.py):
from Xml.Xslt import test_harness
source_1 = "..."
sheet_1 = "..."
expected_1 = "..."
def Test(tester):
source = test_harness.FileInfo(string=source_1)
sheet = test_harness.FileInfo(string=sheet_1)
test_harness.XsltTest(tester, source, [sheet], expected_1,
title='output bug')
return
would become three files in the amara/test/xslt/borrowed directory:
af_20000922.xml: the contents of source_1
af_20000922.xslt: the contents of sheet_1
af_20000922.out: the contents of expected_1
For those tests that have multiple tests in one Python source file, simply append a _nn to the base name, where nn matches the number suffix of the string inputs.
If an XsltTest() tests for an exception or uses top-level parameters, skip it, but indicate those tests here as they will need more attention.
More notes
For now we'll replace the test files and reorg as makes sense. We may ned some lightweight harness machinery for 4Suite, e.g. a test_support module that each test module will need to import (this will also help abstract the platform differences). In particular we might need to come up with our own TestLoader to give us flexibility for combination of TestSuites and amara.test.test_case into each file. We might also need setUp() and tearDown() methods, which are called before each test function (amara.test.test_case.testXXX).
http://oakwinter.com/code/category/python/unittest/
Use decorators to e.g. mark knownFail tests. Keep all extensions simple, in one file that's easy to find and easy to follow (i.e. well-documented. If there must be magic, given unittest's limitations, keep it all in one place, and well explained.
The "core" and "borrowed" tests should be merged into one directory, with the "borrowed test" terminology changing, perhaps to "field test" or "user test" (i.e. a test based on an observation by a user in the field). This will tend to explode the number of test files within the directory, so good naming will be key.
Outdated assignments
This section is quite out of date. Present assignments are above. If you completed some work in this section, but didn't turn it in, please e-mail this info to the akara-dev list
Uche will work on test/Lib and Uche and Jeremy on specializations to the test harness
amara2/test/xmlcore
Ported from 4Suite/test/Xml/Core/:
- test_domlette* - John C
- test_domlette_reader.py - Chime O.
- test_xpdate - John C
- test_xmlstring - Eric L
- test_saxlette* - Eric L
- test_format_number - Eric L
- test_catalog - Eric L
- test_printers - Eric L
- test_ranges - Eric L
- test_xinclude - Eric L
- test_markup_writer - Luis MM
- test_parse_fragment - Luis MM
- test_convenience_parse - Luis MM
- test_nss - Joel B
- test_relax_ng - Joel B
- test_c14n - Uche
Porting from 4Suite/test/Xml/Borrowed/:
If anyone finishes the above and is ready to move on, mention to the list and move on to port 4Suite/test/Xml/Borrowed/
amara2/test/bindery
Soon to be assigned. Mostly to Luis MM and Joel B
amara2/test/xpath
Jeremy is working on ports from 4Suite/test/Xml/XPath/Core/:
Need to assign tests from 4Suite/test/Xml/XPath/Borrowed/:
