Starting expecco via Command Line/rest/en

Aus expecco Wiki (Version 2.x)
Zur Navigation springen Zur Suche springen

expecco REST Service Interface[Bearbeiten]

If enabled, expecco accepts REST requests, via the URL "/expeccoService/rest". I.e. the default URL is "host:9090/expeccoService/rest".

Start expecco with REST Server enabled[Bearbeiten]

The service can be started using the command line arguments -- server or --service. Please refer to the detailed description of the command line arguments for more details. Otherwise it is possible to start the service within the expecco IDE. In the Main Menu you will find the menu entries "Extras/Webservices/Test Execution Client For expeccoALM (SOAP)" Start... and Stop. The menu entry "Start" opens a dialog where you can choose the port number should be used by the server. If you choose start the SOAP and REST Services will be started. With the menu entry "Stop" the server will be stopped.

Introduction[Bearbeiten]

The expecco REST service supports nearly the same set of operations as the expecco SOAP service, but uses a much more lightweight approach in its parameter encoding. It is both easier to implement on the client side, and also faster than SOAP, due to the minimal encoding/decoding overhead. Expecco REST calls are HTTP-GET or HTTP-PUT requests, possibly with attached JSON encoded argument data. For requests with response data, the data are also JSON encoded. The http response code on success is 200.

The operation is determined by the URI: the last component is the operation name to be executed.

A description of the supported REST calls can be aqcuired from the running service via "host:9090/expeccoService/rest/protocolInfo".

API Functions[Bearbeiten]

A very useful REST-entry is the "protocolInfo" request, which returns a description of all supported REST call entries:

ProtocolInfo Request[Bearbeiten]

"host:9090/expeccoService/rest/protocolInfo"

All REST services from eXept products support the protocolInfo request (see also expeccoALM-Rest service). It allows for a client to dynamically adapt to newer versions.

The Response is a JSON dictionary with the following fields:

  • "Protocol" - an array containing one entry per supported call entry (see below).
  • "URLPath" - the URL of the service (just a confirmation, as you would not have a response at hand without it)
  • "Service" - the name of the service (class name in Smalltalk) currently always "ExpeccoRestService"
  • "Version" - a protocol version number; currently 1

the elements of the protocol array are objects with the following fields:

  • "Name" - the name of the rest call entry
  • "Request" - the type of HTTP request, one of "GET","PUT" or "DELETE";
  • "Comment" - a comment describing the operation
  • "Argument" - a short description of the argument; if not present, argument is required; can be one of "Dictionary", "String" or any other of the basic JSON data types.
  • "Return" - the type of return data. Same possible values as the argument description.

For example, the current expecco implementation returns the following JSON object:

{
    "Version":2,
    "URLPath":"expeccoService/rest",
    "Protocol":[
        {
            "Name":"cleanupTempFiles",
            "Request":"GET",
            "Comment":"remove leftover temporary files."
        },
        {
            "Name":"download",
            "Request":"PUT",
            "Comment":"download a suite.",
            "Argument":"(SuiteID:String, Suite:String, SuiteURI:String, Parameters:Array),"
        },
        {
            "Name":"execute",
            "Request":"PUT",
            "Comment":"start execution; return ticketID.",
            "Return":"Dictionary",
            "Argument":"(ID:String, SuiteID:String, Suite:String, SuiteURI:String, Environment:Dictionary, TestPlans:Array, Resources:Array, Parameters:Array)"
        },
        {
            "Name":"executeTestSuiteFile",
            "Request":"PUT",
            "Comment":"start execution of a well known suite; return ticketID.",
            "Return":"Dictionary",
            "Argument":"(ID:String, SuiteFileName:String, Environment:Dictionary, TestPlans:Array, Resources:Array, Parameters:Array)"
        },
        {
            "Name":"executeTestSuiteFileWithTestplanNames",
            "Request":"PUT",
            "Comment":"start execution of a well known suite; return ticketID.",
            "Return":"Dictionary",
            "Argument":"(ID:String, SuiteFileName:String, Environment:Dictionary, TestPlans:Array, Resources:Array, Parameters:Array)"
        },
        {
            "Name":"getExecutionInfo",
            "Request":"PUT",
            "Comment":"get execution status of an execute job; argument is ticketID.",
            "Return":"Dictionary",
            "Argument":"(ID:String)"
        },
        {
            "Name":"getListOfTestSuiteFiles",
            "Request":"GET",
            "Comment":"get a list of known test suites which can be executed via executeTestSuiteFile.",
            "Return":"Array"
        },
        {
            "Name":"killExecution",
            "Request":"GET",
            "Comment":"kill execution of an execute job; argument is ticketID.",
            "Argument":"(ID:String)"
        },
        {
            "Name":"loadSuite",
            "Request":"PUT",
            "Comment":"load a suite.",
            "Argument":"(SuiteID:String, SuitePathString:String, Parameters:Array),"
        },
        {
            "Name":"ping",
            "Request":"GET",
            "Comment":"test reachability and return some status info.",
            "Return":"Dictionary"
        },
        {
            "Name":"removeTicket",
            "Request":"GET",
            "Comment":"give up execution of an execute job; if required, kill the job. argument is ticketID.",
            "Argument":"(ID:String)"
        },
        {
            "Name":"waitForExecutionResult",
            "Request":"PUT",
            "Comment":"get execution status of an execute job; argument is ticketID.",
            "Return":"Dictionary",
            "Argument":"(ID:String; ReportFiles:Array,)"
        },
        {
            "Name":"protocolInfo",
            "Request":"GET",
            "Return":"Dictionary"
        }
    ],
    "Service":"ExpeccoRestService"
}


