Login | Register
My pages Projects Community openCollabNet

Discussions > dev > Re: [maxq-dev] Obese scripts

maxq
Discussion topic

Back to topic list

Re: [maxq-dev] Obese scripts

Author fcohen
Full name Frank Cohen
Date 2004-09-27 22:14:42 PDT
Message On Sep 27, 2004, at 8:59 PM, Oliver Bock wrote:

> Frank,
>
> Sorry, now I see that you have provided an example. I like that your
> logging is self-contained. Perhaps we should include a self.log()
> function in the HttpBaseTest that will output just like "print"
> normally, but which can be turned off by calling another function,
> like self.suppressLog() or self.setLogLevel(). This way it won't get
> in the way of normal users, but is available for people who want it.

Yeh, I'm at the same quandary. I expanded the log function to allow
users to choose where they are logging-to: file, console, jdbc
datasource. Now it's even more complex and I'm not sure if it belongs
in a baseclass?


>
> Your script looks reasonable as a JUnit test, except that it is not
> derived from TestCase. I have not used MaxQ scripts as real JUnit
> tests, but since they are derived form TestCase it should just be a
> matter of compiling them into Java classes (jythonc) and including
> maxq.jar in the classpath.
>

Yes, it's the calling package that will want to know that the script
implement's TestCase's methods. So it's fine not to subclass TestCase
since it implements all of its methods.


