Index: openacs-4/packages/acs-core-docs/www/tutorial-debug.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/tutorial-debug.adp,v diff -u -r1.1.2.11 -r1.1.2.12 --- openacs-4/packages/acs-core-docs/www/tutorial-debug.adp 21 Jun 2016 07:44:36 -0000 1.1.2.11 +++ openacs-4/packages/acs-core-docs/www/tutorial-debug.adp 23 Jun 2016 08:32:46 -0000 1.1.2.12 @@ -16,19 +16,20 @@ OpenACS documentation staff.

Debugging

-Developer Support. The Developer Support -package adds several goodies: debug information for every page; the -ability to log comments to the page instead of the error log, and -fast user switching so that you can test pages as anonymous and as -dummy users without logging in and out.

-PostgreSQL. You can work directly with the -database to do debugging steps like looking directly at tables and -testing stored procedures. Start emacs. Type M-x sql-postgres. Press enter for -server name and use $OPENACS_SERVICE_NAME +Developer Support. The Developer +Support package adds several goodies: debug information for every +page; the ability to log comments to the page instead of the error +log, and fast user switching so that you can test pages as +anonymous and as dummy users without logging in and out.

+PostgreSQL. You can work directly +with the database to do debugging steps like looking directly at +tables and testing stored procedures. Start emacs. Type +M-x sql-postgres. +Press enter for server name and use $OPENACS_SERVICE_NAME for database name. You can use C-(up arrow) and C-(down arrow) for -command history.

Hint: "Parse error near *" usually means that an xql file wasn't -recognized, because the tcl file is choking on the *SQL* -placeholder that it falls back on.

Watching the server log. 

To set up real-time monitoring of the AOLserver error log, +command history.

Hint: "Parse error near *" usually means that an xql +file wasn't recognized, because the tcl file is choking on the +*SQL* placeholder that it falls back on.

Watching the server log. 

To set up real-time monitoring of the AOLserver error log, type

 less /var/lib/aolserver/$OPENACS_SERVICE_NAME/log/openacs-dev-error.log
@@ -68,8 +69,8 @@
 mfp::note::delete.Proc should return 0 for success.
 
 
-

Other things to test: try to delete someone else's note. Try to -delete your own note. Edit your own note. Search for a note.

+

Other things to test: try to delete someone else's note. Try +to delete your own note. Edit your own note. Search for a note.

Write automated tests

@@ -79,7 +80,7 @@ It seems to me that a lot of people have been asking for some guidelines on how to write automated tests. I've done several tests by now and have found the process to be -extremely easy and useful. It's a joy to work with automated +extremely easy and useful. It's a joy to work with automated testing once you get the hang of it.

Create the directory that will contain the test script and edit the script file. The directory location and file name are standards which are recognized by the automated testing package:

@@ -92,23 +93,24 @@
     ...
 }
 

To create a test case you call -aa_register_case test_case_name.. Once you've -created the test case you start writing the needed logic. We'll use -the tutorial package, "myfirstpackage," as an example. Let's say -you just wrote an API for adding and deleting notes in the notes packages -and wanted to test that. You'd probably want to write a test that -first creates a note, then verifies that it was inserted, then -perhaps deletes it again, and finally verifies that it is gone.

Naturally this means you'll be adding a lot of bogus data to the -database, which you're not really interested in having there. To -avoid this I usually do two things. I always put all my test code -inside a call to aa_run_with_teardown which basically means that -all the inserts, deletes, and updates will be rolled back once the -test has been executed. A very useful feature. Instead of inserting -bogus data like: set name -"Simon", I tend to generate a random script in order avoid -inserting a value that's already in the database:

+aa_register_case test_case_name.. Once you've
+created the test case you start writing the needed logic. We'll
+use the tutorial package, "myfirstpackage," as an
+example. Let's say you just wrote an API for adding and deleting notes in
+the notes packages and wanted to test that. You'd probably want
+to write a test that first creates a note, then verifies that it
+was inserted, then perhaps deletes it again, and finally verifies
+that it is gone.

