Yes, I forgot to mention the db.commit(). In fact, I would db.commit() after every successful insertion/delete/update this way your tests will be more in line?
I do not know any reason as to why web2py passes along args that it is not using. However I think this could be beneficial in certain scripts that need to rely on certain parameters, like I have a backup script that relies on the app name, I can look at the -S arg to determine what app I am currently working on for this script. There should be a way though to easily filter out web2py args from sys.argv in a script.... perhaps a helper function in shell.py that can do this for you when you call it. -Thadeus On Thu, Feb 25, 2010 at 11:33 AM, spiffytech <[email protected]> wrote: > *addendum: at the bottom of applications/api/controllers/test.py add > the line "db.commit()" to force web2py to clear the database. web2py > automatically uses database transactions. They are executed > automatically after a controller's function is called, which is why > you don't normally have to call commit yourself. In external scripts, > though, all inserts/updates/deletes in the database have to be > manually committed.) > > > On Feb 25, 12:12 pm, spiffytech <[email protected]> wrote: >> Works great! I added an "import copy" in db.py, and added a line in my >> unit test to rename "test_db" to "db" so that functions in the test >> script will use the test DB. >> >> For posterity, here is a complete working example of unit tests with >> web2py, with access to the database, using test database. The wiki >> article I create will explain each piece and why it's needed. >> >> ====== To run the unit tests, type this on the command line: ====== >> python web2py.py -S api -M -R applications/api/controllers/test.py # >> Fill in your own values for the test file and controller name >> ================================================ >> >> ====== applications/api/controllers/test.py ====== >> #!/usr/bin/python >> import sys >> import unittest >> >> from gluon.globals import Request # So we can reset the request for >> each test >> >> sys.arvg = sys.argv[5:] # web2py.py passes the whole command line to >> this script >> >> db = test_db # Rename the test database so that functions will use it >> instead of the real database >> execfile("applications/api/controllers/10.py", globals()) # Brings >> the controller's functions into this script's scope >> >> class TestListActiveGames(unittest.TestCase): >> def setUp(self): >> request = Request() # Use a clean request >> >> def testListActiveGames(self): >> # Set variables for the test function >> request.post_vars["game_id"] = 1 >> request.post_vars["username"] = "spiffytech" >> >> # Call a function from the controller "10.py" and print the >> dictionary it returns >> resp = list_active_games() >> print resp >> self.assertEquals(0, len(resp["games"])) >> >> # Manually specify tests to run; the web2py environment breaks >> unittest.main() >> # Taken from >> here:http://agiletesting.blogspot.com/2005/01/python-unit-testing-part-1-u... >> suite = unittest.TestSuite() >> suite.addTest(unittest.makeSuite(TestListActiveGames)) >> unittest.TextTestRunner(verbosity=2).run(suite) >> >> db(db.game.id>0).delete() # Empty out the test database so it's fresh >> for next time >> ====================================== >> >> ====== Added to the bottom of applications/api/models/db.py ====== >> # Create a test database that's laid out just like the "real" database >> import copy >> test_db = DAL('sqlite://testing.sqlite') # DB name and location >> for tablename in db.tables: # Copy tables! >> table_copy = [copy.copy(f) for f in db[tablename]] >> test_db.define_table(tablename, *table_copy) >> >> =================================================== >> >> On Feb 25, 11:36 am, Thadeus Burgess <[email protected]> wrote: >> >> > So the easiest way to use a testing db and your existing tables is to >> > automatically recreate them. >> >> > So assuming you are in the web2py environment and have access to ``db`` >> >> > >>> test_db = DAL('testing.sqlite') >> > >>> for tablename in db.tables: >> > >>> table_copy = [copy.copy(f) for f in db[tablename]] >> > >>> test_db.define_table(tablename, *table_copy) >> >> > This will create a new testing sqlite database. Then it will go >> > through all tables defined in db, then copy their fields to a list, >> > then it will define a new table in the sqlite with the copied fields. >> >> > Now any functions that you might want to unit test might rely on your >> > ``db`` object, which could be an issue depending on how you have your >> > code structured. >> >> > -Thadeus >> >> > On Thu, Feb 25, 2010 at 8:02 AM, Tiago Almeida >> >> > <[email protected]> wrote: >> > > I concur. Thanks :) >> >> > > On Thu, Feb 25, 2010 at 1:52 PM, Nicol van der Merwe >> > > <[email protected]> >> > > wrote: >> >> > >> Super awesome, thanks! >> >> > >> On Thu, Feb 25, 2010 at 3:43 PM, spiffytech <[email protected]> >> > >> wrote: >> >> > >>> I'm going to write up a nice, clear wiki article on unit testing with >> > >>> the unittest module based on what I learned in this discussion. I'll >> > >>> be sure to link to it here when it's done. >> >> > >>> On Feb 25, 4:20 am, Nicol van der Merwe <[email protected]> wrote: >> > >>> > Hi guys >> >> > >>> > This stuff is very interesting. I would like to request, if possible, >> > >>> > that >> > >>> > someone makes a web2pyslice or proper AlterEgo entry on how to setup >> > >>> > and run >> > >>> > these kinds of tests for web2py. I am very interested in setting up >> > >>> > tests >> > >>> > for my application but I'm a bit lost as I've never done so before >> > >>> > (plus I'm >> > >>> > unfortunately just too busy to research all this and make my own >> > >>> > slice). >> >> > >>> > It would be very much appreciated if this can be done :) >> >> > >>> > Nicolaas >> >> > >>> > On Thu, Feb 25, 2010 at 5:35 AM, spiffytech <[email protected]> >> > >>> > wrote: >> > >>> > > Thanks! Interesting article! My test cases now execute. However, I >> > >>> > > have a couple new questions, including a problem accessing the db >> > >>> > > in >> > >>> > > my controller. >> >> > >>> > > I modified my test file as AlterEgo 213 indicates so my unit tests >> > >>> > > can >> > >>> > > access the controller's functions. Here is my updated test file: >> >> > >>> > > ============== >> > >>> > > #!/usr/bin/python >> > >>> > > import sys >> > >>> > > import unittest >> >> > >>> > > from gluon.shell import exec_environment >> > >>> > > from gluon.globals import Request, Response, Session >> > >>> > > from gluon.storage import Storage >> >> > >>> > > sys.arvg = sys.argv[5:] # web2py.py passes the whole command line >> > >>> > > to >> > >>> > > this script >> >> > >>> > > class TestListActiveGames(unittest.TestCase): >> > >>> > > def setUp(self): >> > >>> > > self.request = Request() # Use a clean Request >> > >>> > > self.controller = exec_environment('applications/api/ >> > >>> > > controllers/10.py', request=self.request) >> >> > >>> > > def testListActiveGames(self): >> > >>> > > self.request.post_vars["game_id"] = 1 >> > >>> > > self.request.post_vars["username"] = "spiffytech" >> > >>> > > self.controller.list_active_games() >> >> > >>> > > suite = unittest.TestSuite() >> > >>> > > suite.addTest(unittest.makeSuite(TestListActiveGames)) >> > >>> > > unittest.TextTestRunner(verbosity=2).run(suite) >> > >>> > > ============== >> >> > >>> > > It is called with the command: >> >> > >>> > > ============== >> > >>> > > python web2py.py -S api -M -R applications/api/tests/test.py >> > >>> > > ============== >> >> > >>> > > The output is this: >> >> > >>> > > ============== >> > >>> > > web2py Enterprise Web Framework >> > >>> > > Created by Massimo Di Pierro, Copyright 2007-2010 >> > >>> > > Version 1.75.4 (2010-02-18 20:57:56) >> > >>> > > Database drivers available: pysqlite2 >> > >>> > > testListActiveGames (__builtin__.TestListActiveGames) ... ERROR >> >> > >>> > > ====================================================================== >> > >>> > > ERROR: testListActiveGames (__builtin__.TestListActiveGames) >> >> > >>> > > ---------------------------------------------------------------------- >> > >>> > > Traceback (most recent call last): >> > >>> > > File "applications/api/tests/test.py", line 19, in >> > >>> > > testListActiveGames >> > >>> > > self.controller.list_active_games() >> > >>> > > File "applications/api/controllers/10.py", line 47, in >> > >>> > > list_active_games >> > >>> > > games = >> > >>> > > db(((db.game.user1==username)|(db.game.user2==username)) & >> > >>> > > (db.game.victory==-2)).select(db.game.user1, db.game.user2, >> > >>> > > db.game.id, db.game.turn_number).as_list() >> > >>> > > NameError: global name 'db' is not defined >> >> > >>> > > ---------------------------------------------------------------------- >> > >>> > > Ran 1 test in 0.008s >> >> > >>> > > FAILED (errors=1) >> > >>> > > ============== >> >> > >>> > > Questions: >> > >>> > > 1) How can I get my controller to see the database? >> > >>> > > 2) Am I simply doing something very wrong? I would expect the >> > >>> > > web2py >> > >>> > > "- >> > >>> > > S" option to set up the environment, complete with my controller's >> > >>> > > functions, and Request/Storage/Response objects available for >> > >>> > > instantiation. However, several posts on the mailing list indicate >> > >>> > > that I need to run exec_enviroment() for access to my controllers. >> > >>> > > Also, the Request/Storage/Response objects don't seem to exist in >> > >>> > > the >> > >>> > > shell. >> >> > >>> > > On Feb 24, 2:52 pm, Thadeus Burgess <[email protected]> wrote: >> > >>> > > > Replacing the way you run test suites helps. Instead of using >> > >>> > > > .main() >> > >>> > > > add them manually. >> >> > >>> > > > I would suggest reading the following article, as it includes >> > >>> > > > methods >> > >>> > > > to aggregate your test suites together. >> >> > >>> > > > >http://agiletesting.blogspot.com/2005/01/python-unit-testing-part-1-u... >> >> > >>> > > > import sys >> > >>> > > > sys.argv = sys.argv[5:] >> >> > >>> > > > import unittest >> >> > >>> > > > class TestDefaultController(unittest.TestCase): >> >> > >>> > > > def testPrintStatement(self): >> > >>> > > > print "This line should print" >> > >>> > > > def testDatabaseRecordCount(self): >> > >>> > > > print "Records in database --- ", >> > >>> > > > db(db.auth_user.id>0).count() >> >> > >>> > > > suite = unittest.TestSuite() >> > >>> > > > suite.addTest(unittest.makeSuite(TestDefaultController)) >> > >>> > > > unittest.TextTestRunner(verbosity=2).run(suite) >> >> > >>> > > > python web2py.py -S pms -M -R >> > >>> > > applications/pms/test/testDefaultController.py >> > >>> > > > web2py Enterprise Web Framework >> > >>> > > > Created by Massimo Di Pierro, Copyright 2007-2010 >> > >>> > > > Version 1.75.4 (2010-02-18 14:55:03) >> > >>> > > > Database drivers available: SQLite3 >> > >>> > > > /home/thadeusb/web2py/applications/pms/modules/utils.py:16: >> > >>> > > > DeprecationWarning: the md5 module is deprecated; use hashlib >> > >>> > > > instead >> > >>> > > > import md5 >> > >>> > > > testDatabaseRecordCount (__builtin__.TestDefaultController) ... >> > >>> > > > Records in database --- 4052 >> > >>> > > > ok >> > >>> > > > testPrintStatement (__builtin__.TestDefaultController) ... This >> > >>> > > > line >> > >>> > > > should print >> > >>> > > > ok >> >> > >>> > > > ---------------------------------------------------------------------- >> > >>> > > > Ran 2 tests in 0.006s >> >> > >>> > > > OK >> >> > >>> > > > -Thadeus >> >> > >>> > > > On Wed, Feb 24, 2010 at 12:50 PM, spiffytech >> > >>> > > > <[email protected]> >> >> ... >> >> read more » > > -- > You received this message because you are subscribed to the Google Groups > "web2py-users" group. > To post to this group, send email to [email protected]. > To unsubscribe from this group, send email to > [email protected]. > For more options, visit this group at > http://groups.google.com/group/web2py?hl=en. > > -- You received this message because you are subscribed to the Google Groups "web2py-users" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/web2py?hl=en.

