About
Hooks are special script functions that run before or after you execute a BDD script or a feature file. If you have a programming background, you can consider them as event handlers.
TestComplete supports the following hooks:
BeforeFeature
|
The test engine calls this hook before executing of a feature file (that is, before you run all the scenarios defined in this file).
|
AfterFeature
|
This hook works after execution of a feature file.
|
BeforeScenario
|
The test engine calls this hook before execution of a BDD scenario. If you run a feature file that contains multiple scenarios, the test engine will call this hook for every scenario.
|
AfterScenario
|
The test engine calls this hook after execution of a BDD scenario. If you run multiple scenarios, the test engine will call this hook for every scenario.
|
Syntax
Here is an example of the BeforeScenario
hook definition. To use other hooks, replace BeforeScenario with the designed hook type:
JavaScript
BeforeScenario(function (param1){
// Perform some action before running a scenario, for example:
// Log.Message("Before scenario: " + param1.Name);
})
Python
@beforescenario
def someFunc(param1):
# Perform some action before running a scenario, for example:
# Log.Message("Before scenario: " + param1.Name)
VBScript
' [BeforeScenario]
Sub SomeFunc(param1)
' Perform some action before running a scenario, for example:
' Log.Message("Before scenario: " + param1.Name)
End Sub
DelphiScript
// DelphiScript does not support BDD.
C++Script, C#Script
BeforeScenario(function (param1){
// Perform some action before running a scenario, for example:
// Log["Message"]("Before scenario: " + param1["Name"]);
})
All the hook functions use one parameter –
JavaScript
BeforeScenario(function (param1){
// ...
})
Python
@beforescenario
def someFunc(param1):
# ...
VBScript
' [BeforeScenario]
Sub SomeFunc(param1)
' ...
End Sub
DelphiScript
// DelphiScript does not support BDD.
C++Script, C#Script
BeforeScenario(function (param1){
// ...
})
The test engine uses it to pass the Scenario
or Feature
scripting object that corresponds to the scenario or feature being run to the hook. You can use it to check the name of the scenario or feature you run, and then perform or skip certain actions for some scenarios or features. See below for examples.
What actions to perform in hooks
Before... hooks
In Before... hooks, you can perform some initialization actions, for example:
-
In BeforeScenario
, you can post an image of your application’s window to the test log to be aware of the application state before running a scenario.
Show Example
Show ExampleHide ExampleThe following code snippet posts an image of the entire screen (desktop) to the test log before the test engine starts running a BDD scenario.
JavaScript, JScript
BeforeScenario(function (param1){
Log.Picture(Sys.Desktop.Picture(), "Before starting '" + param1.Name + "'");
})
Python
@beforescenario
def someFunc(param1):
Log.Picture(Sys.Desktop.Picture(), "Before starting '" + param1.Name + "'")
VBScript
' [BeforeScenario]
Sub foo(param1)
Log.Picture Sys.Desktop.Picture(), "Before starting '" + param1.Name + "'"
End Sub
DelphiScript
// DelphiScript does not support BDD.
C++Script, C#Script
BeforeScenario(function (param1){
Log["Picture"](Sys["Desktop"]["Picture"](), "Before starting '" + param1["Name"] + "'");
})
-
In BeforeFeature
, you can read a data file that is used by multiple scenarios in your feature file.
Show Example
Show ExampleHide Example
JavaScript, JScript
var fileData; // Global variable
BeforeFeature(function (param1) {
// Read file data
fileData = aqFile.ReadWholeTextFile("c:\\data\\test-data.txt", aqFile.ctUTF8);
})
Python
fileData = "" # Global variable
@beforefeature
def someFunc(param1):
# Read file data
fileData = aqFile.ReadWholeTextFile("c:\\data\\test-data.txt", aqFile.ctUTF8)
VBScript
Dim FileData ' Global variable
'[BeforeFeature]
Sub foo
' Read file data
FileData = aqFile.ReadWholeTextFile("c:\data\test-data.txt", aqFile.ctUTF8)
End Sub
DelphiScript
// DelphiScript does not support BDD.
C++Script, C#Script
var fileData; // Global variable
BeforeFeature(function(param1) {
// Read file data
fileData = aqFile["ReadWholeTextFile"]("c:\\data\\test-data.txt", aqFile["ctUTF8"]);
})
-
In BeforeFeature
, you can set up a database connection used by scenarios in your feature file.
Show Example
Show ExampleHide ExampleThe following code snippet connects to the sample database that is part of the additional sample package. You can download this package from support.smartbear.com/downloads/testcomplete/samples/. In your tests, you will need to replace the connection string with the string that matches your database.
To store the Connection object, we use a global variable. This way you can use the Connection object from script functions that are linked to individual test steps. Don’t forget to close the connection at the end of the test run.
For more information on working with databases from test scripts, see Working With Databases.
JavaScript, JScript
var dbConnection; // Global variable to store the Connection object
BeforeFeature(function (param1){
dbConnection = ADO.CreateADOConnection();
// Specify the connection string
dbConnection.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;"+
"Data Source=C:\\Users\\Public\\Documents\\TestComplete 14 Samples\\Desktop\\Checkpoints\\XML\\DataGridViewSample\\OrdersDB.mdb";
// Suppress the login dialog box
dbConnection.LoginPrompt = false;
dbConnection.Open();
})
Python
dbConnection = "" # Global variable to store the Connection object
@beforefeature
def someFunc(param1):
global dbConnection
# Create a Connection object
dbConnection = ADO.CreateADOConnection()
# Specify the connection string
dbConnection.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" + \
"Data Source=C:\\Users\\Public\\Documents\\TestComplete 14 Samples\\Desktop\\Checkpoints\\XML\\DataGridViewSample\\OrdersDB.mdb";
# Suppress the login dialog box
dbConnection.LoginPrompt = False
dbConnection.Open()
VBScript
Dim dbConnection ' Global variable to store the Connection object
' [BeforeFeature]
Sub foo1(param1)
Set dbConnection = ADO.CreateADOConnection()
dbConnection.ConnectionString = _
"Provider=Microsoft.Jet.OLEDB.4.0;"+ _
"Data Source=C:\Users\Public\Documents\TestComplete 14 Samples\Desktop\Checkpoints\XML\DataGridViewSample\OrdersDB.mdb"
' Suppress the login dialog box
dbConnection.LoginPrompt = False
dbConnection.Open
End Sub
DelphiScript
// DelphiScript does not support BDD.
C++Script, C#Script
var dbConnection; // Global variable to store the Connection object
BeforeFeature(function (param1){
dbConnection = ADO["CreateADOConnection"]();
// Specify the connection string
dbConnection["ConnectionString"] = "Provider=Microsoft.Jet.OLEDB.4.0;"+
"Data Source=C:\\Users\\Public\\Documents\\TestComplete 14 Samples\\Desktop\\Checkpoints\\XML\\DataGridViewSample\\OrdersDB.mdb";
// Suppress the login dialog box
dbConnection["LoginPrompt"] = false;
dbConnection["Open"]();
})
After... hooks
In After... hooks, you can perform some finalization actions, for example:
-
In AfterScenario
, you can post an image of the tested application’s window to the test log to get information on the application status at the end of the scenario run.
Show Example
Show ExampleHide ExampleThe following code snippet posts an image of a tested application to the test log after the test engine completes a BDD scenario.
As a tested application, we use the Orders sample desktop application that comes along with TestComplete. In your code, you will need to replace the lines that get the Process and Window objects with the code that corresponds to your tested application.
JavaScript, JScript
AfterScenario(function (param1){
var p = Sys.Process("Orders"); // Get process
var w = p.WinFormsObject("MainForm"); // Get window
Log.Picture(w.Picture(), "The '" + param1.Name + "' scenario is over");
})
Python
@afterscenario
def someFunc(param1):
p = Sys.Process("Orders") # Get process
w = p.WinFormsObject("MainForm") # Get window
Log.Picture(w.Picture(), "The '" + param1.Name + "' scenario is over")
VBScript
' [AfterScenario]
Sub foo(param1)
Set p = Sys.Process("Orders") ' Get process
Set w = p.WinFormsObject("MainForm") ' Get window
Log.Picture w.Picture(), "The '" + param1.Name + "' scenario is over"
End Sub
DelphiScript
// DelphiScript does not support BDD.
C++Script, C#Script
AfterScenario(function (param1){
var p = Sys["Process"]("Orders"); // Get process
var w = p["WinFormsObject"]("MainForm"); // Get window
Log["Picture"](w["Picture"](), "The '" + param1["Name"] + "' scenario is over");
})
-
In AfterFeature
(or even in AfterScenario
), you can send a notification to your teammates about completion of the run.
Show Example
Show ExampleHide ExampleTo send an email, we will use th BuiltIn.SendMail(...)
function. See also Sending Email From Scripts.
JavaScript, JScript
AfterFeature(function (param1) {
SendMail("[email protected]",
"mail.mycompany.com",
"John Smith",
"[email protected]",
param1 + ": The test is over",
"");
})
Python
@afterfeature
def someFunc2(param1):
SendMail("[email protected]", "mail.mycompany.com", "John Smith", "[email protected]", param1 + ": The test is over", "")
VBScript
Sub foo(param1)
Call SendMail("[email protected]",
"mail.mycompany.com",
"John Smith",
"[email protected]",
param1 + ": The test is over",
"")
End Sub
DelphiScript
// DelphiScript does not support BDD.
C++Script, C#Script
AfterFeature(function (param1) {
SendMail("[email protected]",
"mail.mycompany.com",
"John Smith",
"[email protected]",
param1 + ": The test is over",
"");
})
-
In AfterFeature
, you can close a database connection that your scenarios used.
Show Example
Show ExampleHide ExampleThe code snippet below assumes that the global dbConnection
variable stores the Connection object created in the BeforeFeature hook function.
JavaScript, JScript
var dbConnection; // Global variable that stores the Connection object
AfterScenario(function (param1){
dbConnection.Close();
})
Python
dbConnection = "" # Global variable that stores the Connection object
@afterscenario
def someFunc(param1):
global dbConnection
dbConnection.Close()
VBScript
Dim dbConnection ' Global variable that stores the Connection object
' [AfterFeature]
Sub foo(param1)
dbConnection.Close
End Sub
DelphiScript
// DelphiScript does not support BDD.
C++Script, C#Script
var dbConnection; // Global variable that stores the Connection object
AfterScenario(function (param1){
dbConnection["Close"]();
})
Tip
Remember that if you open a connection or file, or allocate some other resource at the beginning of the run, you need to close this collection or file, or release the resource at the end of the run.
Note, however, that it is quite possible that the After... hooks will not run. This might happen if an error occurs during the test run and the Playback > On error property of your test project is set to Stop project or Stop test item. In this case, TestComplete will stop the test run and will not reach the code in your After hook that releases an allocated resource.
To work around the issue, set the On error property to Continue running, or create an OnLogError
event handler and release the allocated resources in it. See also Handling Events - Overview.
Tagged hooks
You can assign tags to feature files and scenarios, and run scenarios and files by tags. You can also make hooks work only for those feature files and scenarios that have specific tags assigned, that is, you can implement tagged hooks. To do this, check the scenario’s or feature file’s tags at the beginning of the hook function and run the hook body depending on the result of the check. The sample hook code below demonstrates how you can implement this. The sample hooks work only for those scenarios that have the @tagA
tag assigned, and don’t have @tagB
assigned:
JavaScript, JScript
BeforeScenario(function (param1){
// param1 contains the Scenario object
if (param1.Tags.Contains("@tagA") &&
!param1.Tags.Contains("@tagB")) {
// Run the hook code
// ...
}
})
Python
@beforescenario
def someFunc(param1):
if param1.Tags.Contains("@tagA") and not param1.Tags.Contains("@tagB"):
# Run the hook code
# ...
VBScript
' [BeforeScenario]
Sub SomeFunc(param1)
' param1 contains the Scenario object
If param1.Tags.Contains("@tagA") And _
Not param1.Tags.Contains("@tagB") Then
' Run the hook code
' ...
End If
End Sub
DelphiScript
// DelphiScript does not support BDD.
C++Script, C#Script
BeforeScenario(function (param1){
// param1 contains the Scenario object
if (param1["Tags"]["Contains"]("@tagA") &&
!param1["Tags"]["Contains"]("@tagB")) {
// Run the hook code
// ...
}
})
To adopt this example to another hook, simply replace BeforeScenario with the desired hook name. For information on working with tags, see Tags.
More notes
-
The actions you perform in hooks functions are not reflected in feature files and scenarios and are hidden for their authors (in some organizations, BDD scenarios are written by subject matter experts or product managers, while test steps are automated by the QA team or automation engineers). This might be important if the test authors should know about the initialization actions the BeforeScenario or BeforeFeature hooks perform. To make these actions more visible to the authors, you can suggest that they use the Background
keyword in BDD tests.
-
You can define multiple hook functions of the same time, for example, multiple scripts functions as a BeforeScenario
hook. TestComplete will execute them all. However, their execution order is not configurable.
-
TestComplete ignores the result value of hook functions.