>
> Oliver
>
> --
> On 28/09/2004, at 08:21, Frank Cohen wrote:
>
>> One other thing... In an earlier email I proposed using a log-level
>> variable to determine which information get printed to the console as
>> the test script operations. Did you consider this? Below is my sample
>> script that incorporates the log-level.
>>
>> -Frank
>>
>>
>> A few TestMaker users have asked me about support of jUnit. It seems
>> to me that the TestMaker recorder should be outputing tests that
>> conform to a jUnit TestCase. Below is a script that accomplishes
>> this. I am seeking your input, feedback and criticism of this script
>> before I make any changes to the recorder.
>>
>> '''
>> Agent name: mytest.py
>> Created by: TestMaker Agent Recorder
>> Created on:
>>
>> Purpose:
>> Calculates a Transaction-Per-Second index for a
>> Web-enabled HTTP application
>>
>> For details on TestMaker see http://www.pushtotest.com
>> '''
>>
>> from com.pushtotest.tool.​protocolhandler import ProtocolHandler,
>> HTTPProtocol
>> from com.pushtotest.tool.response import Response
>> from java.util import Date
>> from java.lang import Exception
>> from junit.framework import TestCase
>>
>> '''
>> The test class implements the steps recorded while watching a user
>> operate the application using a browser.
>> '''
>>
>> class mytest:
>>
>> def __init__( self, loglvl = 0 ):
>> ''' Initialization '''
>> self.loglevel = loglvl
>> if self.loglevel > 0:
>> print "mytest: Initialize"
>> self.steps = 0 # Counter of steps in transaction
>> self.http = ProtocolHandler.getP​rotocol("http")
>>
>> def setUp( self ):
>> ''' Add any needed set-up code here. '''
>> if self.loglevel > 0:
>> print "mytest: setUp"
>> pass
>>
>> def runTest( self ):
>> ''' Run the test '''
>> if self.loglevel > 0:
>> print "mytest: runTest"
>>
>> self.http.setUrl(
>> '''http://examples.push​totest.com/responder​/htmlresponder?
>> file=file1.html''' )
>> self.http.setType( HTTPProtocol.GET )
>> self.response = self.http.connect()
>> TestCase.assertEquals("Step 1 failed while trying to get: '"
>> + \
>> self.http.getURL("http"), 200,
>> self.response.getResponseCode() )
>> self.logit()
>>
>> self.http.setUrl(
>> '''http://examples.push​totest.com/responder​/htmlresponder''' )
>> self.http.setType( HTTPProtocol.POST )
>> self.body = ProtocolHandler.getBody( 'http' )
>> self.http.setBody( self.body )
>> self.body.addParamet​er('''firstname''', '''frank''')
>> self.body.addParamet​er('''lastname''', '''cohen''')
>> self.body.addParamet​er('''phone''', '''''')
>> self.body.addParamet​er('''account''', '''''')
>> self.body.addParamet​er('''amount''', '''''')
>> self.body.addParamet​er('''Transfer''', '''Transfer Funds''')
>> self.response = self.http.connect()
>> TestCase.assertEquals("Step 2 failed while trying to post: '"
>> + self.http.getURL("http"), 200, self.response.getResponseCode() )
>> self.logit()
>>
>> self.http.setUrl(
>> '''http://examples.push​totest.com/responder​/htmlresponder?
>> file=file3.html''' )
>> self.http.setType( HTTPProtocol.GET )
>> self.response = self.http.connect()
>> TestCase.assertEquals("Step 3 failed while trying to get: '"
>> + self.http.getURL("http"), 200, self.response.getResponseCode() )
>> self.logit()
>>
>> def logit( self ):
>> self.steps += 1
>> if self.loglevel > 1:
>> print "mytest: runTest, step", self.steps
>>
>> def tearDown( self ):
>> ''' Add any needed code to end the test here. '''
>>
>> def setLoglevel( self, loglv ):
>> self.loglevel = loglv
>> def getLogLevel( self ):
>> return self.loglevel
>> def getSteps( self ):
>> return self.steps
>>
>> # Code to instantiate and run the test
>>
>> if __name__ == 'main':
>>
>> print "===================​====================​================"
>> print " myTest.py: Functional test of a Web application "
>> print "===================​====================​================"
>> print "Test recorded by TestMaker from http://www.pushtotest.com"
>> print
>>
>> test = mytest( 2 ) # Value determines logging level, 0 =
>> off, 1 = Major messages only, 2 = Step details
>> test.runTest()
>>
>> print "Test executed", test.getSteps(), "steps."
>> print "Test completed."
>>
>>
>> I am open to your input, feedback and criticism of the above script.
>> Please let me know your thoughts. Thanks, in advance.
>>
>> -Frank
>>
>>
>>
>>
>> On Sep 27, 2004, at 3:08 PM, Frank Cohen wrote:
>>
>>> Nice summary of the problem and solution. I urge you to consider two
>>> changes to your proposal.
>>>
>>> 1) It's nice to see how many ideas are being passed around the MaxQ
>>> project. At this rate MaxQ is going to outgrow a one-size-fits-all
>>> format for the recorded scripts. For example, I really want the
>>> logging to stay. I propose adding a Preferences command that allows
>>> users to choose recording options.
>>>
>>> 2) Add a regex way to validate http response codes.
>>>
>>> -Frank
>>>
>>>
>>> On Sep 27, 2004, at 2:51 PM, Oliver Bock wrote:
>>>
>>>> I'm concerned that the scripts being generated by MaxQ are complex
>>>> and too large. While I mainly use my new "compact" scripts, I do
>>>> think that the old style is still useful for new users because they
>>>> can see what is happening. Its simplicity is also useful for
>>>> people who are only generating a few scripts and don't mind hand
>>>> editing them. Here is a script that submits a single form with
>>>> four parameters:
>>>>
>>>> # Generated by MaxQ
>>>> [com.bitmechanic.max​q.generator.JythonCo​deGenerator]
>>>> from sys import *
>>>>
>>>> from com.bitmechanic.maxq import Config
>>>> global driverPkg, validatorPkg, logger
>>>> if __name__ == 'main':
>>>> driverPkg = Config.getDriverPkgName()
>>>> validatorPkg = Config.getValidatorPkgName()
>>>>
>>>> # Determine the driver for this testcase.
>>>> exec 'from '+driverPkg+' import HttpTestCase'
>>>>
>>>> # Determine the validator for this testcase.
>>>> exec 'from '+validatorPkg+' import Validator'
>>>>
>>>> # imports
>>>> from junit.textui import TestRunner
>>>> from java.lang import *
>>>> from java.io import *
>>>> from java.util import *
>>>> from org.apache.commons.httpclient import NameValuePair
>>>>
>>>>
>>>> # definition of test class
>>>> [com.bitmechanic.max​q.generator.JythonCo​deGenerator]
>>>> class MaxQTest(HttpTestCase):
>>>> def __init__(self, testName):
>>>> HttpTestCase.__init__(self, testName)
>>>>
>>>> # Add setup code here. See Junit javadoc.
>>>> def setUp(self):
>>>> pass
>>>>
>>>> # Add tearDown code here. See Junit javadoc.
>>>> def tearDown(self):
>>>> pass
>>>>
>>>> # Runs the test
>>>> def runTest(self):
>>>> self.doTest()
>>>>
>>>> # Test script
>>>> def doTest(self):
>>>> self.currentParams = ArrayList()
>>>> self.currentParams.a​dd(NameValuePair('''​scope''',
>>>> '''projectAndSubs'''))
>>>> self.currentParams.a​dd(NameValuePair('''​resultsPerPage''',
>>>> '''40'''))
>>>> self.currentParams.a​dd(NameValuePair('''​query''',
>>>> '''ghjghj'''))
>>>> self.currentParams.a​dd(NameValuePair('''​Button''',
>>>> '''Go'''))
>>>> print "Testing URL: %s" %
>>>> self.replaceURL('''http://maxq.tigris.o​rg/servlets/Search?
>>>> scope=projectAndSubs​&resultsPerPage=​40&query=ghjghj​&Button=Go''')
>>>> self.currentUrl = "http://maxq.tigris.o​rg/servlets/Search"
>>>> list = self.currentParams
>>>> Validator.validateRequest(self, self.getMethod(), "get",
>>>> self.currentUrl, self.currentParams)
>>>> self.get(self.currentUrl, list)
>>>> print "Response code: %s" % self.getMethod().get​StatusCode()
>>>> self.assertEquals("Assert number 2 failed", 200,
>>>> self.getMethod().get​StatusCode())
>>>> Validator.validateRe​sponse(self, self.getMethod(),
>>>> self.currentUrl, self.currentParams)
>>>>
>>>> # ^^^ Insert new recordings here. (Do not remove this line.)
>>>>
>>>>
>>>> ####################​####################​##
>>>>
>>>> # Code to load and run the test
>>>> if __name__ == 'main':
>>>> logger = Config.getTestLogger()
>>>> test = MaxQTest("MaxQTest")
>>>> test.Run()
>>>>
>>>> SIXTY SIX LINES!!! When it's simple, Jython/Python is a language
>>>> that inexperienced programmers can understand and get started on
>>>> quickly. Presumably this is why it was chosen for MaxQ. But this?
>>>> Can you imagine the reaction of most people when they download
>>>> MaxQ and it produces this stuff? They go elsewhere.
>>>>
>>>> I propose these changes:
>>>>
>>>> - We switch from encoding parameters in an ArrayList of
>>>> NameValuePairs to a Jython array of tuples. This will make the
>>>> scripts more concise and will stop them being tied to HttpClient.
>>>> e.g.
>>>> self.currentParams = [('''scope''', '''projectAndSubs'''),
>>>> ('''resultsPerPage''', '''40'''),
>>>> ('''query''', '''ghjghj'''),
>>>> ('''Button''', '''Go''')]
>>>>
>>>> - We remove the empty setUp() and tearDown() functions. They are
>>>> documented and so need not be included in every script. We can
>>>> also include some sample scripts showing how to use them.
>>>>
>>>> - We get rid of doTest() and put recorded code in runTest(). It is
>>>> trivial for the user to break the code into multiple functions if
>>>> this is what she desires. Again, examples will assist.
>>>>
>>>> - We stop using esoteric syntax to allow Config to override the
>>>> class for HttpTestCase and Validator. No new MaxQ user will want
>>>> to do this, rather they will wonder: "What they hell is this? This
>>>> doesn't appear in the Python tutorial!" Now that the
>>>> JythonGenerator code is much simpler, it would be easy to derive a
>>>> new class from JythonGenerator to change these base classes for
>>>> whichever sophisticated users wish it.
>>>>
>>>> - We stop loading a logger. We do not want people to use a logger
>>>> because it will stop output going to stdout/stderr and therefore it
>>>> will not appear in MaxQ's run window. "print" is obviously easier
>>>> for a user to understand, and that's what the script uses anyway.
>>>>
>>>> We would end up with a script like this:
>>>>
>>>> # Generated by MaxQ
>>>> [com.bitmechanic.max​q.generator.JythonCo​deGenerator]
>>>> from com.bitmechanic.maxq import Validator
>>>>
>>>> class MaxQTest(HttpTestCase):
>>>> def runTest(self):
>>>> self.currentParams = [('''scope''', '''projectAndSubs'''),
>>>> ('''resultsPerPage''', '''40'''),
>>>> ('''query''', '''ghjghj'''),
>>>> ('''Button''', '''Go''')]
>>>> print "Testing URL: %s" %
>>>> self.replaceURL('''http://maxq.tigris.o​rg/servlets/Search?
>>>> scope=projectAndSubs​&resultsPerPage=​40&query=ghjghj​&Button=Go''')
>>>> self.currentUrl = "http://maxq.tigris.o​rg/servlets/Search"
>>>> Validator.validateRequest(self, self.getMethod(), "get",
>>>> self.currentUrl, self.currentParams)
>>>> self.get(self.currentUrl, self.currentParams)
>>>> print "Response code: %s" % self.getMethod().get​StatusCode()
>>>> self.assertEquals("Assert number 2 failed", 200,
>>>> self.getMethod().get​StatusCode())
>>>> Validator.validateRe​sponse(self, self.getMethod(),
>>>> self.currentUrl, self.currentParams)
>>>>
>>>> # ^^^ Insert new recordings here. (Do not remove this line.)
>>>>
>>>>
>>>> # Code to load and run the test
>>>> if __name__ == 'main':
>>>> test = MaxQTest("MaxQTest")
>>>> test.Run()
>>>>
>>>>
>>>> Oliver
>>>>
>>>>
>>>> --------------------​--------------------​--------------------​--------
>>>> -
>>>> To unsubscribe, e-mail: dev-unsubscribe at maxq dot tigris dot org
>>>> For additional commands, e-mail: dev-help at maxq dot tigris dot org
>>>>
>>>>
>>> ---
>>> Frank Cohen, PushToTest, http://www.PushToTest.com, phone: 408 374
>>> 7426
>>> Author of "Java Testing and Design: From Unit Tests to Automated Web
>>> Tests"
>>> from Prentice Hall, details at http://thebook.pushtotest.com
>>>
>>>
>>> --------------------​--------------------​--------------------​---------
>>> To unsubscribe, e-mail: dev-unsubscribe at maxq dot tigris dot org
>>> For additional commands, e-mail: dev-help at maxq dot tigris dot org
>>>
>>>
>> ---
>> Frank Cohen, PushToTest, http://www.PushToTest.com, phone: 408 374
>> 7426
>> Author of "Java Testing and Design: From Unit Tests to Automated Web
>> Tests"
>> from Prentice Hall, details at http://thebook.pushtotest.com
>>
>>
>> --------------------​--------------------​--------------------​---------
>> To unsubscribe, e-mail: dev-unsubscribe at maxq dot tigris dot org
>> For additional commands, e-mail: dev-help at maxq dot tigris dot org
>>
>>
>
>
> --------------------​--------------------​--------------------​---------
> To unsubscribe, e-mail: dev-unsubscribe at maxq dot tigris dot org
> For additional commands, e-mail: dev-help at maxq dot tigris dot org
>
>
---
Frank Cohen, PushToTest, http://www.PushToTest.com, phone: 408 374 7426
Author of "Java Testing and Design: From Unit Tests to Automated Web
Tests"
from Prentice Hall, details at http://thebook.pushtotest.com


