What about adding to the shell environment a variable containing the name of the current app? Then scripts like yours could still get the information they need, and the extra values could be removed from sys.argv without a script having to import a helper.
Does this count as breaking backward-compatibility in web2py, or does web2py only claim compatibility for models/views/controller code? On Feb 25, 1:42 pm, Thadeus Burgess <[email protected]> wrote: > 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 > > athttp://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.

