Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 50 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
50
Dung lượng
532,89 KB
Nội dung
Preparation and Setup Agents 279
The agent begins the main body of the commands by opening the com-
mands file.
dbfile = open( target )
The default open command opens a file for read access.
The agent then duplicates the command constants originally defined in
Prepare_Setup_Agent. The agent loops through each record in the com-
mand.db file and processes each command. While the
post_message()
function does not actually send a request to a Web-enabled application, it
does print the
reply message with the correct indentation to the screen.
The agent then creates variables used during command processing,
including a counter for the number of commands processed, an identifier for
the next new message, and an integer value to track the indentation of the
next
reply message in the tree of reply messages.
Setup_agent processes each command in the commands file. The for
command loops through every line in the commands file.
for line in dbfile.readlines():
The agent creates a list variable called commands by reading a line from
the commands file and splitting it into a list of individual values by delimiting
each value by a comma character using the split function.
commands = line.split(",")
The commands variable is a list so commands[0] refers to the first value
found in the current line of the commands file. In the discussion system
example, the first time through this loop
commands[0] contains a
new_thread command.
The agent handles commands and takes action accordingly. When han-
dling a
new_thread command, the agent indicates the command has been
handled, bumps up the number of handled commands, posts the message
using the
post_message() function, pushes the indentation value onto the
stack using the
push() function, then bumps up the number of messages and
the indentation value.
if int( command ) == new_thread:
handled=1
tick += 1
node=post_message(next_message,indent, \
PH069-Cohen.book Page 279 Monday, March 15, 2004 9:00 AM
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
280 Chapter 8 State, Design, and Testing
"top-message",commands[1],commands[2])
push( indent )
next_message += 1
indent += 1
The handled variable is a simple flag that the agent uses to make sure
every command is recognized and executed. If handled is still 0 at the end of
the next block of code, then an error is thrown.
if handled==0:
print "Unknown command!"
print line
Prepare_Setup_Agent
automatically runs Setup_agent using the exec-
file
command. When execfile is used, Setup_agent exits back to Prepare
_Setup_Agent
then execution continues after the execfile command.
Using Databases to Configure Tests
Earlier in this chapter we learned how the preparation stage of a test formats
configuration instructions into a command file. The configuration instruc-
tions may be manually coded into a preparation test agent retrieved from a
file or database. This section shows how an intelligent test agent that was
built in TestMaker interacts with relational database systems.
TestMaker provides a rich environment for building intelligent test agents,
but at its heart TestMaker is just another application written in Java. The Java
language provides database connectivity through the JDBC API. JDBC driv-
ers are available for most commercial and open source databases, including
Oracle, Microsoft SQL Server, and PostgreSQL.
Following is a test agent that demonstrates how to use JDBC functions
from within a test agent environment.
# DB_meister.a
# Created on: July 3, 2002
# Author: fcohen@pushtotest.com
print "Agent running: DB_meister.a"
print "Description:"
print " Shows how an agent may use a relational "
print " database to receive or record data."
print
PH069-Cohen.book Page 280 Monday, March 15, 2004 9:00 AM
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Using Databases to Configure Tests 281
print " NOTE: THIS AGENT DOES NOT ACTUALLY RUN since "
print " there is no relational database source"
print " available and this agent print depends on "
print " a JDBC driver that you must supply."
print
# Please configure this agent and then remove the
# sys.exit command
print
print "Stopping agent: Please configure this agent to your"
print "own JDBC driver and relational database source."
print
sys.exit
# Import tells TestMaker where to find TOOL, JDBC objects
import sys
from java.sql import DriverManager
# JDBC Driver information
# Note: You must provide these parameters to
# use your provided JDBC driver. You must also add the JDBC
# driver code to the TestMaker classpath. Set the classpath
# by changing the testmaker/testmaker/bin/ide.cfg file.
JDBCDriverClassName = "com.ashna.jturbo.driver.Driver"
jdbcURL = "jdbc:JTurbo://myrelationaldatabase:1410:MSSQL"
jdbcUserID = "myuserid"
jdbcPassword = "thepassword"
# Load the JDBC driver
try:
java.lang.Class.forName( JDBCDriverClassName )
myConn = DriverManager.getConnection( jdbcURL, jdbcUse-
rID, jdbcPassword )
except:
print
print "Could not load JDBC driver: ", \
JDBCDriverClassName
sys.exit
PH069-Cohen.book Page 281 Monday, March 15, 2004 9:00 AM
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
282 Chapter 8 State, Design, and Testing
# Show example of reading from a relational database
print
print "==================================================="
print "Information from the Customers table:"
# Customer count
query1 = "select count(*) from Customers"
try:
statement = myConn.createStatement()
results = statement.executeQuery( query1 )
results.next()
except Exception, ex:
print "Exception while counting customers: ",ex
sys.exit
print
print " Customer count: ", results.int
# Customer list
query2 = "select customer_number, last_name, "
query2 += "salutation, city, year"
query2 += " from table"
query2 += " order by last_name"
try:
statement2 = myConn.createStatement()
r2 = statement.executeQuery( query2 )
except Exception, ex:
print "Exception while getting customer list: ",ex
sys.exit
print
print " Complete customer list (sorted by last name):"
while results2.next():
print " ",r2.getString,r2.getString,r2.getString, \
r2.getString(4),r2.getString(5)
#
PH069-Cohen.book Page 282 Monday, March 15, 2004 9:00 AM
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Using Databases to Configure Tests 283
# Inserting data into a table
insert1 = "insert into customers files (id, name,"
insert1 += "manager, phone) "
insert1 += "VALUES (1001, 'Simpson', 'Mr.', "
insert1 += "'Springfield', 2001)"
try:
i1 = myConn.createStatement();
ir1 = s2.executeQuery( insert1 );
except Exception, ex:
print "Exception while inserting a record: ",ex
print
print "Agent ended."
Let us look at the agent script’s individual sections to learn what the script
does to communicate with a relational database. Unlike most of the other test
agents presented in this book, the
DB_meister agent does not actually run
since at the time of writing this book there was no publicly available relational
database source for the agent to connect to. Check the http://examples.push-
totest.com Web site to see if an example database source is now available.
sys.exit
By default this agent starts and then exits. To run this agent, please config-
ure the agent to connect to an available database and then remove the
sys.exit command.
The
Import command tells TestMaker where to find the standard Java
libraries that implement an interface to the JDBC driver.
from java.sql import DriverManager
A JDBC driver implements all the code needed to communicate with a
specific type of database and an interface that conforms to the JDBC specifi-
cation published by Sun for the Java platform. Database providers and third-
party driver manufacturers provide JDBC drivers. A driver is packaged as a
JAR file. Adding the driver JAR file to the TestMaker classpath is required to
give test agents access to the driver’s functions. For instructions on adding
resources to the classpath, see the TestMaker documentation.
PH069-Cohen.book Page 283 Monday, March 15, 2004 9:00 AM
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
284 Chapter 8 State, Design, and Testing
The test agent sets four basic parameters to tell the JDBC driver where
and how to connect to the database.
JDBCDriverClassName points to the
driver object in a Java namespace defined by the driver manufacturer. The
jdbcURL parameter describes which JDBC driver to use (JTurbo), the URL
to the database, and the database name (
ORCL.)
JDBCDriverClassName = "com.ashna.jturbo.driver.Driver"
jdbcURL = "jdbc:JTurbo://myrelationaldatabase:1527:ORCL"
Driver and database manufacturers define the format to the JDBCDriver-
ClassName and jdbcURL parameters. Here is a short list of common JDBC
drivers and their parameters:
For IBM DB2 (http://www.ibm.com), the agents use:
JDBCDriverClassName = "COM.ibm.db2.jdbc.net.DB2Driver"
jdbcURL = "jdbc:db2://myrelationaldatabase.com/test"
For Oracle (http://www.oracle.com), agents use:
JDBCDriverClassName = "oracle.jdbc.driver.OracleDriver"
jdbcURL = "jdbc:oracle:thin:@myrelationaldata-
base.com:1527:ORCL
JTurbo is a JDBC driver for MS SQL server (http://www.newatlanta.com/
index.jsp):
JDBCDriverClassName = "com.ashna.jturbo.driver.Driver"
jdbcURL = "jdbc:JTurbo://myrelationaldatabase.com:1433/ \
dbhost/sql70=true"
JDBC drivers use Java’s class loader functions to find and access a driver’s
functions. Note that the agent code uses the
try/except format so as to trap
an error that may happen when the driver loads. Possible errors include Java
not finding the driver, the driver not being able to connect to the database, or
the wrong configuration information.
try:
java.lang.Class.forName( JDBCDriverClassName )
myConn = DriverManager.getConnection( jdbcURL, \
jdbcUserID, jdbcPassword )
except:
print
print "Could not load driver: ", JDBCDriverClassName
sys.exit
PH069-Cohen.book Page 284 Monday, March 15, 2004 9:00 AM
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Using Databases to Configure Tests 285
Now that the driver is loaded, the agent shows a few SQL functions to
retrieve data from the Customers table in the database. The Customers table
has these fields and descriptions:
•
customer_number long
• last_name char(50)
• salutation char(10)
• city char(50)
• year char(10)
The first query counts the number of customers in the Customers table
using a SQL select statement.
query1 = "select count(*) from Customers"
Executing the query requires a connection object and statement object.
The agent uses the
try/except format to catch errors that happen while
processing the database function.
try:
statement = myConn.createStatement()
results = statement.executeQuery( query1 )
results.next()
except Exception, ex:
print "Exception while counting customers: ",ex
sys.exit
The query result is returned in the results object. Using the next() method
retrieves the first row of the database results. In this case there is only a single
row, which is formatted and printed to the TestMaker output window.
print " Customer count: ", results.int
The second query demonstrates a more complex database command that
returns more than one row of results. The
query2 += "" format builds the
query statement from multiple parts.
query2 = "select customer_number, last_name, "
query2 += "salutation, city, year"
query2 += " from table"
query2 += " order by last_name"
PH069-Cohen.book Page 285 Monday, March 15, 2004 9:00 AM
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
286 Chapter 8 State, Design, and Testing
The agent makes a connection to the database and returns the results2
object that holds the response from the database. The while command loops
through all the rows in the response.
while results2.next():
print " ",r2.getString,r2.getString,r2.getString, \
r2.getString(4),r2.getString(5)
The third example shows how the agent inserts new rows into the Custom-
ers table. The setup for the database command is the same as the previous
two queries.
insert1 = "insert into customers files (id, name, "
insert1 += "manager, phone) "
insert1 += "VALUES (1001, 'Simpson', 'Mr.', "
insert1 += "'Springfield', 2001)"
To make the query, the agent builds a new connection object and uses the
executeQuery command to process the Insert command.
try:
i1 = myConn.createStatement();
ir1 = s2.executeQuery( insert1 );
except Exception, ex:
print "Exception while inserting a record: ",ex
The TestMaker script language provides access to all of JDBC’s many
methods. Consult your driver documentation for examples of additional
JDBC functions.
Using Lingo to Make Test Content
Close to Real
In the discussion system example presented earlier in this chapter, the
Setup_agent creates a new discussion group by posting messages and reply
messages. Experience shows us that when the message content is uniform, the
underlying systems (Web-enabled application servers, database servers, net-
work routers, and load balancers) try to use optimization technology to
enhance the performance of the system. Rarely, if ever, in the real world would
we find a discussion where every message contained the same content. There-
PH069-Cohen.book Page 286 Monday, March 15, 2004 9:00 AM
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Using Lingo to Make Test Content Close to Real 287
fore, TestMaker includes a handy Lingo utility to automatically generate
pseudo-English-like content for message subject lines and message bodies.
For example, suppose the test agent needed to create a new message. The
Lingo utility object creates this paragraph:
Lipsem it quantos surbatton ditchek surbatton deplorem
ventes so surbatton quantos infreteres ipsem aqua sit
ventes. Campus ad surbatton ad infreteres ad novus surbatton
deplorem it delorum novus. Campus quantos ditchek quantos.
Via surbatton novus surbatton. Novato quantos ditchek deplo-
rem novus ditchek ventes.
The important thing is that Lingo creates a different paragraph each time
it is called, which defeats the system’s attempt to optimize performance while
running tests where the message content is always the same.
Following is a test agent in its entirety that demonstrates Lingo’s many
uses. An explanation of the Lingo functions follows the agent.
# Lingo_meister.a
# Author: fcohen@pushtotest.com
# Import tells TestMaker where to find TOOL objects
from com.pushtotest.tool.util import Lingo
print
print "==================================================="
print "Technique 1: A simple message example"
myLingo = Lingo()
print "Subject:",myLingo.getSubject( 4 )
print "Message:"
print myLingo.getMessage()
print "-end of message-"
print
print "==================================================="
print "Technique 2: URL encoded message example"
print
print "If we needed to include a message in an HTTP POST"
print "command the message would need to be URL encoded."
print "Here is a Lingo message that is URL encoded:"
print
PH069-Cohen.book Page 287 Monday, March 15, 2004 9:00 AM
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
288 Chapter 8 State, Design, and Testing
print myLingo.getMessageEncoded( 100 )
print
print "==================================================="
print "Technique 3: A complete Lingo letter"
print
print "Here is an example business memo using several"
print "Lingo methods."
print
print "Dear Mr.",myLingo.getSingleCap(),":"
print
print "We have found the manuscript you were searching"
print "for and it includes the following excerpt:"
print
# Next we use a special version of getMessage
# to include a starting capital letter, ending period
# and encoding. The format is:
# getMessage(int size, boolean startCap,
# boolean endPeriod, boolean encoded)
print myLingo.getMessage(15, 1, 1, 0)
print
print "As you can see we are not certain what dialect the"
print "text is written in. Please do your best to let us"
print "know what it means."
print
print "Sincerely,"
print
print myLingo.getSingleCap()
print
print "==================================================="
print "Technique 4: Making your own Lingo language"
print
print "Here is the same example business memo from"
print "technique 3 but using French words to form the"
print "Lingo gibberish."
print
caps = [ "Francois", "Sanjournais", "Berjerack", "Mon", \
"La", "Le", "Incroyable! " ]
tokens = [ "devrait","ouvrir","le","cortËge,","entourÈ", \
PH069-Cohen.book Page 288 Monday, March 15, 2004 9:00 AM
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
[...]... WSDL description .NET benefits IT managers, software developers, and QA analysts: • • With the emphasis on XML, configuration and management files become more open and more standardized Third-party system management solutions such as HP’s OpenView and IBM Tivoli should more easily and rapidly support Microsoft servers QA analysts will find testing NET applications easier than prior Microsoft-built applications... Microsoft’s adoption of XML and delivery of a single run-time engine enables increased productivity and efficiency as developers, IT managers, and QA analysts deliver products built with Microsoft development tools Of course, like all new technologies, the NET products come with problems and issues that need to be understood and tested Interoperability and Integration The good news for Java developers working... understand and validate SOAP headers is an important part of testing and monitoring Web services WSDL NET Style Chapter 7 described WSDL as an XML-based document format that describes the services a Web service provides so tools can access and use them The WSDL for a service describes the location of the service; the names of the available services; their method names, parameters, and types; and return... function that takes the DOM element and appends a new child element This is just a convenience function to make the subsequent addElement() commands more legible soap = ProtocolHandler.getProtocol("soap") body = ProtocolHandler.getBody("soap") The TOOL in TestMaker provides a SOAPProtocol handler object and SOAPBody object We use these to construct the request document and to communicate with the host... a skeleton, and paper-thin An expanded agent makes multiple requests of various sizes and delays, operates multiple concurrent threads of the request script to increase the load on the server, runs multiple copies of the multithreaded agent on multiple machines, and adds simple logging functions to the agents so we may determine TPS and SPI val- Please purchase PDF Split-Merge on www.verypdf.com to... eyebrows between Java and NET developers These are not really interoperability issues as much as they are the systems integration issues that we typically have to deal with everyday Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark PH069-Cohen.book Page 297 Monday, March 15, 2004 9:00 AM How Is NET Different? NET’s support of XML and SOAP offers a solution to problems 1 and 2 By... using an Import command to identify the Lingo object to the Jython script language from com.pushtotest.tool.util import Lingo The Lingo object is instantiated and then used by accessing its many methods myLingo = Lingo() Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark 289 PH069-Cohen.book Page 290 Monday, March 15, 2004 9:00 AM 290 Chapter 8 State, Design, and Testing The getSubject()... development tools to offer standardized configuration, description, and deployment definitions For example, while Microsoft BizTalk Server, SQL Server, and Exchange Server still use the Windows Registry, they also now use XML for configuration and management features Microsoft product strategies build XML into all its technology by coding configuration information in XML formats stored in files and databases XML also... services published on XMethods.net This list cleaves in two: SOAP RPC Web services are written in Java and document-style Web services are written in NET One last thing to consider in both RPC and document-style SOAP calls is that the SOAP standard does not cover more complicated data elements than arrays and structures In the previous example we would find that Microsoft has its own encoding for Hashmaps... implementations tested have serious limitations and flaws As new and better implementations become available, a scalability and performance test of the new SOAP stacks is needed to understand how the performance characteristics change SOAP Headers in NET In the formative time of Web services, Microsoft was the first to strongly support XML Schema, WSDL, and SOAP headers Other Web service platforms were . loop
commands[0] contains a
new_thread command.
The agent handles commands and takes action accordingly. When han-
dling a
new_thread command, the agent. purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
280 Chapter 8 State, Design, and Testing
"top-message",commands[1],commands[2])