The unit test already has access to web2py environment (and db or
anything else in your models). ``exec_environment`` just recreates a
blank environment, when executing your controller it executes it
outside of the current global scope.
Instead of running exec_environment on your controller, run
``execfile('/path/to/file', globals())``. This way the controller is
executed in the current environment instead of a new one.
The objects for Request Storage and Response don't exist even to your
web2py app, you always have to import them if you are using them. So
if you wanted to use Storage even in your models you would need an
"from gluon.storage import Storage" somewhere.
Do you want your unit tests to work on your actual database? Usually I
define a test.sqlite database that has
nothing in it, and during my tests gets data inserted, altered, and
then removed at the end of the tests.
-Thadeus
On Wed, Feb 24, 2010 at 9:35 PM, 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]> wrote:
>> > The confusion is not with doctests, but with external unit tests
>> > created with the 'unittest' module. Could you please post your
>> > testControllerDefault.py so I can see what you're doing different from
>> > me?
>>
>> > Please allow me to elaborate on my problems running unit tests with
>> > web2py. Here is my (very minimal) example unit test file:
>> > =================
>> > #!/usr/bin/python
>> > import unittest
>>
>> > class TestListActiveGames(unittest.TestCase):
>> > def testListActiveGames(self):
>> > print "This line should print out"
>>
>> > if __name__ == "__main__":
>> > unittest.main()
>> > =================
>>
>> > If the test is actually run, the command line will show "This line
>> > should print out".
>>
>> > The file is stored at <web2py_root>/applications/api/tests/test.py. My
>> > current working directory is <web2py_root>.
>> > I run the following command:
>>
>> > =======
>> > python web2py.py -S api -M -R applications/api/tests/test.py
>> > =======
>>
>> > And I get this output:
>>
>> > ================
>> > 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: pysqlite
>> > ================
>>
>> > The output does not contain the line, "This line should print out",
>> > indicating the unit tests are not being run.
>>
>> > I did some debugging and found that the last two lines, which are
>> > typical for unittest files, do not work when the file is executed by
>> > web2py. Rather than being equal to "__main__", which indicates the
>> > file is being executed from the command line, __name__ is equal to
>> > "__builtin__". I modified the code to work anyway:
>>
>> > ================
>> > #!/usr/bin/python
>> > import unittest
>>
>> > class TestListActiveGames(unittest.TestCase):
>> > def testListActiveGames(self):
>> > print "This line should print out"
>>
>> > unittest.main()
>> > ================
>>
>> > Now, I receive this output:
>>
>> > =======
>> > 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
>> > option -S not recognized
>> > Usage: web2py.py [options] [test] [...]
>>
>> > Options:
>> > -h, --help Show this message
>> > -v, --verbose Verbose output
>> > -q, --quiet Minimal output
>>
>> > Examples:
>> > web2py.py - run default set of tests
>> > web2py.py MyTestSuite - run suite 'MyTestSuite'
>> > web2py.py MyTestCase.testSomething - run
>> > MyTestCase.testSomething
>> > web2py.py MyTestCase - run all 'test*' test
>> > methods
>> > in MyTestCase
>> > =======
>>
>> > More debugging revealed that this is output by unittest.main(). The
>> > unittest module tries to parse arguments on the command line, sees the
>> > "-S" option that was passed to web2py.py, says "I don't know what '-S'
>> > means!", and exits.
>>
>> > To coerce unittest.main() to continue running, I made a quick hack to
>> > shell.py to strip out the extra command line arguments in sys.argv
>> > before test.py is run:
>>
>> > ==== gluon/shell.py, insert line 165 ====
>> > sys.argv = sys.argv[5:]
>> > ===================
>>
>> > I call the test file again, with the same command as before, and get
>> > 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
>>
>> > ----------------------------------------------------------------------
>> > Ran 0 tests in 0.000s
>>
>> > OK
>> > ================
>>
>> > The line, "This line should be printed out", is still not printed.
>> > Stepping through the code with Python's debugging module, pdb, shows
>> > that unittest.main() thinks it's being called from web2py.py, and not
>> > from test.py. unittest.main() looks for tests to run in web2py.py,
>> > finds none, and quits.
>>
>> > So now I'm stuck: the unittest module expects test.py to be run as a
>> > standalone script, but instead test.py is being executed within the
>> > scope of web2py.py, which is confusing the unittest module in several
>> > ways.
>>
>> > On Feb 24, 1:02 pm, Thadeus Burgess <[email protected]> wrote:
>> >> If I create a unittest
>>
>> >> init/tests/testControllerDefault.py
>>
>> >> and run the following command line
>>
>> >> python web2py.py -S <yourapp> -M -R
>> >> applications/init/tests/testControllerDefault.py
>>
>> >> My test is ran.
>>
>> >> I don't see what is so confusing.
>>
>> >> -Thadeus
>>
>> >> On Wed, Feb 24, 2010 at 12:01 PM, Thadeus Burgess <[email protected]>
>> >> wrote:
>> >> > consider controllers/default.py
>>
>> >> > def index():
>> >> > """
>> >> >>>> db(db.people.id > 0).count()
>> >> > '35'
>> >> > """
>> >> > return db(db.people.id > 0).count()
>>
>> >> > now when I run
>>
>> >> > `python web2py.py -T init/default/index`
>>
>> >> > produces my doctest.
>>
>> >> > -Thadeus
>>
>> >> > On Wed, Feb 24, 2010 at 2:28 AM, Jon Romero <[email protected]> wrote:
>> >> >> So, any idea/hint how to do it? Do we need a patch?
>>
>> >> >> On Feb 23, 10:40 pm, spiffytech <[email protected]> wrote:
>> >> >>> I'm running the latest version, 1.75.4.
>>
>> >> >>> On Feb 23, 11:35 am, Thadeus Burgess <[email protected]> wrote:
>>
>> >> >>> > What version of web2py are you running?
>>
>> >> >>> > What is the output of ``python web2py.py --help``
>>
>> >> >>> > -Thadeus
>>
>> >> >>> > On Tue, Feb 23, 2010 at 5:23 AM, Jon Romero <[email protected]>
>> >> >>> > wrote:
>> >> >>> > > ust put a prin "Hello world!" inside the test file, everything
>> >> >>> > > works ok. So, I suppose that this file tries to load AGAIN the
>> >> >>> > > web2py
>> >> >>> > > environment and there is
>> >> >>> > > some sort of mi
>>
>> >> >> --
>> >> >> 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
>> > 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.
>
>
--
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.