PyOGP Package Unittests

From Second Life Wiki
Revision as of 10:35, 3 September 2009 by Enus Linden (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Overview

Each package in the lib should have unit tests, which cover as much code as possible. The unit tests evaluate the integrity of the library code itself, in terms of apis, code paths, and dependencies.

Packages under unit test right now:

pyogp.lib.base
pyogp.lib.client

Python test types

unittest

Unit tests are written as standard python unittest implementations. For more on this, see http://docs.python.org/library/unittest.html.

doctest

doctests are narrative sample uses of code, that may be run via various test wrappers. For more, see http://docs.python.org/library/doctest.html.

Running tests

nose

We use Nose! http://somethingaboutorange.com/mrl/projects/nose/0.11.1/

Nose Install Steps:
# http://somethingaboutorange.com/mrl/projects/nose/nose-0.11.1.tar.gz
# gzip -dc nose-0.11.1.tar.gz | tar xf -
# cd nose-0.11.1
# python setup.py install

in buildout

After running buildout, there will be a bin/unittests script available. Simply run it, passing which package's unit tests to run...

bin/unittests --where=src/pyogp.lib.client/
bin/unittests --where=src/pyogp.lib.base/

Evaluating test coverage

Nose has a great tie into the coverage module (http://nedbatchelder.com/code/modules/rees-coverage.html), which evaluates code coverage by our tests. Buildout automatically installs the necessary module, or, you can install it to your python instance via "easy_install coverage".

To run the unittests via a buildout instance, add the following flags (making sure package names match up):

--with-coverage --cover-package=pyogp.lib.client

For more on the nose test wrapper, see bin/unittests -h.

Using installed packages

You are on your own if you want to grab the modules separately, though Enus is working to support a simple per package test runner.

Ensure the necessary modules are in your python instance's path:

Here's what the buildout generated nose test wrapper looks like on Enus' machine:

#!/Users/enus/svn/buildout/bin/python

import sys
sys.path[0:0] = [
  '/Users/enus/svn/buildout/eggs/uuid-1.30-py2.5.egg',
  '/Users/enus/svn/buildout/eggs/indra.base-1.0-py2.5.egg',
  '/Users/enus/svn/buildout/eggs/eventlet-0.8.14-py2.5.egg',
  '/Users/enus/svn/buildout/eggs/wsgiref-0.1.2-py2.5.egg',
  '/Users/enus/svn/buildout/src/pyogp.lib.base',
  '/Users/enus/svn/buildout/eggs/nose-0.11.1-py2.5.egg',
  '/Users/enus/svn/buildout/eggs/WebOb-0.9.6.1-py2.5.egg',
  '/Users/enus/svn/buildout/eggs/elementtree-1.2.7_20070827_preview-py2.5.egg',
  '/Users/enus/svn/buildout/eggs/setuptools-0.6c9-py2.5.egg',
  '/Users/enus/svn/buildout/eggs/pyOpenSSL-0.9-py2.5-macosx-10.5-i386.egg',
  '/Users/enus/svn/buildout/eggs/greenlet-0.2-py2.5-macosx-10.5-i386.egg',
  '/Users/enus/svn/buildout/eggs/indra.util-1.0-py2.5.egg',
  ]

import nose

if __name__ == '__main__':
    nose.main(argv=['nose']+sys.argv[1:])

Running tests:

  1. nosetests --where={path to src/pyogp.lib.base}
  2. see nosetests --help for more info

Code Coverage

Currently, coverage of code by unittest is OK, but, we need to improve it!

pyogp.lib.client

Current coverage:

[11:32:17] [enus@sune] buildout$ bin/unittests --where=src/pyogp.lib.client/ --with-coverage --cover-package=pyogp.lib.client

Name Stmts Exec Cover Missing


pyogp.lib.client 1 1 100% pyogp.lib.client.agent 513 164 31% 35-49, 71, 82, 179-180, 213, 216, 222-239, 272, 281-303, 311-331, 336-345, 350-359, 365-431, 437-446, 452-457, 477-486, 496-533, 552-570, 575-580, 586-587, 593, 600-615, 620-632, 637-644, 649, 658-674, 679-700, 705-746, 751-757, 762-787, 792-804, 818-872, 881-925, 930-953, 967-980, 986-1017, 1024-1044, 1052-1068, 1073, 1080-1086, 1090-1093, 1098-1101, 1105, 1109-1112, 1117-1119 pyogp.lib.client.appearance 151 76 50% 76-83, 89-97, 122-135, 151-162, 165, 171, 179-183, 194-199, 216-226, 234-249, 257-280, 294-310, 335, 341-347, 354-355 pyogp.lib.client.assets 125 30 24% 58, 68-123, 145-168, 174, 177, 185-192, 202-211, 215-217, 222-231, 234-261 pyogp.lib.client.event_queue 153 90 58% 31, 39, 64, 73, 104, 107-109, 118-125, 136-149, 173, 179, 184-215, 220-235, 248-273 pyogp.lib.client.event_system 89 71 79% 43, 60-67, 82-84, 173-174, 184-185, 193-200, 205, 210 pyogp.lib.client.exc 136 78 57% 36, 42, 45, 57-60, 64, 73, 76, 86-90, 94, 116, 119, 128, 131, 141-142, 145, 160-161, 164, 173-174, 177, 186-187, 190, 199-200, 203, 212-213, 216, 225-226, 229, 238-239, 242, 261, 273, 285, 302, 305, 317, 330, 333, 345, 348, 356, 359, 367, 370 pyogp.lib.client.groups 243 54 22% 65-79, 85-90, 97-111, 116-130, 135-144, 149-156, 174-205, 210-215, 221-224, 229-236, 241, 246-252, 262-273, 278-287, 292-310, 315, 320, 325-329, 333-339, 347-359, 364, 369-375, 380-382, 387-404, 424-451, 469-477, 484-488, 492, 496-520, 524-527 pyogp.lib.client.inventory 495 181 36% 73-80, 84, 88, 93-152, 157-164, 173-180, 191-193, 199-202, 227, 243, 275-277, 295-302, 312, 320-322, 332-338, 350, 362, 373, 378-384, 389-391, 399-408, 417-431, 436-468, 473-480, 522, 559-560, 567-572, 577, 582, 587, 592, 599-601, 606-630, 635-659, 664-697, 702-705, 710-742, 749, 754, 759, 764-775, 780, 784-812, 816-867, 897, 902-909, 914, 924-933, 938, 948-956, 1021-1027, 1036-1040, 1046-1063, 1075-1104, 1109-1150 pyogp.lib.client.login 205 176 85% 111, 129, 150, 171, 201, 210, 225-226, 234, 281-283, 293, 300-301, 308-313, 341, 343, 347, 361, 370, 374-377, 389, 406, 433 pyogp.lib.client.objects 612 276 45% 114, 120-132, 143, 159-190, 200, 207, 212-220, 225-227, 235-239, 244-257, 262-284, 289-294, 298-303, 329-332, 340, 354, 357, 367-376, 382-391, 425-461, 466-633, 639-663, 691-693, 729-859, 907-908, 919-967, 971-973, 977-1014, 1037-1067, 1173, 1183-1195, 1203-1205, 1213-1215, 1223-1225, 1233-1235, 1242-1244, 1251-1253, 1260, 1268-1276, 1283, 1291-1299, 1304, 1309-1323, 1328-1344, 1351, 1358-1365, 1372, 1379-1386 pyogp.lib.client.parcel 372 69 18% 99-112, 122-127, 132-185, 190-212, 219-234, 239-279, 284-299, 304-307, 311, 315, 319, 325-328, 333-338, 343-359, 364-376, 381-389, 394-412, 417-424, 429-447, 452-456, 462, 467-482, 489, 521, 554, 587, 615, 642, 670, 696-699, 704-713, 721-723, 747-750, 755-763, 768-787, 797-873, 878-882, 889, 921, 945, 978, 1006, 1030, 1051, 1083, 1107, 1139 pyogp.lib.client.permissions 23 18 78% 57-61 pyogp.lib.client.region 259 91 35% 34, 40-41, 43, 78, 85, 96, 189-195, 199, 223-229, 237-240, 245-250, 255-272, 277-285, 289-315, 321-331, 336-351, 356-361, 366-367, 373-385, 390-396, 401-407, 412-416, 433-448, 453-460, 465-472, 477-514, 519-523, 528-529, 535-565, 570, 575, 580-586, 597-620, 623 pyogp.lib.client.settings 67 55 82% 146-155, 178-179 pyogp.lib.client.visualparams 502 495 98% 42-44, 50-53


TOTAL 3946 1925 48%


Ran 94 tests in 14.455s

FAILED (errors=1)

pyogp.lib.base

Nice coverage!

[11:32:40] [enus@sune] buildout$ bin/unittests --where=src/pyogp.lib.base/ --with-coverage --cover-package=pyogp.lib.base

Name Stmts Exec Cover Missing


pyogp.lib.base 1 1 100% pyogp.lib.base.datatypes 106 73 68% 45, 49, 53, 72, 75, 80, 88-91, 107, 111, 115, 119, 136-141, 150, 153, 158, 184-189, 208, 213, 222-225, 230-232 pyogp.lib.base.exc 136 77 56% 33, 36, 42, 45, 57-60, 64, 73, 76, 86-90, 94, 116, 119, 128, 131, 141-142, 145, 160-161, 164, 173-174, 177, 186-187, 190, 199-200, 203, 212-213, 216, 225-226, 229, 238-239, 242, 261, 273, 285, 302, 305, 317, 330, 333, 345, 348, 356, 359, 367, 370 pyogp.lib.base.message 1 1 100% pyogp.lib.base.message.circuit 84 69 82% 39, 78-83, 91, 98-104, 134, 149-150, 154 pyogp.lib.base.message.data 4 4 100% pyogp.lib.base.message.data_packer 63 48 76% 66, 69-70, 73-75, 78, 81, 84-87, 92, 99, 101 pyogp.lib.base.message.data_unpacker 65 57 87% 76-80, 83-84, 91, 94, 100 pyogp.lib.base.message.llsd_builder 39 38 97% 34 pyogp.lib.base.message.message 63 42 66% 35-36, 43-44, 109-110, 114, 119-136, 141 pyogp.lib.base.message.message_handler 44 29 65% 38, 47-49, 60, 75-78, 88-90, 93, 97, 100-102, 106 pyogp.lib.base.message.msgtypes 83 76 91% 45-47, 118, 125, 127, 143 pyogp.lib.base.message.template 133 105 78% 46, 63, 71, 84, 87-92, 98, 101, 105, 116, 119, 121, 145, 148, 151, 154, 187, 190, 196, 199, 202, 205, 208, 211, 214 pyogp.lib.base.message.template_dict 58 52 89% 49-52, 100, 106 pyogp.lib.base.message.template_parser 228 187 82% 172-173, 177, 223, 252, 266-278, 281-294, 297-305, 309-317, 320 pyogp.lib.base.message.udpdeserializer 180 139 77% 52, 76-78, 116-125, 132, 138, 145-147, 170, 175, 184, 193, 197, 220-230, 240, 262, 274-275, 296-297, 308-315, 321-323, 335 pyogp.lib.base.message.udpdispatcher 149 108 72% 80, 111, 124-130, 135, 141, 147, 164, 173, 178, 190, 192, 203-211, 220-224, 242-255, 281, 287-288, 297-301, 305 pyogp.lib.base.message.udpserializer 66 57 86% 72, 89, 110-111, 131, 138, 143-147 pyogp.lib.base.network 1 1 100% pyogp.lib.base.network.net 27 14 51% 31, 35-38, 41-50, 66 pyogp.lib.base.settings 67 45 67% 146-155, 167-198 pyogp.lib.base.utilities 1 1 100% pyogp.lib.base.utilities.events 35 17 48% 36-38, 43-51, 55-65, 69, 73-74, 78 pyogp.lib.base.utilities.helpers 107 45 42% 48, 54-58, 64-71, 77-81, 87-100, 106-119, 125-128, 136, 150, 156, 162, 187, 204, 208, 213, 267-268, 270, 275-276, 287-292, 296-305, 309


TOTAL 1741 1286 73%


Ran 71 tests in 17.255s

OK