--------------------​--------------------​--------------------​---------
To unsubscribe, e-mail: dev-unsubscribe at maxq dot tigris dot org
For additional commands, e-mail: dev-help at maxq dot tigris dot org

« Previous message in topic | 5 of 24 | Next message in topic »

Messages

Show all messages in topic

[maxq-dev] Obese scripts oliverbock Oliver Bock 2004-09-27 14:51:38 PDT
     Re: [maxq-dev] Obese scripts fcohen Frank Cohen 2004-09-27 15:08:32 PDT
         Re: [maxq-dev] Obese scripts fcohen Frank Cohen 2004-09-27 15:21:33 PDT
             Re: [maxq-dev] Obese scripts oliverbock Oliver Bock 2004-09-27 20:59:38 PDT
                 Re: [maxq-dev] Obese scripts fcohen Frank Cohen 2004-09-27 22:14:42 PDT
                 Re: [maxq-dev] Obese scripts bitter lee 2004-09-27 23:37:48 PDT
                     Re: [maxq-dev] Obese scripts oliverbock Oliver Bock 2004-09-29 14:32:39 PDT
                         Re: [maxq-dev] Obese scripts bitter lee 2004-09-29 18:49:38 PDT
                 Re: [maxq-dev] Obese scripts bitter lee 2004-09-27 23:38:33 PDT
                     Re: [maxq-dev] Obese scripts hdara at primavera dot com hdara at primavera dot com 2004-09-28 10:29:04 PDT
                         Re: [maxq-dev] Obese scripts oliverbock Oliver Bock 2004-09-28 14:11:22 PDT
                             Re: [maxq-dev] Obese scripts hdara at primavera dot com hdara at primavera dot com 2004-09-28 14:29:05 PDT
                                 Re: [maxq-dev] Obese scripts oliverbock Oliver Bock 2004-09-28 16:10:32 PDT
                                 Re: [maxq-dev] Obese scripts avery1701 Matt Avery 2004-09-29 07:07:51 PDT
                                     Re: [maxq-dev] Obese scripts avery1701 Matt Avery 2004-09-29 07:49:04 PDT
                                         Re: [maxq-dev] Obese scripts hdara at primavera dot com hdara at primavera dot com 2004-09-29 10:16:43 PDT
         Re: [maxq-dev] Obese scripts oliverbock Oliver Bock 2004-09-27 20:54:23 PDT
             Re: [maxq-dev] Obese scripts fcohen Frank Cohen 2004-09-27 22:10:32 PDT
                 [maxq-dev] Regular expressions in Jython? fcohen Frank Cohen 2004-09-27 22:40:49 PDT
                     Re: [maxq-dev] Regular expressions in Jython? oliverbock Oliver Bock 2004-09-28 14:08:27 PDT
                         Re: [maxq-dev] Regular expressions in Jython? fcohen Frank Cohen 2004-09-28 14:13:34 PDT
     Re: [maxq-dev] Obese scripts hdara at primavera dot com hdara at primavera dot com 2004-09-27 15:26:32 PDT
         Re: [maxq-dev] Obese scripts oliverbock Oliver Bock 2004-09-27 21:00:49 PDT
             Re: [maxq-dev] Obese scripts hdara at primavera dot com hdara at primavera dot com 2004-09-27 22:47:15 PDT
Messages per page: