This topic explains how to handle strings in Python and provides examples of operations that deal with strings. It contains the following sections:
Accessing an Individual Character of a String
Searching for Characters and Substrings
Removing Extra Spaces From a String
Basics
A string is a sequence of symbols or digits. Strings are among the most frequently used data types. Like any other data types, strings in TestComplete are represented as OLE-compatible variants.
In Python, a sequence of literal characters enclosed in a matching pair of quotation marks is recognized as a string. Quotation marks can be single ('), double (") or triple quotes (""" or '''). The quotation characters are allowed within a string if they do not match the enclosing pair. All the strings below are valid:
Python
str2 = 'It came out of night fog and looked weird: no sails, no lights and no crew.';
str3 = "'Ahoy! Is there anyone?' - the captain cried.";
str4 = """"Nobody." - was the answer."""
To deal with strings, TestComplete has a special aqString
scripting object. The object is available for all supported scripting languages, so that you can use it to operate with string values regardless of the chosen language.
Method, Property | Description |
---|---|
aqString.AddListItem |
Adds a new item to a string list. |
aqString.ChangeListItem |
Changes the value of the string list item with the given index. |
aqString.Compare |
Compares two specified strings. |
aqString.Concat |
Concatenates two specified strings. |
aqString.DeleteListItem |
Removes an item with the given index from a string list. |
aqString.Find |
Searches for a substring within the given string. Use this method instead of the obsolete aqString.Contains . |
aqString.Format |
Generates a formatted string. |
aqString.GetChar |
Retrieves a single character from the input string. |
aqString.GetLength |
Returns the number of characters in a string. |
aqString.GetListItem |
Returns an individual item from the list passed through the input string. |
aqString.GetListLength |
Returns the number of items in the string list. |
aqString.Insert |
Inserts one string to another at the specified position. |
aqString.ListSeparator |
Specifies a character used to separate individual values in a list. |
aqString.Quote |
Encloses the specified string in quotes. |
aqString.QuoteSymbol |
Specifies a symbol used as a quotation mark. |
aqString.Remove |
Removes a number of characters from the input string. |
aqString.Replace |
Replaces all the occurrences of one substring with another substring. |
aqString.SubString |
Retrieves a substring from the input string. |
aqString.ToLower |
Converts the specified string to lower case. |
aqString.ToUpper |
Converts the specified string to upper case. |
aqString.Trim |
Removes spaces and control characters from the specified string. |
aqString.Unquote |
Converts a quoted string to an unquoted string. |
Another scripting object that is useful for string manipulation is aqConvert
. This object has several methods that convert values of different types to a string representation and vice versa.
Method | Description |
---|---|
aqConvert.CurrencyToFormatStr |
Converts a currency value to a string using the specified format settings. |
aqConvert.CurrencyToStr |
Converts a currency value to a string. |
aqConvert.DateTimeToFormatStr |
Converts the given date value to a string using the specified format. |
aqConvert.DateTimeToStr |
Converts the given date value to a string. |
aqConvert.FloatToStr |
Converts a floating-point value to a string. |
aqConvert.IntToStr |
Converts the given number into a string. |
aqConvert.StrToCurrency |
Converts the specified string to a currency value. |
aqConvert.StrToDate |
Converts the specified string to a date value. |
aqConvert.StrToDateTime |
Converts the specified string to a date/time value. |
aqConvert.StrToFloat |
Converts the specified string to a floating-point value. |
aqConvert.StrToInt |
Converts the specified string to an integer value. |
aqConvert.StrToInt64 |
Converts the specified string to a long integer value. |
aqConvert.StrToTime |
Converts the specified string to a time value. |
aqConvert.VarToStr |
Converts the specified variant value to a string. |
Furthermore, Python has its own inherent object, string
, which is a wrapper for the string data type. Strings that are used in TestComplete are compatible with this object. Moreover, string
objects are created implicitly for every string. That is, you can call object methods not only for object instances but also for any TestComplete string. For example, the following method call is correct:
Python
mySubStr = myStr[11:6]
A detailed description of the string
object is provided in Python Wiki. The table below lists the object's major properties and methods:
Property, Method | Description |
---|---|
capitalize() |
Method. Capitalizes the first letter in a string. |
center(width, fillchar) |
Method. Returns a center-aligned string. Spaces are used for formatting. |
count(str, beg= 0,end=len(string)) |
Method. Counts how many times str occurs in a string or substring if the starting index (beg ) and the ending index (end ) are specified.
|
decode(encoding='UTF-8',errors='strict') |
Method. Decodes a string by using the specified codec. Uses the default string encoding if no encoding is specified. |
encode(encoding='UTF-8',errors='strict') |
Method. Returns an encoded string. If an error occurs, the method displays the ValueError message unless the errors parameter is specified as 'ignore' or 'replace'.
|
endswith(suffix, beg=0, end=len(string)) |
Method. Determines if a string or a substring (if the starting index (beg ) and the ending index (end ) are specified) ends with a suffix. Returns True on success and False otherwise. |
expandtabs(tabsize=8) |
Method. Replaces tabs in a string with multiple spaces. Uses 8 spaces per tab if tabsize is not specified.
|
find(str, beg=0 end=len(string)) |
Method. Determines if str occurs in a string or substring if the starting index (beg ) and the ending index (end ) are specified. Returns the index of the first symbol in the match if str is found, and -1 otherwise.
|
index(str, beg=0, end=len(string)) |
Method. The same as find() , but raises an exception if str is not found.
|
isalnum() |
Property. Returns True if a string has at least 1 character and all the characters are alphanumeric. False otherwise. |
isalpha() |
Property. Returns True if a string has at least 1 character and all the characters are alphabetic. False otherwise. |
isdigit() |
Property. Returns True if a string contains only digits, and False otherwise. |
islower() |
Property. Returns True if all the characters in a string are lowercase. |
isspace() |
Property. Returns True if a string contains only whitespace characters, and False otherwise. |
istitle() |
Property. Returns True if title case is used in a string (the first letter of each word is in uppercase), and False otherwise. |
isupper() |
Property. Returns True if all the characters in a string are in uppercase. |
join(seq) |
Method. Combines the elements in the seq sequence. Inserts a separator between the elements.
|
len(string) |
Property. Returns the length of the string. |
ljust(width[, fillchar]) |
Method. Returns a left-aligned string. Spaces are used for formatting. |
lower() |
Method. Converts all the letters in a string to lowercase letters. |
lstrip() |
Method. Removes all leading whitespaces from a string. |
maketrans() |
Method. Returns a translation table used to translate strings. |
max(str) |
Property. Returns the lexicographically highest character from the string. For example, max("smartbear") will return t.
|
min(str) |
Property. Returns the lexicographically lowest character from the string. For example, min("smartbear") will return a.
|
replace(old, new [, max]) |
Method. Replaces the occurrences of an old substring in a string with a new substring. The number of replacements is specified by the max argument.
|
rfind(str, beg=0,end=len(string)) |
Method. The same as find() , but searches backwards in a string.
|
rindex( str, beg=0, end=len(string)) |
Method. The same as index() , but searches backwards in a string.
|
rjust(width,[, fillchar]) |
Method. Returns a right-aligned string. Spaces are used for formatting. |
split(str="", num=string.count(str)) |
Method. Splits a string by using the str delimiter (if str is not specified, spaces are used) and returns a list of substrings. The num argument specifies the number of substrings.
|
splitlines( num=string.count('\n')) |
Method. Splits a string by new line characters and returns a list of lines. New line characters are removed from these lines. The num argument specifies the number of lines.
|
startswith(str, beg=0,end=len(string)) |
Method. Determines if a string or a substring (if the starting index beg and the ending index end are specified) starts with the substring str . Returns True if it does, and False otherwise.
|
strip([chars]) |
Method. Removes all leading and trailing whitespaces from a string. |
swapcase() |
Method. Inverts the case of all the letters in a string. |
title() |
Property. Returns the titlecased version of the string (all the words begin with uppercase letters and the other letters are in lowercase). |
translate(table, deletechars="") |
Method. Translates the words specified in the translation table .
|
upper() |
Method. Converts lowercase letters in a string to uppercase letters. |
zfill (width) |
Property. Returns a string with zeros added at the beginning of the string to reach the specified width. |
isdecimal() |
Property. Returns True if the string contains only decimal characters, and False otherwise. |
Special Characters
There are several pairs of symbols used to represent special characters in Python strings. All of them start with a backslash character (\), and are often called escape characters. The following escape characters are allowed in Python.
Character sequence | Description |
---|---|
\newline | Ignored new line |
\' | Single quote |
\" | Single quote |
\a | Bell |
\b | Backspace |
\f | Formfeed |
\n | Linefeed |
\r | Carriage Return |
\t | Horizontal Tab |
\v | Vertical Tab |
\ooo | ASCII character with octal value ooo |
\xhh... | ASCII character with hex value hh... |
String Prefixes
In Python, you can prefix a string with a special character to specify the way in which it will be processed. In TestComplete, you can use only one prefix for a string. If you need to process a string in multiple ways, process it several times, or use Python methods to convert it.
Prefix | Description |
b | A string will be stored by using an array of bytes. |
r | All escape codes in a string will be ignored. All characters will be escaped. |
u | A string will be processed as a Unicode string. |
Getting the String Length
To obtain the total number of characters in a string, you can either call the len
Python method, or the aqString.GetLength
method. The character position in Python strings is zero-based, so the maximum position number in a string is Length-1. The code below demonstrates both ways of obtaining the string length:
Python
def StringLengthDemo():
aString = "Some text"
Log.Message("The string is " + str(len(aString)) + " character(s) long.")
Log.Message("The string is " + str(aqString.GetLength(aString)) + " character(s) long.")
Using TestComplete, you can limit the length of string parameters returned by functions of the tested application. For this purpose, use the Maximum string length of [out] parameters project property. If the length of the string returned from the application via one of its out parameters exceeds the property’s value, TestComplete treats the returned string as a null one. |
Concatenating Strings
Several strings can be concatenated to form another string. The aqString
object has a special (aqString.Concat
) method that performs this operation.
However, it is more convenient to use the addition operator (+) for this purpose. To append an numeric value, convert it to a string by using the str
method.
The sample code below demonstrates how to use all three techniques:
Python
def ConcatenationDemo():
Str1 = "String No 1 "
Str2 = "String No 2 "
Log.Message(aqString.Concat(Str1, Str2))
Log.Message(Str1 + "String No 2 " + "String No " + str(3) + " ")
Comparing Strings
You may often need to compare two strings during testing. Generally, a test procedure obtains text data (user input, file contents, property value and so on) and then compares it with the expected data. In Python, the comparison operator (==) can check if the strings are identical. For the TestComplete aqString
object, there is the aqString.Compare
method.
The aqString.Compare
method has three parameters: two of them, String 1 and String2, specify the strings to be compared, while the last parameter defines whether the comparison should be case-sensitive or not.
Both approaches can be used to compare strings containing national symbols, for example, characters with diacritical marks ( , , and others).
The code below demonstrates how to use both approaches:
Python
def StringComparison():
# Using the method of the native String object
if "Abra" == "abra":
Log.Message("Abra is equal to abra")
else:
Log.Message("Abra is not equal to abra")
if "abra" == "Abra":
Log.Message("abra is equal to Abra")
else:
Log.Message("abra is not equal to Abra")
if "abra" == "abra":
Log.Message("abra is equal to abra")
else:
Log.Message("abra is not equal to abra")
# Using the method of the aqString object
Log.Message("aqString.Compare(\"Abra\", \"abra\", False): " + str(aqString.Compare("Abra","abra", False)));
Log.Message("aqString.Compare(\"Abra\", \"abra\", True): " + str(aqString.Compare("Abra","abra", True)));
# Dealing with native-language characters
# The following code assumes that French layout is installed on computer
# 040C - is the identifier of the French layout
if aqEnvironment.IsLanguageSupported(0x040C) and aqEnvironment.SetKeyboardLayout(Sys.Process("TestComplete").Id, Ox040C):
if "français" == "Français":
Log.Message("français is equal to Français")
else:
Log.Message("français is not equal to Français")
if "français" == "français":
Log.Message("français is equal to français")
else:
Log.Message("français is not equal to français")
if "français" == "francais":
Log.Message("français is equal to francais")
else:
Log.Message("français is not equal to francais")
Log.Message("aqString.Compare(\"français\", \"Français\", False): "+str(aqString.Compare("français", "Français", False)))
Log.Message("aqString.Compare(\"français\", \"Francais\", False): "+str(aqString.Compare("français", "Francais", False)))
Log.Message("aqString.Compare(\"français\", \"Français\", True): "+str(aqString.Compare("français", "Français", True)))
Accessing an Individual Character of a String
The Python scripting language does not have a data type used for storing single symbols. However, it is not a problem, since strings can contain series of characters and individual characters. You can access any symbol in a string by specifying its valid index. Moreover, you can extract a single character from a string using the aqString.GetChar
method. The sample routine below demonstrates how to extract symbols from strings. It posts text to the TestComplete log in two different ways: as a whole string and by single letters.
Python
def StringByLetter():
aString = "Per aspera ad astra"
Log.Message("The string is : " + aString)
Log.Message("And now this text letter by letter using aqString.GetChar:")
for i in range(0, len(aString)):
Log.Message(aqString.GetChar(aString, i));
Log.Message("And now this text letter by letter using Python syntax:")
for char in aString:
Log.Message(char)
Searching for Characters and Substrings
One of the most common tasks that you may need to perform when working with string values is determining whether specific text is part of a string. To perform such tasks, use a conditional statement or the aqString.Find
method. If the specified substring was found, the method returns the number of the first occurrence of the substring within the source string. If the specified substring was not found, the method returns -1:
Python
def StringOccurrenceDemo():
aString = "Per aspera ad astra"
aSubString = "astra"
Res = aqString.Find(aString, aSubString)
if Res != -1:
Log.Message("A substring '" + aSubString + "' was found in string '" + aString + "' at position " + aqConvert.IntToStr(Res));
else:
Log.Message("There are no occurrences of '" + aSubString + "' in '" + aString + "'.")
You can also get the position of the specified substring by using Python's native find
method. If the substring was found, the method returns the initial position (from 0) of the first substring match. If no occurrences were found, the method returns -1. The code below demonstrates how to do this:
Python
def TextPosDemo():
aString = "Per aspera ad astra"
aSubString = "astra"
findpos = aString.find(aSubString)
if findpos != -1:
Log.Message("A substring '" + aSubString + "' was found at position " + str(findpos))
else:
Log.Message("There are no occurrences of '" + aSubString + "' in '" + aString + "'.")
Getting a Substring
Python strings can be accessed as arrays. This means that to get a substring, you can just use the array syntax ([x:y]).
TestComplete provides the aqString
object that has the SubString
method. This method returns the text fragment between the starting and ending character positions. The character at the ending position is not included. The position is zero-based. If the starting position is greater than the ending position, then these values are swapped. Negative values are considered as zeros.
The sample code below demonstrates how to use these approaches:
Python
def GetStringDemo():
Str = "0123456789";
Log.Message("The Python array syntax demo:")
Log.Message(Str[2:7]) # Posts "23456"
Log.Message(Str[7:2]) # Posts "23456"
Log.Message(Str[-2:7]) # Posts "0123456"
Log.Message(Str[2:2]) # Posts ""
Log.Message("The 'aqString.SubString' method demo:")
Log.Message(aqString.SubString(Str, 2, 5)) # Posts "23456"
Log.Message(aqString.SubString(Str, 2, 0)) # Posts ""
Splitting Strings
Sometimes, you may need to make several strings out of a single string. This operation splits a string into substrings. This can be done by using the Python split
method. This method searches the string for delimiter characters (defined either as a string or a regular expression), splits the string and returns a list containing the resulting strings. Also, you can limit the list length using the third parameter. It is optional and can be omitted. The same method can be used to split a string into substrings, sentences and even separate words. This depends on the specified delimiter. The first sample routine below uses a space character as a delimiter to extract words from a string and the second routine splits a string by line breaks:
Python
def SplitDemo1():
s = "Better late than never but better never late."
# Split at each space character.
ss = s.split(" ")
Log.Message("The resulting array is: " + str(ss))
Log.Message("There are " + str(len(ss)) + " words in the array")
Log.Message("The first word is: " + ss[0])
def SplitDemo2():
s = "Better late than never\r\nbut better never late.";
# Split at line break character.
ss = s.split("\r\n")
Log.Message("The resulting array is: " + str(ss))
Log.Message("There are " + str(len(ss)) + " words in the array")
Log.Message("The first word is: " + ss[0])
TestComplete has a similar method called aqString.GetListItem. It extracts a substring with the specified index from the input string. It was designed to read items from string lists. See Working With String Lists for more information. However, it also redefines delimiter characters and, like the split
method, can be used to get sentences, separate words and so on.
Python
def SplitDemo3():
s = "Better late than never but better never late."
# Assign list separator to space character
prevSep = aqString.ListSeparator
aqString.ListSeparator = " "
# Split by spaces
Log.Message("There are " + str(aqString.GetListLength(s)) + " words in a string")
Log.Message("The first word is: " + aqString.GetListItem(s,0))
# Restore previous separator
aqString.ListSeparator = prevSep
Removing Extra Spaces From a String
You may need to remove leading or trailing spaces, or both from a string you get in your tests. To do this, use Python's string.lstrip
, string.rstrip
and string.strip
methods and the TestComplete aqString.Trim
method.
Python
def TrimDemo():
str=" Hallo ";
Log.Message("'" + aqString.Trim(str, aqString.stLeading) + "'") # Posts 'Hallo '
Log.Message("'" + aqString.Trim(str, aqString.stTrailing) + "'") # Posts ' Hallo'
Log.Message("'" + aqString.Trim(str, aqString.stAll) + "'") # Posts 'Hallo'
You may also want to exclude extra inner whitespaces from a string. To do this, split the string into separate words and then put the words together separating them with one space character.
Python
def TrimInner(Str):
WordArray = Str.split()
Str = ""
for i in range(0, len(WordArray)):
Str += (WordArray[i] + " ")
return aqString.Trim(Str)
#An example of how to use this function
def TrimInnerDemo():
Log.Message(TrimInner("Follow the white rabbit"));
Replacing Characters and Substrings
You may need to find and replace a character or substring within a string. You can do this in two ways: by using the aqString.Replace
method or by using the replace
method of a string
object.
The aqString
object method is much easier to use. It can be used when you need to change certain character or string. It allows you to specify whether the search should be case-sensitive or not. Below is an example that demonstrates how to use this method:
Python
def StringReplaceDemo():
str = "Hi, Bob. Have you seen Bob Robbinson?"
str = aqString.Replace(str, "Bob", "Jack", True)
Log.Message(str)
The String.replace
method is more complicated, but it offers more flexibility. You can change not only a character or string, but also all the fragments matching the specified regular expression pattern.
The first sample demonstrates how to change a string using the replace
method.
Python
import re
def RegExReplaceDemo1():
str = "Hi, Bob. Have you seen Bob Robbinson?"
# Define regular expression pattern
regexp = "Bob"
# Perform replace operation
str = re.sub(regexp, "Jack", str)
Log.Message(str)
The second example demonstrates how to replace a substring with alternative parts. The patterns of alternative parts are separated by pipe characters (" | "). For instance in the example below, the ht(ml|m) pattern matches both html and htm:
Python
def RegExReplaceDemo2():
str = "The html is widely used in Internet. The HTM file is a text file with tags."
# Define regular expression pattern.
regexp = "(html|htm)"
# Perform replace operation
str = re.sub(regexp,"hypertext markup language", str, flags=re.I)
Log.Message(str)
Furthermore, using regular expressions, you can search for the text fragments matching the specified format. In the example below, all the dates written in the DD/MM/YYYY format are replaced with the Some Date string. This operation can be useful, for example, when comparing two reports that contain the date they were generated.
Python
def RegExReplaceDemo3():
str = "Date of report: 30/04/2005."
# Define regular expression pattern.
regexp = "(\d{1,2}.\d{1,2}.\d{2,4})"
# Perform replace operation
str = re.sub(regexp,"Some Date", str)
Log.Message(str)
Changing the Letter Case
The TestComplete aqString
object and the native string
object have methods that convert uppercase letters to lowercase letters and vice versa. They are: aqString.ToLower, aqString.ToUpper, String.lower
, String.upper
and String.title
.
The code below demonstrates how to use these methods.
Python
def LetterCaseDemo():
str="The word 'Champagne' is of French origin"
# Converting to lower case
Log.Message(aqString.ToLower(str))
Log.Message(str.lower())
# Converting to upper case
Log.Message(aqString.ToUpper(str))
Log.Message(str.upper())
# Converting to title case
Log.Message(str.title())
Working With String Lists
Some scripting objects, generally, controls like ListBoxes, ComboBoxes, Memos, etc., return information about their state or contents as string lists. The individual data elements (or items) in these lists are separated by commas, line breaks, carriage returns or some other delimiter characters.
The aqString
object has a number of specific methods (AddListItem
, ChangeListItem
, DeleteListItem
, GetListItem
and GetListLength
) that deal with such lists of strings. The AddListItem
method adds an item to the list, the DeleteListItem
method removes an item from the list, the GetListItem
method retrieves the item with the given index, the ChangeListItem
method assigns a new value to the given item and the GetListLength
method returns the total number of items in the string list.
The symbol that is used as a separator of list items is defined by the ListSeparator
property. By default, the list separator is a pipe character "|", but you can also assigned a comma, column, line break, carriage return, tab character or any other printable and non-printable character, or even several characters.
The sample code below demonstrates how you can work with string lists returned by scripting objects.
Python
def ListDialogOptions():
# Get a string with dialog options
OptStr = UserForms.UserForm1.SaveDialog1.Options
# Assign list separator to comma
prevSep = aqString.ListSeparator
aqString.ListSeparator = ","
# Get the number of dialog options
Log.Message("The dialog has " + str(aqString.GetListLength(OptStr)) + " option(s) enabled:")
# Iterate through the options list
for i in range(0, aqString.GetListLength(OptStr)):
#Get the option and post it to log
Log.Message("Option No " + str((i+1)) + " is: "+ aqString.GetListItem(OptStr, i))
# Restore previous separator
aqString.ListSeparator = prevSep;
def ManageMemoText():
# Get a string with memo lines
StrList = UserForms.UserForm1.cxMemo1.Lines.Text
# Post the memo contents to log
Log.Message(UserForms.UserForm1.cxMemo1.Lines.Text)
# Assign list separator to newline character
prevSep = aqString.ListSeparator
aqString.ListSeparator = "\n"
# Append one more line
StrList = aqString.AddListItem(StrList, "Last Line")
Log.Message(str(StrList))
# Change the value of the first line
StrList = aqString.ChangeListItem(StrList, "New First Line",0)
# Set the memo contents to a new list
UserForms.UserForm1.cxMemo1.Lines.Text = StrList
# Post the memo contents to log
Log.Message(UserForms.UserForm1.cxMemo1.Lines.Text)
# Restore previous separator
aqString.ListSeparator = prevSep