Naturally this means you'll be adding a lot of bogus data to +the database, which you're not really interested in having +there. To avoid this I usually do two things. I always put all my +test code inside a call to aa_run_with_teardown which basically +means that all the inserts, deletes, and updates will be rolled +back once the test has been executed. A very useful feature. +Instead of inserting bogus data like: set name "Simon", I tend to +generate a random script in order avoid inserting a value +that's already in the database:

 set name [ad_generate_random_string]
-

Here's how the test case looks so far:

+

Here's how the test case looks so far:

 aa_register_case mfp_basic_test {
     My test
 } {
@@ -118,39 +120,42 @@
 
        }
 }
-

Now let's look at the actual test code. That's the code that -goes inside -test_code {}. We -want to implement test case API-001, "Given an object id from -API-001, invoke mfp::note::get. Proc should return the specific -word in the title."

+

Now let's look at the actual test code. That's the code +that goes inside -test_code {}. +We want to implement test case API-001, "Given an object id +from API-001, invoke mfp::note::get. Proc should return the +specific word in the title."

       set name [ad_generate_random_string]
       set new_id [mfp::note::add -title $name]
       aa_true "Note add succeeded" ([info exists new_id] && $new_id ne "")
 

To test our simple case, we must load the test file into the system (just as with the /tcl file in the basic tutorial, since the -file didn't exist when the system started, the system doesn't know -about it.) To make this file take effect, go to the APM and choose -"Reload changed" for "MyFirstPackage". Since we'll be changing it -frequently, select "watch this file" on the next page. This will -cause the system to check this file every time any page is -requested, which is bad for production systems but convenient for -developing. We can also add some aa_register_case flags to make it -easier to run the test. The -procs flag, which indicates which procs +file didn't exist when the system started, the system +doesn't know about it.) To make this file take effect, go to +the APM +and choose "Reload changed" for +"MyFirstPackage". Since we'll be changing it +frequently, select "watch this file" on the next page. +This will cause the system to check this file every time any page +is requested, which is bad for production systems but convenient +for developing. We can also add some aa_register_case flags to make +it easier to run the test. The -procs flag, which indicates which procs are tested by this test case, makes it easier to find procs in your -package that aren't tested at all. The -cats flag, setting categories, makes it +package that aren't tested at all. The -cats flag, setting categories, makes it easier to control which tests to run. The smoke test setting means that this is a basic test case that can and should be run any time you are doing any test. (a definition of "smoke test")

Once the file is loaded, go to ACS Automated Testing and click on myfirstpackage. You should see your test case. Run it and examine the results.

-TCLWebtest tests

API testing can only test part of our package - it doesn't test -the code in our adp/tcl pairs. For this, we can use TCLwebtest. -TCLwebtest must be installed for this test to work. -This provides a library of functions that make it easy to call a page -through HTTP, examine the results, and drive forms. TCLwebtest's -functions overlap slightly with acs-automated-testing; see the -example provided for one approach on integrating them.

+TCLWebtest tests

API testing can only test part of our package - it doesn't +test the code in our adp/tcl pairs. For this, we can use +TCLwebtest. TCLwebtest must be installed +for this test to work. This provides a library of functions that make it easy to call a page +through HTTP, examine the results, and drive forms. +TCLwebtest's functions overlap slightly with +acs-automated-testing; see the example provided for one approach on +integrating them.

Example

Now we can add the rest of the API tests, including a test with @@ -218,15 +223,15 @@ \@author Peter Marklund } { - # we need to get a user_id here so that it's available throughout + # we need to get a user_id here so that it's available throughout # this proc set user_id [db_nextval acs_object_id_seq] set note_title [ad_generate_random_string] # NOTE: Never use the aa_run_with_teardown with the rollback switch # when running Tclwebtest tests since this will put the test code in - # a transaction and changes won't be visible across HTTP requests. + # a transaction and changes won't be visible across HTTP requests. aa_run_with_teardown -test_code { @@ -276,7 +281,7 @@ # 1) go directly to the database to get the id # 2) require an API function that takes name and returns ID # 3) screen-scrape for the ID - # all options are problematic. We'll do #1 in this example: + # all options are problematic. We'll do #1 in this example: set note_id [db_string get_note_id_from_name " select item_id