Thomas Murphy, Director at Gartner, says ".. as we note Oracle has solid tools, because of the customer base a natural channel but the testing tools are hidden to the world. Some of Oracle’s testing story is associated with the core DB but the majority with the Enterprise Manager set of products."
A blurb directly from Oracle's web site: "Application Testing Suite (ATS) is a comprehensive, integrated testing solution that ensures the quality, scalability, and availability of your Web applications and Web Services."
ATS provides a familiar Eclipse-based IDE and record/playback model for test creation. Web-based applications, Oracle Forms, Siebel High Interactivity (HI), ADF/JSF, Adobe Flex, and SOA applications can all be tested with ATS.
A blurb directly from Oracle's web site: "Application Testing Suite (ATS) is a comprehensive, integrated testing solution that ensures the quality, scalability, and availability of your Web applications and Web Services."
ATS provides a familiar Eclipse-based IDE and record/playback model for test creation. Web-based applications, Oracle Forms, Siebel High Interactivity (HI), ADF/JSF, Adobe Flex, and SOA applications can all be tested with ATS.
Application Testing Suite is widely considered to be very easy to use yet very powerful, but there is a downside: the record/playback model does not work very well for non-interactive applications, such as socket-based applications. In this blog entry, I'm showing how trivially easy it is to write a module to load-test an SMTP (e-mail) server.
The first step is to launch OpenScript, the Eclipse-based test GUI. Once launched, create a new test script:

ATS allows us to choose what type of test (Functional, Load, or General) we want to create. For this exercise, we select a General Java Code Script.

ATS will then create the generic Java Code Script test harness, which contains three methods, Initialize, Run, and Finish. Notice that the Record button at the top is grayed out, as we cannot meaningfully do a browser navigation to automatically create the test. Also note the Tree View and Java Code tabs at the bottom left.

When we switch to Java Code, we can see the (stub) test harness. For simplicity, let's put the entire load test in the Run section.

In order to send an email, we need to use the JavaMail API. JavaMail also uses the Java Activation Framework (JAF), but thankfully JAF is part of Java SE 6, so we don't need to add it. However, we do need to download JavaMail and put mail.jar somewhere on the class path so that our load script can find it.
This is very easily done for our script: select the Script menu item, then Script Properties:

Click on Script Assets on the left-hand pane, then click the Add button and select the Jar File option. Browse to wherever you've saved mail.jar and we're done.

The stub test harness looks like this:
import oracle.oats.scripting.modules.basic.api.*;
import oracle.oats.scripting.modules.utilities.api.*;
import oracle.oats.scripting.modules.utilities.api.sql.*;
import oracle.oats.scripting.modules.utilities.api.xml.*;
import oracle.oats.scripting.modules.utilities.api.file.*;
public class script extends IteratingVUserScript {
@ScriptService oracle.oats.scripting.modules.utilities.api.UtilitiesService
utilities;
public void initialize() throws Exception {
}
/**
* Add code to be executed each iteration for this virtual user.
*/
public void run() throws Exception {
}
public void finish() throws Exception {
}
}
We have to import the appropriate class libraries at the top..
import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;
import javax.activation.*;
Then replace the entire Run section with one of our own (in this case, I've hard-coded all of the parameters, sender, recipient, SMTP server, and message body):
public void run() throws Exception {
// put recipient here
String to = "orly@nova-N81Vp";
// and sender
String from = "atsloadtesting@localhost";
// host name of SMTP server
String host = "demoserver";
// Create properties, get Session
Properties props = new Properties();
props.put("mail.smtp.host", host);
props.put("mail.debug", "true");
javax.mail.Session session = javax.mail.Session.getInstance(props);
try {
// Instantiate a message
Message msg = new MimeMessage(session);
//Set message attributes
msg.setFrom(new InternetAddress(from));
InternetAddress[] address = {new InternetAddress(to)};
msg.setRecipients(Message.RecipientType.TO, address);
msg.setSubject("Test E-Mail through Java");
msg.setSentDate(new Date());
// Set message content
msg.setText("This is a test of sending a " +
"plain text e-mail through Java.\n" +
"Here is the second line.");
// Send the message
Transport.send(msg);
}
catch (MessagingException mex) {
// Prints all nested (chained) exceptions as well
mex.printStackTrace();
}
}You can then press the Play button to check that the load test works (you'll want to log in to your mail account and check that an email was indeed delivered).
The usual ATS features such as Data Banks can also be used. Let's say we want to parameterize the e-mail Sender. The first step is to create a new Script Variable. To do this, switch back to Tree View, right-click on the Run section, then select Set Variable:

We are then presented with a dialog box asking us to name the Script Variable (note that Script Variables and Java variables are not the same thing!) and provide a value. We can put in a literal value, or interpolate data from an external data source via the Substitute Variable button (the small chain-like button at the right of the Value field):

When we click on Substitute Variable, we are given a choice of where to get this Script Variable's value; we select Add new Databank:

Data Banks can be either a JDBC data source, or a CSV file. For simplicity, we select the CSV file, click the Next button, and browse to the location of the CSV file.

Upon loading the CSV file, we can select which column will be interpolated into the Script Variable, then press Finish.

We're now back at the Set Variable dialog, with both Name and Value fields filled-in:

On our Tree View, we can see that the new variable has been added to the Run section, however it has been added to the end:

So we simply drag it to right after the GetNextDataBankRecord step:

When we switch back to Java Code, we can see that a couple new code lines have been added.
public void run() throws Exception {
getDatabank("avitek").getNextDatabankRecord();
getVariables().set("sender", "{{db.avitek.Username}}",
Variables.Scope.GLOBAL);
// put recipient here
String to = "orly@nova-N81Vp";
// and sender
String from = "atsloadtesting@localhost";
...
We now want to put the "sender" Script Variable, into the Java String "from" -
String from = (String)getVariables().get("sender");
And that's it! when we next iterate the Load Test (whether in OpenScript, or in Oracle Load Testing if we want to simulate tens or hundreds of users), the "from" variable will automatically cycle through our CSV Data Bank. Obviously, the same principle can be applied to the rest of the variables, such as the recipient, message body, and so on.
This procedure can be adopted to any protocol for which a Java library exists (and for those that don't, you can implement the protocol yourself in Java). For example, if you want to load-test a GSM Short Message Service Center (SMSC) that uses the Logica SMPP protocol, all you will need is the SMPP Java library from Logica (they also provide a sample Java client which you can cut-and-paste into OpenScript) and follow pretty much the exact same procedure we've just gone through.
