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.

Reply via email to