Execute Test Suite File[Bearbeiten]

"host:9090/expeccoService/rest/executeTestSuiteFile"

Load the testsuite and execute the testplans.

The argument is a JSON object with the following fields:

  • ID - mandatory; job id
  • SuiteFileName - name of the testSuite file (ets file)
  • Environment - optional
  • TestPlans - optional
  • Resources - optional
  • Parameters - optional

The ID is an unique identifier which can be used later to retrieve the execution state, results and execution logs. The ets file must be present/reachable by the expecco slave. It may be either an absolute pathname (typically on a shared network drive) or a relative filename. If a relative file name is given, it will be searched in the folder specified with the "--suiteDirectory" command line argument.

{
    "ID":"Testrun-4713", 
    "SuiteFileName":"E:\\tmp\\DemoTest2.ets",
    "Environment":[
        "TestDelay1" "60"
    ],
    "TestPlans":[
        "DefaultTestplan"
    ], 
    "Resources":[], 
    "Parameters":[
        "generateLog" "true" 
        "generatePDFReport" "true"
    ]
}

GetExecutionInfo Request "/expeccoService/rest/getExecutionInfo"[Bearbeiten]

The argument is a JSON object with the following fields:

  • ID - mandatory; job id

The operation is the same as described in the previous SOAP section.

KillExecution Request "/expeccoService/rest/killExecution"[Bearbeiten]

The argument is a JSON object with the following fields:

  • ID - mandatory; job id

The operation is the same as described in the previous SOAP section.

RemoveTicket Request "/expeccoService/rest/removeTicket"[Bearbeiten]

The argument is a JSON object with the following fields:

  • ID - mandatory; job id

The operation is the same as described in the previous SOAP section.

Cleanup Request "/expeccoService/rest/cleanupTempFiles"[Bearbeiten]

No argument. no return value.

Ping Request "/expeccoService/rest/ping"[Bearbeiten]

No argument. Returns an object containing status information.

 

Execute Request "/expeccoService/rest/execute"[Bearbeiten]

The details are the same as in the above SOAP variant.

The argument is a JSON object with the following fields:

  • ID - mandatory; job id
  • SuiteID - mandatory; the UUID of the test suite
  • Suite - optional; suite data file (ets file) in base64 encoding
  • SuiteURI - optional; the URL where expecco could fetch the suite
  • Environment - optional;
  • TestPlans - optional;
  • Resources - optional
  • Parameters - optional;

As described in the SOAP interface above, expecco caches downloaded suites in a temporary cache folder. Therefore, the SuiteID field must be present and contain the test suite's ID.

The .ets file can be either passed down as data (in the Suite field), or expecco can be ordered to fetch the suite via http from the given SuiteURI. If Suite is empty or missing, expecco tries to fetch the .ets file via the SuiteURI. If both fields are empty, expecco will run the test if and only if the suite is already present in its cach folder. Thus, you can optimize execute requests, by either always provide a SuiteURI (instead of the suite data), or - if the client cannot provide the suite via HTTP, but has to send it as data - by first sending an execute request with only the suiteID, but neither suite-data, nor suite-URI. In this case, an error will be reported by expecco if it has the suite not already in its cache, and the client should send another execute request, this time with valid suite data.

The optional "Parameters" field:

If the "Parameters" field is present, it must be a JSON array containing alternating key-value elements. Currently supported keys are:

  • "generateLog" - JSON boolean as corresponding value element
  • "generatePDFReport" - JSON boolean as corresponding value element

The optional "TestPlans" field:

If the "TestPlans" field is present, it must be a JSON array containing JSON arrays as elements. Each entry must consist of a 1 or 2 element JSON array. The first being the UUID of the testplan, the optional second element must be (if present) another JSON array giving the list of test-case UUID to execute.


As described above, the returned object contains the job ID, which is used to refer to this execution job in further getExecutionInfo or terminateExecution requests (see below).

Download Request "/expeccoService/rest/download"[Bearbeiten]

This is similar to the suite transmission scheme described in the execute request. However, the suite is not executed. The argument is a JSON object with the following fields:

  • SuiteID - mandatory String; the suite's ID
  • Suite - optional String; base64 encoded .ets file
  • SuiteURI - optional String; the URI from which expecco can fetch the suite
  • Parameters - optional Array. For future expansion

The operation is the same as described in the previous SOAP section.

Examples[Bearbeiten]

Example Requests / Responses[Bearbeiten]

Wire protocol of sending a Ping request ("/expecco/rest/ping"):

Request to expecco:

 GET /expeccoService/rest/ping HTTP/1.1 
 Host: localhost:9123 
 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:35.0) Gecko/20100101 Firefox/35.0 
 Accept: application/json 
 Connection: keep-alive 

Response:

 HTTP/1.1 200 OK 
 Content-Type: application/json; charset="utf-8" 
 Content-Length: 4111 
 Connection: Keep-Alive 

 {
    "hello":"exeptn.bh.exept.de",
    "restInterfaceVersion":"1",
    "node":"fancy",
    "osType":"osx",
    "cpuType":"x86_64",
    "osRelease":"10.8.0",
    "architecture":"Darwin",
    "system":"Darwin"
    "numberOfCPUs":4,
    "numberOfRunningTests":0,
    "suiteDirectories":["/Users/cg/work/exept/expecco/projects"],
    "knownTestSuites":["test1.ets","test2.ets"],
    "expeccoRelease":"2.7.0.0",

    "pluginNames":["SwiftMessages","WSDL Import Support","XMI Import Support","RemoteAccess",
                  "SAP  Plugin","DotNET Bridge","SWT GUI Test Plugin","JavaFX GUI Test Plugin","VNC Client",
                  "Android GUI Testing Plugin","SNMP Plugin","Windows Automation Plugin","Manual Test Import 2",
                  "Windows Forms Plugin","Java Browser","Visual Basic Scripting","Swing GUI Test Plugin","Java Import",
                  "Java Bridge","QtTesting","C Header File Parser (DLL Call Generator)","Java Debugger",
                  "Common Java GUI Test Plugin","JIRA Interface","SmallSensePlugin","DocuPrintPlugin","Webtest (Selenium)",
                  "Gembird Power Manager Control","GUI Testing Plugin Platform","EDI-Edifact"],
    "plugins"[...],
    "expeccoPluginID:DLLCallGeneratorPlugin":"e79207a0-0c23-11df-8eaf-00ff7b08316c 1 1.24",
    ...
    "expeccoPluginID:VBScriptPlugin":"09a8d100-eb01-11e3-9aba-6067202bc199 1 1.25",

}

Download request to expecco (without suite-info, to check if the suite is already loaded):

 GET /expeccoService/rest/download HTTP/1.1 
 Host: localhost:9123 
 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:35.0) Gecko/20100101 Firefox/35.0 
 Accept: application/json
 Connection: keep-alive

 {
   "SuiteID":"09a8d1FF-ebF1-12AB-9aba-98ab016389f0",
}

Response (empty, because suite is not present):

 HTTP/1.1 200 OK 
 Content-Type: application/json; charset="utf-8" 
 Content-Length: 4111 
 Connection: Keep-Alive 

 {
}

Download request to expecco (with suite-info, to ensure suite is present):

 GET /expeccoService/rest/download HTTP/1.1 
 Host: localhost:9123 
 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:35.0) Gecko/20100101 Firefox/35.0  
 Accept: application/json 
 Connection: keep-alive

 {
   "SuiteID":"09a8d1FF-ebF1-12AB-9aba-98ab016389f0",
   "Suite":"... base64 encoded .ets suite file ..."
}

Response (non-empty, because suite is now present on the expecco client machine):

 HTTP/1.1 200 OK 
 Content-Type: application/json; charset="utf-8" 
 Content-Length: 4111 
 Connection: Keep-Alive 

 {
   "SuiteID":"09a8d1FF-ebF1-12AB-9aba-98ab016389f0",
}

Execute request to expecco (with suite-info). The suite info is not required, if the above download was done before.

 GET /expeccoService/rest/execute HTTP/1.1 
 Host: localhost:9123 
 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:35.0) Gecko/20100101 Firefox/35.0 
 Accept: application/json 
 Accept-Language: en-US,en;q=0.5 
 Accept-Encoding: gzip, deflate 
 Connection: keep-alive

 {
   "ID":"09ab0149-1234-9876-4583-1259a5e301f5",
   "SuiteID":"09a8d1FF-ebF1-12AB-9aba-98ab016389f0",
   "Suite":"... base64 encoded .ets suite file ..."
}

Response (returns the execution's job ID):

 HTTP/1.1 200 OK 
 Content-Type: application/json; charset="utf-8" 
 Content-Length: 4111 
 Connection: Keep-Alive 

 {
   "ID":"09ab0149-1234-9876-4583-1259a5e301f5",
}

Get progress and status information about a running test:

 GET /expeccoService/rest/getStatusInfo HTTP/1.1 
 Host: localhost:9123 
 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:35.0) Gecko/20100101 Firefox/35.0 
 Accept: application/json 
 Accept-Language: en-US,en;q=0.5 
 Accept-Encoding: gzip, deflate 
 Connection: keep-alive

 {
   "ID":"09ab0149-1234-9876-4583-1259a5e301f5",
}

Response (returns the execution's job ID):

 HTTP/1.1 200 OK 
 Content-Type: application/json; charset="utf-8" 
 Content-Length: 4111 
 Connection: Keep-Alive 

 {
   "ID":"09ab0149-1234-9876-4583-1259a5e301f5",
}

Alternative execute-by-filename request (the suite-file must be present on the slave already):

 GET /expeccoService/rest/executeTestSuiteFile HTTP/1.1 
 Host: localhost:9123 
 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:35.0) Gecko/20100101 Firefox/35.0 
 Accept: application/json 
 Accept-Language: en-US,en;q=0.5 
 Accept-Encoding: gzip, deflate 
 Connection: keep-alive

 {
   "ID":"09ab0149-1234-9876-4583-1259a5e301f6",
   "SuiteFileName":"c:\sharedSuites\test.ets"
}

Perl Client[Bearbeiten]

use REST::Client;
use JSON;
# Data::Dumper makes it easy to see what the JSON returned actually looks like 
# when converted into Perl data structures.
use Data::Dumper;
use MIME::Base64;

my $username = 'admin';
my $password = 'admin';
my $headers = {Accept => 'application/json', Authorization => 'Basic ' . encode_base64($username . ':' . $password)};
my $client = REST::Client->new();
$client->setHost('http://127.0.0.1:9090');

#parameter for start test Request
my $startTestURL = '/expeccoService/rest/executeTestSuiteFileWithTestplanNames';
my $startTestJSONArguments = '{ "ID":"expeccoRemoteExec" "SuiteFileName":"E:/exept/tmp/SimpleBridgeTest.ets" "TestPlans":[ "Demo Testplan" ] "Parameters":[ "generateLog" "true" ]}';

#parameter for wait for test end and generate results Request
my $waitTestEndAndCreateResultURL = '/expeccoService/rest/waitForExecutionResult';
my $waitTestEndAndCreateResultJSONArguments = '{"ID":"expeccoRemoteExec" "ReportFiles":[ {"JUnit_ReportFile":"E:/tmp/logs/SimpleBridgeTestResult.junit"} {"PDF_ReportFile":"E:/tmp/logs/SimpleBridgeTestResult.pdf"} {"TEXT_ReportFile":"E:/tmp/logs/SimpleBridgeTestResult.txt"} {"HTML_ReportFile":"E:/tmp/logs/SimpleBridgeTestResult.html"} ]}';


$client->request('PUT', $startTestURL, $startTestJSONArguments, $headers);
if( $client->responseCode() eq '200' ){
     print "\n=== Test started ===\n";
     #my $response = from_json($client->responseContent());
	 #print Dumper($response);
} else {
	print Dumper($client->responseContent());
}

$client->request('PUT', $waitTestEndAndCreateResultURL, $waitTestEndAndCreateResultJSONArguments, $headers);
if( $client->responseCode() eq '200' ){
     print "\n=== Test execution and result generation finished ===\n";
     #my $response = from_json($client->responseContent());
	 #print Dumper($response);
} else {
	print Dumper($client->responseContent());
}



Copyright © 2014-2024 eXept Software AG