Chapter7: 利用Python的Testlink模块上传测试结果,取代Jenkins中的Testlink插件


本系列文章见总链接:

需要在Python环境中安装Testlink-API-Python-client。TestLink-API-Python-client is a Python XML-RPC client for Testlink

下载链接:https://pypi.org/project/TestLink-API-Python-client/

源代码:https://github.com/lczub/TestLink-API-Python-client

示例代码:https://github.com/lczub/TestLink-API-Python-client/blob/master/doc/usage.rst

安装Testlink模块: pip install TestLink-API-Python-client

在Jenkins Job中的配置

Execute Windows Batch Command in Jenkins Job

 代码:

@echo on
cd "%WORKSPACE%\%BUILD_NUMBER%"
for /F "delims=" %%i in ('findstr /r /c:"do set UUTResult="%%i"
echo %UUTResult% | findstr /c:"Passed" 1>nul
set "testresultlevel=%errorlevel%"
if %errorlevel% == 0 (set exec_status=p) else (set exec_status=f)
set "test_case_name=%ScriptName:~0,-4%"
set "custom_fields_name=%test_case_name%.1Main"
set "custom_fields=AutoTest"
for /f tokens^=8^ delims^=^" %%i in ('findstr /i "time=.*>" Report_JUnit.xml') do set "exec_duration=%%i"

set "exec_notes=%BUILD_URL%;;Project: %Project%;UnitType: %UnitType%;RunningMode: %RunningMode%;SystemInUse: %SystemInUse%;PublicORBritishSystem: %PublicORBritishSystem%;ScriptPath: %ScriptPath%;ScriptName: %ScriptName%;test_plan_name: %test_plan_name%;test_suite_name: %test_suite_name%;build_name: %build_name%;"
set "exec_junit_xml_path=%WORKSPACE%\Report_JUnit.xml"

@echo off
echo url = %TestlinkURL%
echo key = %TestlinkKEY%
echo test_project_name = %Project%
echo test_plan_name = %test_plan_name%
echo test_suite_name = %test_suite_name%
echo test_case_name = %test_case_name%
echo build_name = %build_name%
echo custom_fields_name = %custom_fields_name%
echo exec_status = %exec_status%
echo exec_duration(seconds) = %exec_duration%
echo exec_notes = %exec_notes%
echo exec_junit_xml_path = %exec_junit_xml_path%

@echo on
C:\Python27\python.exe c:\jenkins\UpdateTestExecutionINTestlink.py %TestlinkURL% %TestlinkKEY% "%Project%" "%test_plan_name%" "%test_suite_name%" "%test_case_name%" "%build_name%" "%custom_fields%" "%custom_fields_name%" %exec_status% %exec_duration% "%exec_notes%" "%exec_junit_xml_path%"

exit %testresultlevel%

UpdateTestExecutionINTestlink.py 代码:

# -*- coding:UTF-8 -*-
import testlink
import time
import sys

print("url: %s" %sys.argv[1])     #Testlink api address
print("key: %s" %sys.argv[2])     #Testlink developer key for specified user
print("test_project_name: %s" %sys.argv[3])   #test project name in Testlink
print("test_plan_name: %s" %sys.argv[4])      #test plan name for current test execution 
print("test_suite_name: %s" %sys.argv[5])     #test suite name of the test case
print("test_case_name: %s" %sys.argv[6])      #test case name
print("build_name: %s" %sys.argv[7])          #the build name, would be the SW version
print("custom_fields: %s" %sys.argv[8])       #the custom fields defined in Testlink
print("custom_fields_name: %s" %sys.argv[9])  #the custom fields value in test case
print("exec_status: %s" %sys.argv[10])        #the test status for current test execution
print("exec_duration(seconds): %s" %sys.argv[11])    #the duration for current test execution
print("exec_notes: %s" %sys.argv[12].replace(";","\n"))     #the useful information of jenkins job would be uploaded to Testlink
print("exec_junit_xml_path: %s" %sys.argv[13])     #the path of the Junit type XML file for current test execution results
url = sys.argv[1]
key = sys.argv[2]
test_project_name = sys.argv[3]
test_plan_name = sys.argv[4]
test_suite_name = sys.argv[5]
test_case_name = sys.argv[6]
build_name = sys.argv[7]
dict_key = sys.argv[8]
custom_fields = {}
custom_fields[dict_key] = sys.argv[9]
exec_status = sys.argv[10]
exec_duration = sys.argv[11]
exec_duration=round(float(exec_duration)//float(60.0) + float(exec_duration)%float(60.0)/float(60.0),2)     #convert the time from seconds to minutes
print("exec_duration(minutes): %s" %exec_duration)
exec_notes = sys.argv[12].replace(";","\n")+"\nTime: "+str(exec_duration)+" minutes\n"     #replace ; with \n . Then the note in Testlink would be readable
print("exec_notes: %s" %exec_notes)
exec_junit_xml_path = sys.argv[13]

tlc = testlink.TestlinkAPIClient(url,key)
for project in projects:
    print("testProject",project["id"],project["name"])    #print all project with id and name
for project in projects:
    if project["name"]==test_project_name:                
        project_id=project["id"]                          #get the project id by the known name
        print("project_id: %s" %project_id)
test_plans=tlc.getProjectTestPlans(project_id)            
for test_plan in test_plans:
    if test_plan["name"]==test_plan_name:
        test_plan_id=test_plan["id"]                      #get the test plan id by the known name
        print("test_plan_id: %s" %test_plan_id)
test_suites=tlc.getTestSuitesForTestPlan(test_plan_id)    #get the test suites by test plan id
for test_suite in test_suites:
    if test_suite["name"]==test_suite_name:
        test_suite_id=test_suite["id"]                    #get the test suite id by test suite name
        print("test_suite_id: %s" %test_suite_id)
test_cases=tlc.getTestCasesForTestSuite(test_suite_id,True,None)
for test_case in test_cases:
    if test_case["name"] == test_case_name:
        test_case_id=test_case["id"]                      #get the test case id by test case name
        print("test_case_id: %s" %test_case_id)
localtime=time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())            #define the current time stamp

newBuild = tlc.createBuild(test_plan_id,build_name,'Build created automatically with Python')    #Create the build in Testlink

newResult = tlc.reportTCResult(testcaseid=test_case_id,testplanid=test_plan_id,status=exec_status,guess=True,testcaseexternalid=None,platformname=None,buildname=build_name,customfields=custom_fields,execduration=exec_duration,timestamp=localtime,notes=exec_notes)
print(newResult)
newAttachment = tlc.uploadExecutionAttachment(exec_junit_xml_path,newResult[0]['id'],test_case_name,'Description')

在Python中查看方法使用:

Python 2.7.17 (v2.7.17:c2f86d86e6, Oct 19 2019, 20:49:36) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import testlink
>>> tlc = testlink.TestlinkAPIClient("http://10.90.69.239:8181/testlink-1.9.20/lib/api/xmlrpc/v1/xmlrpc.php","740c93c48fa88452c4e172c15b161ffc")
>>> print tlc.whatArgs('reportTCResult')
reportTCResult(, , , , , [testcaseexternalid=], [buildid=], [platformid=], [platformname=], [guess=], [bugid=], [customfields=], [overwrite=], [user=], [execduration=], [timestamp=], [steps=], [devKey=])
 Reports a result for a single test case

        args variations: testcaseid - testcaseexternalid
                         buildid - buildname
                         platformid - platformname

        customfields : dictionary with customfields names + values
            VERY IMPORTANT: value must be formatted in the way it's written to db
        overwrite    : if present and true, then last execution for
                       (testcase,testplan,build,platform) will be overwritten.
        user : if present and user is a valid login (no other check will be done)
               it will be used when writing execution.
        execduration : Exec (min) as float (2.5 = 2min 30sec)
        timestamp    : 'YYYY-MM-DD hh:mm[:ss]'#
        steps        : [{'step_number' : 6, 'result' : 'p', 'notes" : 'a_note'},
                        {'step_number' : 7, 'result' : 'f', 'notes" : 'blabla'}]

>>> print tlc.whatArgs('uploadExecutionAttachment')
uploadExecutionAttachment(, , , <description>, [filename=<filename>], [filetype=<filetype>], [content=<content>], [devKey=<devKey>])<span style="color: rgba(0, 0, 0, 1)">
 Uploads an attachment </span><span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> an execution

        executionid - execution ID

        mandatory non api args: attachmentfile
        - python file descriptor pointing to the file
        - or a valid file </span><span style="color: rgba(0, 0, 255, 1)">path</span><span style="color: rgba(0, 0, 0, 1)">

        default values </span><span style="color: rgba(0, 0, 255, 1)">for</span> filename, filetype,<span style="color: rgba(0, 0, 0, 1)"> content are determine from
        ATTACHMENTFILE</span>, but user could overwrite it, <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> user want to store the
        attachment with a different name

</span>>>></pre>



<pre>>>> help(testlink.TestlinkAPIClient)<span style="color: rgba(0, 0, 0, 1)">
Help </span><span style="color: rgba(0, 0, 255, 1)">on</span> class TestlinkAPIClient in module testlink.<span style="color: rgba(0, 0, 0, 1)">testlinkapi:

class TestlinkAPIClient</span>(testlink.testlinkapigeneric.TestlinkAPIGeneric)<span style="color: rgba(0, 0, 0, 1)">
 |  client </span><span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> XML-RPC communication between Python and TestLink
 |
 |  Inherits TestLink API methods from the generic client TestlinkAPIGeneric</span>.<span style="color: rgba(0, 0, 0, 1)">
 |
 |  Defines Service Methods like </span>"countProjects"<span style="color: rgba(0, 0, 0, 1)"> and change the
 |  configuration </span><span style="color: rgba(0, 0, 255, 1)">for</span> positional and optional arguments in a way,<span style="color: rgba(0, 0, 0, 1)"> that often
 |  used arguments are positional</span>.<span style="color: rgba(0, 0, 0, 1)">
 |  - see _changePositionalArgConfig</span>()<span style="color: rgba(0, 0, 0, 1)">
 |  - configuration of positional arguments is consistent with v0</span>.4.0<span style="color: rgba(0, 0, 0, 1)">
 |
 |  Changes </span><span style="color: rgba(0, 0, 255, 1)">on</span> Service Methods like "countProjects"<span style="color: rgba(0, 0, 0, 1)"> should be implemented in
 |  this class or sub classes
 |  Changes of TestLink API methods should be implemented in generic API
 |  TestlinkAPIGeneric</span>.<span style="color: rgba(0, 0, 0, 1)">
 |
 |  Method resolution order:
 |      TestlinkAPIClient
 |      testlink</span>.testlinkapigeneric.<span style="color: rgba(0, 0, 0, 1)">TestlinkAPIGeneric
 |      __builtin__</span>.<span style="color: rgba(0, 0, 0, 1)">object
 |
 |  Methods defined here:
 |
 |  __init__</span>(self, server_url, devKey, **kwargs)<span style="color: rgba(0, 0, 0, 1)">
 |      </span><span style="color: rgba(0, 0, 255, 1)">call</span> super <span style="color: rgba(0, 0, 255, 1)">for</span> init generell slots, init sepcial slots <span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> teststeps
 |      and define special positional arg settings
 |
 |  appendStep</span>(self, actions, expected_results, execution_type)<span style="color: rgba(0, 0, 0, 1)">
 |      appendStep :
 |      Appends a step to the steps list
 |
 |  copyTCnewTestCase</span>(self, origTestCaseId, origVersion=None, **changedAttributes)<span style="color: rgba(0, 0, 0, 1)">
 |      creates a test case with values from test case ORIGTESTCASEID
 |
 |      ORIGVERSION specifies the test case version</span>, which should be copied,<span style="color: rgba(0, 0, 0, 1)">
 |                  default is the max version number
 |
 |      </span><span style="color: rgba(0, 0, 255, 1)">if</span> the new test case should differ from the original test case,<span style="color: rgba(0, 0, 0, 1)"> changed
 |      api arguments could be defined as key value pairs</span>.<span style="color: rgba(0, 0, 0, 1)">
 |      Example </span><span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> changed test suite and importance:
 |      -  copyTCnewTestCaseVersion</span>('4711', testsuiteid = '1007',<span style="color: rgba(0, 0, 0, 1)">
 |                                          importance </span>= '1')<span style="color: rgba(0, 0, 0, 1)">
 |
 |      Remarks </span><span style="color: rgba(0, 0, 255, 1)">for</span> some special <span style="color: rgba(0, 0, 255, 1)">keys</span><span style="color: rgba(0, 0, 0, 1)">:
 |      'testsuiteid': defines</span>, in which test suite the TC-<span style="color: rgba(0, 0, 255, 1)">copy</span> is inserted.<span style="color: rgba(0, 0, 0, 1)">
 |               Default is the same test suite as the original test case</span>.<span style="color: rgba(0, 0, 0, 1)">
 |      'steps': must be a complete list of all steps</span>,<span style="color: rgba(0, 0, 0, 1)"> changed and unchanged steps
 |               Maybe its better to change the steps in a separat </span><span style="color: rgba(0, 0, 255, 1)">call</span><span style="color: rgba(0, 0, 0, 1)"> using
 |               createTestCaseSteps with action</span>='update'.<span style="color: rgba(0, 0, 0, 1)">
 |
 |  copyTCnewVersion</span>(self, origTestCaseId, origVersion=None, **changedAttributes)<span style="color: rgba(0, 0, 0, 1)">
 |      creates a new version </span><span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> test case ORIGTESTCASEID
 |
 |      ORIGVERSION specifies the test case version</span>, which should be copied,<span style="color: rgba(0, 0, 0, 1)">
 |                  default is the max version number
 |
 |      </span><span style="color: rgba(0, 0, 255, 1)">if</span> the new version should differ from the original test case,<span style="color: rgba(0, 0, 0, 1)"> changed
 |      api arguments could be defined as key value pairs</span>.<span style="color: rgba(0, 0, 0, 1)">
 |      Example </span><span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> changed summary and importance:
 |      -  copyTCnewVersion</span>('4711', summary = 'The summary has changed',<span style="color: rgba(0, 0, 0, 1)">
 |                                  importance </span>= '1')<span style="color: rgba(0, 0, 0, 1)">
 |      Remarks </span><span style="color: rgba(0, 0, 255, 1)">for</span> some special <span style="color: rgba(0, 0, 255, 1)">keys</span><span style="color: rgba(0, 0, 0, 1)">:
 |      'steps': must be a complete list of all steps</span>,<span style="color: rgba(0, 0, 0, 1)"> changed and unchanged steps
 |               Maybe its better to change the steps in a separat </span><span style="color: rgba(0, 0, 255, 1)">call</span><span style="color: rgba(0, 0, 0, 1)"> using
 |               createTestCaseSteps with action</span>='update'.<span style="color: rgba(0, 0, 0, 1)">
 |
 |  countBuilds</span>(self)<span style="color: rgba(0, 0, 0, 1)">
 |      countBuilds :
 |      Count all the Builds
 |
 |  countPlatforms</span>(self)<span style="color: rgba(0, 0, 0, 1)">
 |      countPlatforms :
 |      Count all the Platforms in TestPlans
 |
 |  countProjects</span>(self)<span style="color: rgba(0, 0, 0, 1)">
 |      countProjects :
 |      Count all the test project
 |
 |  countTestCasesTP</span>(self)<span style="color: rgba(0, 0, 0, 1)">
 |      countProjects :
 |      Count all the test cases linked to a Test Plan
 |
 |  countTestCasesTS</span>(self)<span style="color: rgba(0, 0, 0, 1)">
 |      countProjects :
 |      Count all the test cases linked to a Test Suite
 |
 |  countTestPlans</span>(self)<span style="color: rgba(0, 0, 0, 1)">
 |      countProjects :
 |      Count all the test plans
 |
 |  countTestSuites</span>(self)<span style="color: rgba(0, 0, 0, 1)">
 |      countProjects :
 |      Count all the test suites
 |
 |  createTestCase</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      createTestCase: Create a test case
 |      positional args: testcasename</span>, testsuiteid, testprojectid, authorlogin,<span style="color: rgba(0, 0, 0, 1)">
 |                       summary
 |      optional args : steps</span>, preconditions, importance, executiontype, order,<span style="color: rgba(0, 0, 0, 1)">
 |                      internalid</span>, checkduplicatedname, actiononduplicatedname,<span style="color: rgba(0, 0, 0, 1)">
 |                      status</span>,<span style="color: rgba(0, 0, 0, 1)"> estimatedexecduration
 |
 |      argument 'steps' will be </span><span style="color: rgba(0, 0, 255, 1)">set</span> with values from .stepsList,<span style="color: rgba(0, 0, 0, 1)">
 |      - </span><span style="color: rgba(0, 0, 255, 1)">when</span> argsOptional does <span style="color: rgba(0, 0, 255, 1)">not</span><span style="color: rgba(0, 0, 0, 1)"> include a 'steps' item
 |      - </span>.stepsList can be filled before <span style="color: rgba(0, 0, 255, 1)">call</span> via .initStep() and .appendStep()<span style="color: rgba(0, 0, 0, 1)">
 |
 |      otherwise</span>,<span style="color: rgba(0, 0, 0, 1)"> optional arg 'steps' must be defined as a list with
 |      dictionaries </span>,<span style="color: rgba(0, 0, 0, 1)"> example
 |          [{'step_number' : </span>1, 'actions' : "action A" ,<span style="color: rgba(0, 0, 0, 1)">
 |              'expected_results' : </span>"result A", 'execution_type' : 0},<span style="color: rgba(0, 0, 0, 1)">
 |               {'step_number' : </span>2, 'actions' : "action B" ,<span style="color: rgba(0, 0, 0, 1)">
 |              'expected_results' : </span>"result B", 'execution_type' : 1},<span style="color: rgba(0, 0, 0, 1)">
 |               {'step_number' : </span>3, 'actions' : "action C" ,<span style="color: rgba(0, 0, 0, 1)">
 |              'expected_results' : </span>"result C", 'execution_type' : 0<span style="color: rgba(0, 0, 0, 1)">}]
 |
 |  </span><span style="color: rgba(0, 0, 255, 1)">echo</span>(self, message)<span style="color: rgba(0, 0, 0, 1)">
 |
 |  getProjectIDByName</span>(self, projectName)<span style="color: rgba(0, 0, 0, 1)">
 |
 |  getProjectIDByNode</span>(self, a_nodeid)<span style="color: rgba(0, 0, 0, 1)">
 |      returns project id </span>, the nodeid belongs to.<span style="color: rgba(0, 0, 0, 1)">
 |
 |  getTestCaseByVersion</span>(self, testCaseID, version=None)<span style="color: rgba(0, 0, 0, 1)">
 |      Gets testcase information based </span><span style="color: rgba(0, 0, 255, 1)">on</span> the version.<span style="color: rgba(0, 0, 0, 1)">
 |
 |      </span><span style="color: rgba(128, 0, 0, 1)">:param</span> testCaseID: test case to search <span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)">
 |      </span><span style="color: rgba(128, 0, 0, 1)">:param</span> version: version to search <span style="color: rgba(0, 0, 255, 1)">for</span> defaults to None. None searches <span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> latest
 |      </span><span style="color: rgba(128, 0, 0, 1)">:return</span><span style="color: rgba(0, 0, 0, 1)">: test case info dictionary
 |
 |  getTestCaseIDByName</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      getTestCaseIDByName : </span><span style="color: rgba(0, 0, 255, 1)">Find</span><span style="color: rgba(0, 0, 0, 1)"> a test case by its name
 |      positional args: testcasename</span>,<span style="color: rgba(0, 0, 0, 1)">
 |      optional args : testsuitename</span>, testprojectname,<span style="color: rgba(0, 0, 0, 1)"> testcasepathname
 |
 |      testcasepathname : Full test case </span><span style="color: rgba(0, 0, 255, 1)">path</span> name,<span style="color: rgba(0, 0, 0, 1)">
 |              starts with test project name </span>, pieces separator -> <span style="color: rgba(0, 128, 0, 1)">::
</span><span style="color: rgba(0, 0, 0, 1)"> |
 |      server </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> can be a list or a dictionary
 |      - optional arg testprojectname seems to create a dictionary response
 |
 |      this methods customize the generic behaviour and converts a dictionary
 |      response into a list</span>, so methods <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> will be always a list
 |
 |  initStep</span>(self, actions, expected_results, execution_type)<span style="color: rgba(0, 0, 0, 1)">
 |      initStep :
 |      Initializes the list which stores the Steps of a Test Case to create
 |
 |  listKeywordsForTC</span>(self, internal_or_external_tc_id)<span style="color: rgba(0, 0, 0, 1)">
 |      Returns list with keyword </span><span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> a test case
 |      INTERNAL_OR_EXTERNAL_TC_ID defines
 |      - either the internal test case ID </span>(8111 or '8111')<span style="color: rgba(0, 0, 0, 1)">
 |      - or the full external test case ID </span>('NPROAPI-2')<span style="color: rgba(0, 0, 0, 1)">
 |
 |      Attention:
 |      - the tcversion_id is </span><span style="color: rgba(0, 0, 255, 1)">not</span><span style="color: rgba(0, 0, 0, 1)"> supported
 |      - it is </span><span style="color: rgba(0, 0, 255, 1)">not</span> possible to ask <span style="color: rgba(0, 0, 255, 1)">for</span> a special test case version,<span style="color: rgba(0, 0, 0, 1)"> cause TL
 |        links keywords against a test case and </span><span style="color: rgba(0, 0, 255, 1)">not</span><span style="color: rgba(0, 0, 0, 1)"> a test case version
 |
 |  listKeywordsForTS</span>(self, internal_ts_id)<span style="color: rgba(0, 0, 0, 1)">
 |      Returns dictionary with keyword lists </span><span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> all test cases of
 |      test suite with id </span>==<span style="color: rgba(0, 0, 0, 1)"> INTERNAL_TS_ID
 |
 |  listProjects</span>(self)<span style="color: rgba(0, 0, 0, 1)">
 |      listProjects :
 |      Lists the Projects </span>(display Name & ID)<span style="color: rgba(0, 0, 0, 1)">
 |
 |  ----------------------------------------------------------------------
 |  Data descriptors defined here:
 |
 |  stepsList
 |
 |  ----------------------------------------------------------------------
 |  Data and other attributes defined here:
 |
 |  __author__ </span>= 'Luiko Czub, Olivier Renault, James Stock, TestLink-API-P...<span style="color: rgba(0, 0, 0, 1)">
 |
 |  ----------------------------------------------------------------------
 |  Methods inherited from testlink</span>.testlinkapigeneric.<span style="color: rgba(0, 0, 0, 1)">TestlinkAPIGeneric:
 |
 |  __str__</span>(self)<span style="color: rgba(0, 0, 0, 1)">
 |
 |  about</span>(self)<span style="color: rgba(0, 0, 0, 1)">
 |      Gives basic information about the API
 |
 |  addPlatformToTestPlan</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Adds a platform to a test plan
 |
 |  addTestCaseKeywords</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      adds list of keywords to a </span><span style="color: rgba(0, 0, 255, 1)">set</span><span style="color: rgba(0, 0, 0, 1)"> of test cases
 |
 |      expects as arg </span><keywords><span style="color: rgba(0, 0, 0, 1)"> a dictionary with
 |        </span><testcaseexternalid> as a key and <list of keywords><span style="color: rgba(0, 0, 0, 1)"> as value
 |
 |      example:
 |        {'TC-</span>4711' : ['KeyWord02'], 'TC-4712' : ['KeyWord01',<span style="color: rgba(0, 0, 0, 1)"> KeyWord03']}
 |
 |        adds to test case 'TC-</span>4711<span style="color: rgba(0, 0, 0, 1)">' the keyword 'KeyWord02'
 |        adds to test case 'TC-</span>4712' the keywords 'KeyWord01' +<span style="color: rgba(0, 0, 0, 1)"> KeyWord03'
 |
 |  addTestCaseToTestPlan</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Add a test case version to a test plan
 |
 |  assignRequirements</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      </span><span style="color: rgba(0, 0, 255, 1)">Assign</span><span style="color: rgba(0, 0, 0, 1)"> Requirements to a test case
 |      It is possible to </span><span style="color: rgba(0, 0, 255, 1)">assign</span> multiple requirements,<span style="color: rgba(0, 0, 0, 1)"> belonging to different
 |      requirement specifications</span>. (the internal IDs must be known!)<span style="color: rgba(0, 0, 0, 1)">
 |
 |      Argument REQUIREMENTS expects an array of dictionaries</span>,<span style="color: rgba(0, 0, 0, 1)"> example:
 |      </span>.assignRequirements('GPROAPI4-2', 6652,<span style="color: rgba(0, 0, 0, 1)">
 |                         [{'req_spec' : </span>6729, 'requirements' : [6731]},<span style="color: rgba(0, 0, 0, 1)">
 |                          {'req_spec' : </span>6733, 'requirements' : [6735, 6737]}])<span style="color: rgba(0, 0, 0, 1)">
 |      This would </span><span style="color: rgba(0, 0, 255, 1)">assign</span> to testcase 'GPROAPI4-2' (in testproject with id 6652)<span style="color: rgba(0, 0, 0, 1)">
 |      a</span>) requirement with ID 6731 of requirement spec 6729<span style="color: rgba(0, 0, 0, 1)"> AND
 |      b</span>) requirements with ID 6735 and 6737 of requirement spec 6733<span style="color: rgba(0, 0, 0, 1)">
 |
 |  assignTestCaseExecutionTask</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      assigns a user to a test case execution task
 |
 |      user                 login name </span>=><span style="color: rgba(0, 0, 0, 1)"> tester
 |      testplanid           test plan id
 |      testcaseexternalid   </span><span style="color: rgba(0, 0, 255, 1)">format</span><span style="color: rgba(0, 0, 0, 1)"> PREFIX-NUMBER
 |
 |      args variations:     buildid - buildname
 |                           platformid - platformname
 |      build information is general mandatory
 |      platform information is required</span>, <span style="color: rgba(0, 0, 255, 1)">when</span><span style="color: rgba(0, 0, 0, 1)"> test plan has assigned platforms
 |
 |  callServerWithPosArgs</span>(self, methodNameAPI, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      concat argsPositional and argsOptional before calling
 |      server method methodNameAPI
 |
 |  checkDevKey</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      check </span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> Developer Key exists
 |      returns true </span><span style="color: rgba(0, 0, 255, 1)">if</span> everything OK,<span style="color: rgba(0, 0, 0, 1)"> otherwise error structure
 |
 |  connectionInfo</span>(self)<span style="color: rgba(0, 0, 0, 1)">
 |      </span><span style="color: rgba(0, 0, 255, 1)">print</span><span style="color: rgba(0, 0, 0, 1)"> current SERVER URL and DEVKEY settings and servers VERSION
 |
 |  createBuild</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Creates a new build </span><span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> a specific test plan
 |
 |      active      : </span>1 (default) = activ  0 =<span style="color: rgba(0, 0, 0, 1)"> inactiv
 |      open        : </span>1 (default) = open   0 =<span style="color: rgba(0, 0, 0, 1)"> closed
 |      releasedate : YYYY-MM-DD
 |      copytestersfrombuild : valid buildid tester assignments will be copied</span>.<span style="color: rgba(0, 0, 0, 1)">
 |
 |  createPlatform</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Creates a platform </span><span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> test project
 |
 |  createTestCaseSteps</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      creates new test steps or updates existing test steps
 |
 |      action - possible values: 'create'</span>,'update',<span style="color: rgba(0, 0, 0, 1)">'push'
 |          create: </span><span style="color: rgba(0, 0, 255, 1)">if</span> step <span style="color: rgba(0, 0, 255, 1)">exist</span><span style="color: rgba(0, 0, 0, 1)"> NOTHING WILL BE DONE
 |          update: </span><span style="color: rgba(0, 0, 255, 1)">if</span> step DOES <span style="color: rgba(0, 0, 255, 1)">NOT</span> <span style="color: rgba(0, 0, 255, 1)">EXIST</span> will be created <span style="color: rgba(0, 0, 255, 1)">else</span> will be updated.<span style="color: rgba(0, 0, 0, 1)">
 |          push: </span><span style="color: rgba(0, 0, 255, 1)">NOT</span> IMPLEMENTED YET (TL 1.9.9)<span style="color: rgba(0, 0, 0, 1)">
 |                </span><span style="color: rgba(0, 0, 255, 1)">shift</span> down all steps with step number >=<span style="color: rgba(0, 0, 0, 1)"> step number provided
 |                and </span><span style="color: rgba(0, 0, 255, 1)">use</span> provided data to create step number requested.<span style="color: rgba(0, 0, 0, 1)">
 |      steps - each element is a hash with following </span><span style="color: rgba(0, 0, 255, 1)">keys</span><span style="color: rgba(0, 0, 0, 1)">
 |          step_number</span>,actions,expected_results,<span style="color: rgba(0, 0, 0, 1)">execution_type
 |      args variations: testcaseid - testcaseexternalid
 |      version - optional </span><span style="color: rgba(0, 0, 255, 1)">if</span> <span style="color: rgba(0, 0, 255, 1)">not</span><span style="color: rgba(0, 0, 0, 1)"> provided LAST ACTIVE version will be used
 |                </span><span style="color: rgba(0, 0, 255, 1)">if</span> all versions are INACTIVE, <span style="color: rgba(0, 0, 255, 1)">then</span> latest version will be used.<span style="color: rgba(0, 0, 0, 1)">
 |
 |  createTestPlan</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      create a test plan
 |
 |      args variations: testprojectname - prefix
 |
 |      supports also pre </span>1.9.14 arg definition,<span style="color: rgba(0, 0, 0, 1)"> where 'testprojectname'
 |      was mandatory </span>('prefix' comes as alternative with 1.9.14)<span style="color: rgba(0, 0, 0, 1)">
 |
 |      examples:
 |      - createTestPlan</span>('aTPlanName', 'aTProjectName')<span style="color: rgba(0, 0, 0, 1)">
 |      - createTestPlan</span>('aTPlanName', testprojectname='aTProjectName')<span style="color: rgba(0, 0, 0, 1)">
 |      - createTestPlan</span>('aTPlanName', prefix='aTProjectPrefix')<span style="color: rgba(0, 0, 0, 1)">
 |
 |  createTestProject</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Create a test project
 |
 |      options : dictionary with </span><span style="color: rgba(0, 0, 255, 1)">keys</span><span style="color: rgba(0, 0, 0, 1)">
 |                  requirementsEnabled</span>, testPriorityEnabled,<span style="color: rgba(0, 0, 0, 1)">
 |                  automationEnabled</span>,<span style="color: rgba(0, 0, 0, 1)">inventoryEnabled
 |               and values </span>0 (false) and 1 (true)<span style="color: rgba(0, 0, 0, 1)">
 |
 |  createTestSuite</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      create a test suite
 |
 |  deleteExecution</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      delete an execution
 |
 |      Default TL server configuration does </span><span style="color: rgba(0, 0, 255, 1)">not</span><span style="color: rgba(0, 0, 0, 1)"> allow deletion of exections
 |      see Installation & Configuration Manual Version </span>1.9<span style="color: rgba(0, 0, 0, 1)">
 |          chap</span>. 5.8.<span style="color: rgba(0, 0, 0, 1)"> Test execution settings
 |          </span>$tlCfg->exec_cfg-><span style="color: rgba(0, 0, 0, 1)">can_delete_execution
 |
 |  deleteTestCaseSteps</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      deletes test cases steps
 |
 |      steps - each element is a step_number
 |      version - optional </span><span style="color: rgba(0, 0, 255, 1)">if</span> <span style="color: rgba(0, 0, 255, 1)">not</span><span style="color: rgba(0, 0, 0, 1)"> provided LAST ACTIVE version will be used
 |
 |  deleteTestPlan</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Delete a test plan and all related link to other items
 |
 |  deleteTestProject</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Delete a test project and all related link to other items
 |
 |  doesUserExist</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Checks </span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> user name exists
 |      returns true </span><span style="color: rgba(0, 0, 255, 1)">if</span> everything OK,<span style="color: rgba(0, 0, 0, 1)"> otherwise error structure
 |
 |  getAllExecutionsResults</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Gets ALL EXECUTIONS </span><span style="color: rgba(0, 0, 255, 1)">for</span> a particular testcase <span style="color: rgba(0, 0, 255, 1)">on</span> a test plan.<span style="color: rgba(0, 0, 0, 1)">
 |          </span><span style="color: rgba(0, 0, 255, 1)">If</span> there are no filter criteria regarding platform and build,<span style="color: rgba(0, 0, 0, 1)">
 |          result will be get WITHOUT checking </span><span style="color: rgba(0, 0, 255, 1)">for</span> a particular platform and build.<span style="color: rgba(0, 0, 0, 1)">
 |
 |      mandatory arg: testplanid - identifies the test plan
 |
 |      mandatory args variations: testcaseid - testcaseexternalid
 |      - test case information is general mandatory
 |
 |      optional args:  buildid
 |                      platformid
 |
 |      options : dictionary with key 'getBugs' and
 |                                values </span>0 (false = default) or 1 (true)<span style="color: rgba(0, 0, 0, 1)">
 |
 |  getBuildsForTestPlan</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Gets a list of builds within a test plan
 |
 |      returns an empty list</span>, <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> no build is assigned
 |
 |  getExecCountersByBuild</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Gets execution metrics information </span><span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> a testplan
 |
 |  getExecutionSet</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Gets a </span><span style="color: rgba(0, 0, 255, 1)">set</span> of EXECUTIONS <span style="color: rgba(0, 0, 255, 1)">for</span> a particular testcase <span style="color: rgba(0, 0, 255, 1)">on</span> a test plan.<span style="color: rgba(0, 0, 0, 1)">
 |          </span><span style="color: rgba(0, 0, 255, 1)">If</span> there are no filter criteria regarding platform and build,<span style="color: rgba(0, 0, 0, 1)"> result
 |          will be get WITHOUT checking </span><span style="color: rgba(0, 0, 255, 1)">for</span> a particular platform and build.<span style="color: rgba(0, 0, 0, 1)">
 |
 |      mandatory arg: testplanid - identifies the test plan
 |
 |      mandatory args variations: testcaseid - testcaseexternalid
 |      - test case information is general mandatory
 |
 |      optional args variations:  buildid - buildname
 |                                 platformid - platformname
 |
 |      options : dictionary with key 'getOrderDescending' and
 |                                values </span>0 (false = default) or 1 (true)<span style="color: rgba(0, 0, 0, 1)">
 |
 |  getFirstLevelTestSuitesForTestProject</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      get </span><span style="color: rgba(0, 0, 255, 1)">set</span> of test suites AT TOP LEVEL of <span style="color: rgba(0, 0, 255, 1)">tree</span> <span style="color: rgba(0, 0, 255, 1)">on</span><span style="color: rgba(0, 0, 0, 1)"> a Test Project
 |
 |      returns an empty list</span>, <span style="color: rgba(0, 0, 255, 1)">if</span> no suite is assigned (api error 7008)<span style="color: rgba(0, 0, 0, 1)">
 |      - details see comments </span><span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> decoMakerApiCallReplaceTLResponseError
 |
 |  getFullPath</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Gets full </span><span style="color: rgba(0, 0, 255, 1)">path</span><span style="color: rgba(0, 0, 0, 1)"> from the given node till the top using nodes_hierarchy_table
 |
 |      nodeid </span>=<span style="color: rgba(0, 0, 0, 1)"> can be just a single id or a list with ids
 |               ATTENTION: id must be an integer</span>.<span style="color: rgba(0, 0, 0, 1)">
 |
 |  getIssueTrackerSystem</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Get Issue Tracker System by name
 |
 |  getLastExecutionResult</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Gets the result of LAST EXECUTION </span><span style="color: rgba(0, 0, 255, 1)">for</span> a particular testcase <span style="color: rgba(0, 0, 255, 1)">on</span> a test plan.<span style="color: rgba(0, 0, 0, 1)">
 |      </span><span style="color: rgba(0, 0, 255, 1)">If</span> there are no filter criteria regarding platform and build,<span style="color: rgba(0, 0, 0, 1)">
 |      result will be get WITHOUT checking </span><span style="color: rgba(0, 0, 255, 1)">for</span> a particular platform and build.<span style="color: rgba(0, 0, 0, 1)">
 |
 |      following optional arguments could only used with
 |      TL version </span>>= 1.9.9<span style="color: rgba(0, 0, 0, 1)">
 |      - platformid</span>, platformname, buildid,<span style="color: rgba(0, 0, 0, 1)"> buildname
 |
 |      TL version </span>>= 1.9.11<span style="color: rgba(0, 0, 0, 1)">
 |      - options : dictionary with key value pair
 |                          'getBugs' : True </span>/<span style="color: rgba(0, 0, 0, 1)"> False
 |
 |  getLatestBuildForTestPlan</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Gets the latest build by choosing the maximum build id </span><span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> a specific test plan
 |
 |  getProjectKeywords</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Gets a dictionary of valid keywords </span><span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> a project
 |
 |      returns an empty dictionary</span>, <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> no keywords are defined
 |
 |  getProjectPlatforms</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Gets a dictionary of platforms </span><span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> a project
 |
 |      returns an empty dictionary</span>, <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> no platform is assigned
 |
 |  getProjectTestPlans</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Gets a list of test plans within a project
 |
 |      returns an empty list</span>, <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> no testplan is assigned
 |
 |  getProjects</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Gets a list of all projects
 |
 |      returns an empty list</span>, <span style="color: rgba(0, 0, 255, 1)">if</span> no test project <span style="color: rgba(0, 0, 255, 1)">exist</span><span style="color: rgba(0, 0, 0, 1)">
 |
 |  getReqCoverage</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Get requirement coverage</span>.<span style="color: rgba(0, 0, 0, 1)">
 |          Retrieve the test cases associated to a requirement
 |
 |      mandatory arg:
 |          testprojectid    - identifies the test project
 |          requirementdocid - identifies the requirement
 |
 |  getReqSpecCustomFieldDesignValue</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Gets a Custom Field of a Requirement Specification in Design Scope</span>.<span style="color: rgba(0, 0, 0, 1)">
 |
 |  getRequirementCustomFieldDesignValue</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Gets a Custom Field of a Requirement Specification in Design Scope</span>.<span style="color: rgba(0, 0, 0, 1)">
 |
 |  getRequirements</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Get requirements</span>.<span style="color: rgba(0, 0, 0, 1)">
 |
 |      mandatory arg: testprojectid - identifies the test project
 |
 |      optional args: testplanid</span>,<span style="color: rgba(0, 0, 0, 1)"> platformid
 |
 |  getTestCase</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      get test case specification using external or internal id
 |
 |      attention - be careful with testcaseexternalid - it must include an '-'</span>.<span style="color: rgba(0, 0, 0, 1)">
 |      otherwise TL </span>(<=1.9.8)<span style="color: rgba(0, 0, 0, 1)"> returns
 |      </span><ProtocolError <span style="color: rgba(0, 0, 255, 1)">for</span> xmlrpc.php: 500 Internal Server Error><span style="color: rgba(0, 0, 0, 1)">
 |
 |  getTestCaseAssignedTester</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Gets the result of LAST EXECUTION </span><span style="color: rgba(0, 0, 255, 1)">for</span> a particular testcase <span style="color: rgba(0, 0, 255, 1)">on</span><span style="color: rgba(0, 0, 0, 1)"> a
 |      test plan</span>.<span style="color: rgba(0, 0, 0, 1)">
 |
 |      testplanid           test plan id
 |      testcaseexternalid   </span><span style="color: rgba(0, 0, 255, 1)">format</span><span style="color: rgba(0, 0, 0, 1)"> PREFIX-NUMBER
 |
 |      args variations:     buildid - buildname
 |                           platformid - platformname
 |      build information is general mandatory
 |      platform information is required</span>, <span style="color: rgba(0, 0, 255, 1)">when</span><span style="color: rgba(0, 0, 0, 1)"> test plan has assigned platforms
 |
 |  getTestCaseAttachments</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Gets attachments </span><span style="color: rgba(0, 0, 255, 1)">for</span> specified test case.<span style="color: rgba(0, 0, 0, 1)">
 |
 |      args variations: testcaseid - testcaseexternalid
 |
 |      version - optional</span>, <span style="color: rgba(0, 0, 255, 1)">if</span> <span style="color: rgba(0, 0, 255, 1)">not</span> present,<span style="color: rgba(0, 0, 0, 1)"> the latest test case version
 |                will be used
 |
 |      The attachment file content is Base64 encoded</span>.<span style="color: rgba(0, 0, 0, 1)"> To save the file to disk
 |      in client</span>, Base64 decode the content and write file in binary <span style="color: rgba(0, 0, 255, 1)">mode</span>.<span style="color: rgba(0, 0, 0, 1)">
 |
 |  getTestCaseBugs</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Returns all bugs linked to a particular testcase </span><span style="color: rgba(0, 0, 255, 1)">on</span> a test plan.<span style="color: rgba(0, 0, 0, 1)">
 |      </span><span style="color: rgba(0, 0, 255, 1)">If</span> there are no filter criteria regarding platform and build,<span style="color: rgba(0, 0, 0, 1)">
 |      result will be get WITHOUT checking </span><span style="color: rgba(0, 0, 255, 1)">for</span> a particular platform and build.<span style="color: rgba(0, 0, 0, 1)">
 |
 |
 |      testplanid       test plan id
 |
 |      args variations: testcaseid - testcaseexternalid  </span>(mandatory!)<span style="color: rgba(0, 0, 0, 1)">
 |                       buildid - buildname
 |                       platformid - platformname
 |      test case information is general mandatory
 |
 |  getTestCaseCustomFieldDesignValue</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Gets value of a Custom Field with scope</span>='design' <span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> a given Test case
 |
 |      details </span>=<span style="color: rgba(0, 0, 0, 1)">  changes output information
 |          null or 'value' </span>=><span style="color: rgba(0, 0, 0, 1)"> just value
 |          'full' </span>=><span style="color: rgba(0, 0, 0, 1)"> a map with all custom field definition
 |                        plus value and internal test case id
 |          'simple' </span>=> value plus custom field name, <span style="color: rgba(0, 0, 255, 1)">label</span>, and <span style="color: rgba(0, 0, 255, 1)">type</span> (as code).<span style="color: rgba(0, 0, 0, 1)">
 |
 |      attention - be careful with testcaseexternalid - it must include an '-'</span>.<span style="color: rgba(0, 0, 0, 1)">
 |      otherwise TL </span>(<=1.9.8)<span style="color: rgba(0, 0, 0, 1)"> returns
 |      </span><ProtocolError <span style="color: rgba(0, 0, 255, 1)">for</span> xmlrpc.php: 500 Internal Server Error><span style="color: rgba(0, 0, 0, 1)">
 |
 |  getTestCaseCustomFieldExecutionValue</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Gets a Custom Field of a Test Case in Execution Scope</span>.<span style="color: rgba(0, 0, 0, 1)">
 |
 |  getTestCaseCustomFieldTestPlanDesignValue</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Gets a Custom Field of a Test Case in Test Plan Design Scope</span>.<span style="color: rgba(0, 0, 0, 1)">
 |
 |  getTestCaseKeywords</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Gets a dictionary of keywords </span><span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> a given Test case
 |
 |      args variations: testcaseid - testcaseexternalid  </span>(mandatoy!)<span style="color: rgba(0, 0, 0, 1)">
 |
 |      returns an empty dictionary</span>, <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> no keywords are defined
 |
 |  getTestCasesForTestPlan</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      List test cases linked to a test plan
 |
 |      details - default is 'full'</span>,<span style="color: rgba(0, 0, 0, 1)">
 |                'simple'</span>,<span style="color: rgba(0, 0, 0, 1)"> 'details' ??
 |
 |      args variations:     keywordid - keywords
 |
 |      returns an empty list</span>, <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> no build is assigned
 |
 |  getTestCasesForTestSuite</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      List test cases within a test suite alphabetically
 |
 |      details - default is 'simple'</span>,<span style="color: rgba(0, 0, 0, 1)">
 |                </span><span style="color: rgba(0, 0, 255, 1)">use</span> 'full' <span style="color: rgba(0, 0, 255, 1)">if</span> you want to get summary,<span style="color: rgba(0, 0, 0, 1)">steps & expected_results
 |                or 'only_id'</span>, <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> you just need an ID list
 |
 |      deep - True</span>/<span style="color: rgba(0, 0, 0, 1)">False - default is True
 |             </span><span style="color: rgba(0, 0, 255, 1)">if</span> True, <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> also test case of child suites
 |
 |      getkeywords - True</span>/<span style="color: rgba(0, 0, 0, 1)">False - default is False
 |             </span><span style="color: rgba(0, 0, 255, 1)">if</span> True AND details='full', dictionary includes <span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> each test
 |             case</span>, which as assigned keywords,<span style="color: rgba(0, 0, 0, 1)"> an additional key value pair
 |             'keywords'
 |
 |      returns an empty list</span>, <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> no build is assigned
 |
 |  getTestPlanByName</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Gets info about target test project
 |
 |  getTestPlanCustomFieldDesignValue</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Gets a Custom Field of a Test Plan in Design Scope</span>.<span style="color: rgba(0, 0, 0, 1)">
 |
 |  getTestPlanPlatforms</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Returns the list of platforms associated to a given test plan
 |
 |      returns an empty list</span>, <span style="color: rgba(0, 0, 255, 1)">if</span> no platform is assigned (api error 3041)<span style="color: rgba(0, 0, 0, 1)">
 |      - details see comments </span><span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> decoMakerApiCallReplaceTLResponseError
 |
 |  getTestProjectByName</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Gets info about target test project
 |
 |  getTestSuite</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Returns list with all test suites named TESTUITENAME defined </span><span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)">
 |      test project using PREFIX
 |
 |  getTestSuiteAttachments</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Gets attachments </span><span style="color: rgba(0, 0, 255, 1)">for</span> specified test suite.<span style="color: rgba(0, 0, 0, 1)">
 |      The attachment file content is Base64 encoded</span>.<span style="color: rgba(0, 0, 0, 1)"> To save the file to disk
 |      in client</span>, Base64 decode the content and write file in binary <span style="color: rgba(0, 0, 255, 1)">mode</span>.<span style="color: rgba(0, 0, 0, 1)">
 |
 |  getTestSuiteByID</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      </span><span style="color: rgba(0, 0, 255, 1)">Return</span><span style="color: rgba(0, 0, 0, 1)"> a TestSuite by ID
 |
 |  getTestSuiteCustomFieldDesignValue</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Gets a Custom Field of a Test Suite in Design Scope</span>.<span style="color: rgba(0, 0, 0, 1)">
 |
 |  getTestSuitesForTestPlan</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      List test suites within a test plan alphabetically
 |
 |      returns an empty list</span>, <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> no suite is assigned
 |
 |  getTestSuitesForTestSuite</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      get list of TestSuites which are DIRECT children of a given TestSuite
 |
 |      returns an empty list</span>, <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> no TestSuite is assigned
 |
 |  getTotalsForTestPlan</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Gets the summarized results grouped by platform</span>.<span style="color: rgba(0, 0, 0, 1)">
 |
 |  getUserByID</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      returns user data </span><span style="color: rgba(0, 0, 255, 1)">for</span> account with USERID in users table,<span style="color: rgba(0, 0, 0, 1)"> column ID
 |
 |      * </span><span style="color: rgba(0, 0, 255, 1)">if</span> everything ok returns an array <span style="color: rgba(0, 0, 255, 1)">on</span><span style="color: rgba(0, 0, 0, 1)"> just one element with following user data
 |      *
 |      * firstName</span>,lastName,emailAddress,locale,isActive,defaultTestprojectID,<span style="color: rgba(0, 0, 0, 1)">
 |      * globalRoleID
 |      * globalRole    array with role info
 |      * tprojectRoles array
 |      * tplanRoles    array
 |      * login
 |      * dbID
 |      * loginRegExp
 |      *
 |      * ATTENTION: userApiKey will be </span><span style="color: rgba(0, 0, 255, 1)">set</span> to NULL,<span style="color: rgba(0, 0, 0, 1)"> because is worst that access to user password
 |
 |  getUserByLogin</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      returns user data </span><span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> account with login name USER
 |
 |          </span><span style="color: rgba(0, 0, 255, 1)">if</span> everything ok returns an array <span style="color: rgba(0, 0, 255, 1)">on</span><span style="color: rgba(0, 0, 0, 1)"> just one element with following user data
 |      *
 |      * firstName</span>,lastName,emailAddress,locale,isActive,defaultTestprojectID,<span style="color: rgba(0, 0, 0, 1)">
 |      * globalRoleID
 |      * globalRole    array with role info
 |      * tprojectRoles array
 |      * tplanRoles    array
 |      * login
 |      * dbID
 |      * loginRegExp
 |      *
 |      * ATTENTION: userApiKey will be </span><span style="color: rgba(0, 0, 255, 1)">set</span> to NULL,<span style="color: rgba(0, 0, 0, 1)"> because is worst that access to user password
 |
 |  ping</span>(self)<span style="color: rgba(0, 0, 0, 1)">
 |      alias </span><span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> methodAPI sayHello
 |
 |  removePlatformFromTestPlan</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Removes a platform from a test plan
 |
 |  removeTestCaseKeywords</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      removes list of keywords from a </span><span style="color: rgba(0, 0, 255, 1)">set</span><span style="color: rgba(0, 0, 0, 1)"> of test cases
 |
 |      expects as arg </span><keywords><span style="color: rgba(0, 0, 0, 1)"> a dictionary with
 |        </span><testcaseexternalid> as a key and <list of keywords><span style="color: rgba(0, 0, 0, 1)"> as value
 |
 |      example:
 |        {'TC-</span>4711' : ['KeyWord02'], 'TC-4712' : ['KeyWord01',<span style="color: rgba(0, 0, 0, 1)"> KeyWord03']}
 |
 |        removes from test case 'TC-</span>4711<span style="color: rgba(0, 0, 0, 1)">' the keyword 'KeyWord02'
 |        removes from test case 'TC-</span>4712' the keywords 'KeyWord01' +<span style="color: rgba(0, 0, 0, 1)"> KeyWord03'
 |
 |  repeat</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Repeats a message back
 |
 |  reportTCResult</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Reports a result </span><span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> a single test case
 |
 |      args variations: testcaseid - testcaseexternalid
 |                       buildid - buildname
 |                       platformid - platformname
 |
 |      customfields : dictionary with customfields names </span>+<span style="color: rgba(0, 0, 0, 1)"> values
 |          VERY IMPORTANT: value must be formatted in the way it's written to db
 |      overwrite    : </span><span style="color: rgba(0, 0, 255, 1)">if</span> present and true, <span style="color: rgba(0, 0, 255, 1)">then</span> last execution <span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)">
 |                     </span>(testcase,testplan,build,platform) will be overwritten.<span style="color: rgba(0, 0, 0, 1)">
 |      user : </span><span style="color: rgba(0, 0, 255, 1)">if</span> present and user is a valid login (no other check will be done)<span style="color: rgba(0, 0, 0, 1)">
 |             it will be used </span><span style="color: rgba(0, 0, 255, 1)">when</span> writing execution.<span style="color: rgba(0, 0, 0, 1)">
 |      execduration : Exec </span>(min) as float (2.5 = 2min 30sec)<span style="color: rgba(0, 0, 0, 1)">
 |      timestamp    : 'YYYY-MM-DD hh</span><span style="color: rgba(128, 0, 0, 1)">:mm</span>[<span style="color: rgba(128, 0, 0, 1)">:ss</span>]'#<span style="color: rgba(0, 0, 0, 1)">
 |      steps        : [{'step_number' : </span>6, 'result' : 'p', 'notes"<span style="color: rgba(0, 0, 0, 1)"> : 'a_note'},
 |                      {'step_number' : 7, 'result' : 'f', 'notes</span>"<span style="color: rgba(0, 0, 0, 1)"> : 'blabla'}]
 |
 |  sayHello</span>(self)<span style="color: rgba(0, 0, 0, 1)">
 |      Lets you see </span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> the server is up and running
 |
 |  setTestCaseExecutionType</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Update execution </span><span style="color: rgba(0, 0, 255, 1)">type</span> <span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> a test case version
 |
 |      possible executiontype values
 |      </span>1 = TESTCASE_EXECUTION_TYPE_MANUAL, 2 =<span style="color: rgba(0, 0, 0, 1)"> TESTCASE_EXECUTION_TYPE_AUTO
 |
 |  setTestCaseTestSuite</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      </span><span style="color: rgba(0, 0, 255, 1)">move</span><span style="color: rgba(0, 0, 0, 1)"> a test case to a different Test Suite
 |
 |      mandatory arg:
 |          testcaseexternalid - identifies the test case
 |          testsuiteid        - identifies the test suite
 |
 |  testLinkVersion</span>(self)<span style="color: rgba(0, 0, 0, 1)">
 |      Returns the TestLink Version
 |      usable with TL</span>>= 1.9.9 , returns '<= 1.9.8' <span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> older versions
 |
 |  unassignTestCaseExecutionTask</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      assigns a user to a test case execution task
 |
 |      testplanid           test plan id
 |      testcaseexternalid   </span><span style="color: rgba(0, 0, 255, 1)">format</span><span style="color: rgba(0, 0, 0, 1)"> PREFIX-NUMBER
 |
 |      args variations:     buildid - buildname
 |                           platformid - platformname
 |                           user </span>(login name) - action ('unassignAll')<span style="color: rgba(0, 0, 0, 1)">
 |      build information is general mandatory
 |      platform information is required</span>, <span style="color: rgba(0, 0, 255, 1)">when</span><span style="color: rgba(0, 0, 0, 1)"> test plan has assigned platforms
 |      </span><span style="color: rgba(0, 0, 255, 1)">if</span> action=='unassignAll', user information is <span style="color: rgba(0, 0, 255, 1)">not</span><span style="color: rgba(0, 0, 0, 1)"> needed
 |      - otherwise</span>, TL itself will <span style="color: rgba(0, 0, 255, 1)">set</span><span style="color: rgba(0, 0, 0, 1)"> action to 'unassignOne' and expects a
 |        valid user information </span>(login name => tester)<span style="color: rgba(0, 0, 0, 1)">
 |
 |  updateBuildCustomFieldsValues</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Update value of Custom Field with scope</span>='design' <span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> a given Build
 |
 |      customfields  : dictionary with customfields names </span>+<span style="color: rgba(0, 0, 0, 1)"> values
 |      VERY IMPORTANT: value must be formatted in the way it's written to db
 |
 |  updateTestCase</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Update an existing test case
 |
 |      steps     array - each element is a hash with following </span><span style="color: rgba(0, 0, 255, 1)">keys</span><span style="color: rgba(0, 0, 0, 1)">
 |                step_number</span>,actions,expected_results,<span style="color: rgba(0, 0, 0, 1)">execution_type
 |      user      login name used as updater - optional
 |                </span><span style="color: rgba(0, 0, 255, 1)">if</span> <span style="color: rgba(0, 0, 255, 1)">not</span> provided will be <span style="color: rgba(0, 0, 255, 1)">set</span><span style="color: rgba(0, 0, 0, 1)"> to user that request update
 |
 |      </span><span style="color: rgba(0, 0, 255, 1)">Not</span><span style="color: rgba(0, 0, 0, 1)"> all test case attributes will be able to be updated using this method
 |
 |  updateTestCaseCustomFieldDesignValue</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Update value of Custom Field with scope</span>='design' <span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> a given Test case
 |
 |      customfields : dictionary with customfields names </span>+<span style="color: rgba(0, 0, 0, 1)"> values
 |           VERY IMPORTANT: value must be formatted in the way it's written to db
 |
 |  updateTestSuite</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      update a test suite
 |
 |      mandatory arg: testsuiteid - identifies the test suite to be change
 |
 |      mandatory args variations: testprojectid or prefix
 |      - test project information is general mandatory
 |
 |      optional args:
 |      - testsuitename - </span><span style="color: rgba(0, 0, 255, 1)">if</span> defined,<span style="color: rgba(0, 0, 0, 1)"> test suite name will be changed
 |      - details       - </span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> defined test suite details will be changed
 |      - order         - </span><span style="color: rgba(0, 0, 255, 1)">if</span> defined,<span style="color: rgba(0, 0, 0, 1)"> order inside parent container is changed
 |
 |  updateTestSuiteCustomFieldDesignValue</span>(self, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Update value of Custom Field with scope</span>='design' <span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> a given Test Suite
 |
 |      customfields  : dictionary with customfields names </span>+<span style="color: rgba(0, 0, 0, 1)"> values
 |      VERY IMPORTANT: value must be formatted in the way it's written to db
 |
 |  uploadAttachment</span>(self, attachmentfile, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Uploads an attachment </span><span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> an execution
 |
 |      fkid    - The Attachment Foreign Key ID
 |      fktable - The Attachment Foreign Key Table
 |
 |      mandatory non api args: attachmentfile
 |      - python file descriptor pointing to the file
 |      - or a valid file </span><span style="color: rgba(0, 0, 255, 1)">path</span><span style="color: rgba(0, 0, 0, 1)">
 |
 |      default values </span><span style="color: rgba(0, 0, 255, 1)">for</span> filename, filetype,<span style="color: rgba(0, 0, 0, 1)"> content are determine from
 |      ATTACHMENTFILE</span>, but user could overwrite it, <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> user want to store the
 |      attachment with a different name
 |
 |  uploadExecutionAttachment</span>(self, attachmentfile, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Uploads an attachment </span><span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> an execution
 |
 |      executionid - execution ID
 |
 |      mandatory non api args: attachmentfile
 |      - python file descriptor pointing to the file
 |      - or a valid file </span><span style="color: rgba(0, 0, 255, 1)">path</span><span style="color: rgba(0, 0, 0, 1)">
 |
 |      default values </span><span style="color: rgba(0, 0, 255, 1)">for</span> filename, filetype,<span style="color: rgba(0, 0, 0, 1)"> content are determine from
 |      ATTACHMENTFILE</span>, but user could overwrite it, <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> user want to store the
 |      attachment with a different name
 |
 |  uploadRequirementAttachment</span>(self, attachmentfile, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Uploads an attachment </span><span style="color: rgba(0, 0, 255, 1)">for</span> a Requirement.<span style="color: rgba(0, 0, 0, 1)">
 |
 |      requirementid - The Requirement ID
 |
 |      mandatory non api args: attachmentfile
 |      - python file descriptor pointing to the file
 |      - or a valid file </span><span style="color: rgba(0, 0, 255, 1)">path</span><span style="color: rgba(0, 0, 0, 1)">
 |
 |      default values </span><span style="color: rgba(0, 0, 255, 1)">for</span> filename, filetype,<span style="color: rgba(0, 0, 0, 1)"> content are determine from
 |      ATTACHMENTFILE</span>, but user could overwrite it, <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> user want to store the
 |      attachment with a different name
 |
 |  uploadRequirementSpecificationAttachment</span>(self, attachmentfile, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Uploads an attachment </span><span style="color: rgba(0, 0, 255, 1)">for</span> a Requirement Specification.<span style="color: rgba(0, 0, 0, 1)">
 |
 |      reqspecid - The Requirement Specification ID
 |
 |      mandatory non api args: attachmentfile
 |      - python file descriptor pointing to the file
 |      - or a valid file </span><span style="color: rgba(0, 0, 255, 1)">path</span><span style="color: rgba(0, 0, 0, 1)">
 |
 |      default values </span><span style="color: rgba(0, 0, 255, 1)">for</span> filename, filetype,<span style="color: rgba(0, 0, 0, 1)"> content are determine from
 |      ATTACHMENTFILE</span>, but user could overwrite it, <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> user want to store the
 |      attachment with a different name
 |
 |  uploadTestCaseAttachment</span>(self, attachmentfile, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Uploads an attachment </span><span style="color: rgba(0, 0, 255, 1)">for</span> a Test Case.<span style="color: rgba(0, 0, 0, 1)">
 |
 |      testcaseid - Test Case INTERNAL ID
 |      version    - Test Case version number
 |
 |      mandatory non api args: attachmentfile
 |      - python file descriptor pointing to the file
 |      - or a valid file </span><span style="color: rgba(0, 0, 255, 1)">path</span><span style="color: rgba(0, 0, 0, 1)">
 |
 |      default values </span><span style="color: rgba(0, 0, 255, 1)">for</span> filename, filetype,<span style="color: rgba(0, 0, 0, 1)"> content are determine from
 |      ATTACHMENTFILE</span>, but user could overwrite it, <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> user want to store the
 |      attachment with a different name
 |
 |  uploadTestProjectAttachment</span>(self, attachmentfile, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Uploads an attachment </span><span style="color: rgba(0, 0, 255, 1)">for</span> a Test Project.<span style="color: rgba(0, 0, 0, 1)">
 |
 |      testprojectid - The Test Project ID
 |
 |      mandatory non api args: attachmentfile
 |      - python file descriptor pointing to the file
 |      - or a valid file </span><span style="color: rgba(0, 0, 255, 1)">path</span><span style="color: rgba(0, 0, 0, 1)">
 |
 |      default values </span><span style="color: rgba(0, 0, 255, 1)">for</span> filename, filetype,<span style="color: rgba(0, 0, 0, 1)"> content are determine from
 |      ATTACHMENTFILE</span>, but user could overwrite it, <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> user want to store the
 |      attachment with a different name
 |
 |  uploadTestSuiteAttachment</span>(self, attachmentfile, *argsPositional, **argsOptional)<span style="color: rgba(0, 0, 0, 1)">
 |      Uploads an attachment </span><span style="color: rgba(0, 0, 255, 1)">for</span> a Test Suite.<span style="color: rgba(0, 0, 0, 1)">
 |
 |      testsuiteid - The Test Suite ID
 |
 |      mandatory non api args: attachmentfile
 |      - python file descriptor pointing to the file
 |      - or a valid file </span><span style="color: rgba(0, 0, 255, 1)">path</span><span style="color: rgba(0, 0, 0, 1)">
 |
 |      default values </span><span style="color: rgba(0, 0, 255, 1)">for</span> filename, filetype,<span style="color: rgba(0, 0, 0, 1)"> content are determine from
 |      ATTACHMENTFILE</span>, but user could overwrite it, <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> user want to store the
 |      attachment with a different name
 |
 |  whatArgs</span>(self, methodNameAPI)<span style="color: rgba(0, 0, 0, 1)">
 |      returns </span><span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> METHODNAME a description with
 |      - positional</span>, optional and other (non api)<span style="color: rgba(0, 0, 0, 1)"> mandatory args
 |      - methods doc</span>/<span style="color: rgba(0, 0, 0, 1)">help string
 |
 |  ----------------------------------------------------------------------
 |  Data descriptors inherited from testlink</span>.testlinkapigeneric.<span style="color: rgba(0, 0, 0, 1)">TestlinkAPIGeneric:
 |
 |  devKey
 |
 |  server
 |
 |  ----------------------------------------------------------------------
 |  Data and other attributes inherited from testlink</span>.testlinkapigeneric.<span style="color: rgba(0, 0, 0, 1)">TestlinkAPIGeneric:
 |
 |  __version__ </span>= '0.8.1'</pre>
						  
					  </div>
						<!--conend-->
							<div class="p-2"></div>

						<div class="arcinfo my-3 fs-7 text-center">
							
							
			<a href='/t/etagid9065-0.html' class='tagbtn' target='_blank'>testlink</a><a href='/t/etagid8-0.html' class='tagbtn' target='_blank'>Python</a>							
						



						</div>
						
						<div class="p-2"></div>

						

						
					</div>
					<div class="p-2"></div>
					<!--xg-->
					<div class="lbox p-4 shadow-sm rounded-3">
						<div class="boxtitle"><h2 class="fs-4">相关</h2></div>
						
<hr>				
						
			<div class="row g-0 py-2 border-bottom align-items-center">
																
								<div class="col-7 col-lg-11 border-lg-end">
										<h3 class="fs-6 mb-0 mb-lg-2"><a href="/a/1-566513.html">学习《Python编程从入门到实践》PDF+代码训练</a></h3>
									
									<div class="ltag fs-8 d-none d-lg-block">
								 

        </div>
								</div>
							
							</div><div class="row g-0 py-2 border-bottom align-items-center">
																
								<div class="col-7 col-lg-11 border-lg-end">
										<h3 class="fs-6 mb-0 mb-lg-2"><a href="/a/1-566439.html">python-----面向对象简单理解</a></h3>
									
									<div class="ltag fs-8 d-none d-lg-block">
								 

        </div>
								</div>
							
							</div><div class="row g-0 py-2 border-bottom align-items-center">
																
								<div class="col-7 col-lg-11 border-lg-end">
										<h3 class="fs-6 mb-0 mb-lg-2"><a href="/a/1-565236.html">python多线程控制</a></h3>
									
									<div class="ltag fs-8 d-none d-lg-block">
								 

        </div>
								</div>
							
							</div><div class="row g-0 py-2 border-bottom align-items-center">
																
								<div class="col-7 col-lg-11 border-lg-end">
										<h3 class="fs-6 mb-0 mb-lg-2"><a href="/a/1-564738.html">Sublime 的安装、汉化、配置、Python环境和插件</a></h3>
									
									<div class="ltag fs-8 d-none d-lg-block">
								 

        </div>
								</div>
							
							</div><div class="row g-0 py-2 border-bottom align-items-center">
																
								<div class="col-7 col-lg-11 border-lg-end">
										<h3 class="fs-6 mb-0 mb-lg-2"><a href="/a/1-564855.html">python——time strftime() 函数表示当地时间</a></h3>
									
									<div class="ltag fs-8 d-none d-lg-block">
								 

        </div>
								</div>
							
							</div><div class="row g-0 py-2 border-bottom align-items-center">
																
								<div class="col-7 col-lg-11 border-lg-end">
										<h3 class="fs-6 mb-0 mb-lg-2"><a href="/a/1-564276.html">python 初识函数</a></h3>
									
									<div class="ltag fs-8 d-none d-lg-block">
								 

        </div>
								</div>
							
							</div><div class="row g-0 py-2 border-bottom align-items-center">
																
								<div class="col-7 col-lg-11 border-lg-end">
										<h3 class="fs-6 mb-0 mb-lg-2"><a href="/a/1-564187.html">python 函数对象 嵌套 闭包</a></h3>
									
									<div class="ltag fs-8 d-none d-lg-block">
								 

        </div>
								</div>
							
							</div><div class="row g-0 py-2 border-bottom align-items-center">
																
								<div class="col-7 col-lg-11 border-lg-end">
										<h3 class="fs-6 mb-0 mb-lg-2"><a href="/a/1-563864.html">Python栈溢出——设置python栈大小</a></h3>
									
									<div class="ltag fs-8 d-none d-lg-block">
								 

        </div>
								</div>
							
							</div><div class="row g-0 py-2 border-bottom align-items-center">
																
								<div class="col-7 col-lg-11 border-lg-end">
										<h3 class="fs-6 mb-0 mb-lg-2"><a href="/a/1-563952.html">python-面向对象-01课堂笔记</a></h3>
									
									<div class="ltag fs-8 d-none d-lg-block">
								 

        </div>
								</div>
							
							</div><div class="row g-0 py-2 border-bottom align-items-center">
																
								<div class="col-7 col-lg-11 border-lg-end">
										<h3 class="fs-6 mb-0 mb-lg-2"><a href="/a/1-563329.html">python爬虫</a></h3>
									
									<div class="ltag fs-8 d-none d-lg-block">
								 

        </div>
								</div>
							
							</div><div class="row g-0 py-2 border-bottom align-items-center">
																
								<div class="col-7 col-lg-11 border-lg-end">
										<h3 class="fs-6 mb-0 mb-lg-2"><a href="/a/1-563001.html">Python 之父的解析器系列之五:左递归 PEG 语法</a></h3>
									
									<div class="ltag fs-8 d-none d-lg-block">
								 

        </div>
								</div>
							
							</div><div class="row g-0 py-2 border-bottom align-items-center">
																
								<div class="col-7 col-lg-11 border-lg-end">
										<h3 class="fs-6 mb-0 mb-lg-2"><a href="/a/1-563230.html">Python 为了提升性能,竟运用了共享经济</a></h3>
									
									<div class="ltag fs-8 d-none d-lg-block">
								 

        </div>
								</div>
							
							</div>            
            
            <!---->
                                    
           <!---->
  			
						

					</div>
					<!--xgend-->
				</div>

				<div class="col-lg-3 col-12 p-0 ps-lg-2">
					<!--box-->									
					<!--boxend-->
					<!--<div class="p-2"></div>-->

					<!--box-->
									<div class="lbox p-4 shadow-sm rounded-3">
					
									   <div class="boxtitle pb-2"><h2 class="fs-4"><a href="#">标签</a></h2></div>
										<div class="clearfix"></div>
										<ul class="m-0 p-0 fs-7 r-tag">
										</ul>
									

										
										<div class="clearfix"></div>
									</div>
					<!--box end-->

					
				</div>

			</div>
		
		
		
		</div>	

</main>
						<div class="p-2"></div>
<footer>
<div class="container-fluid p-0 bg-black">
	<div class="container p-0  fs-8">
	<p class="text-center m-0 py-2 text-white-50">一品网 <a class="text-white-50" href="https://beian.miit.gov.cn/" target="_blank">冀ICP备14022925号-6</a></p>
	</div>	
</div>
<script>
var _hmt = _hmt || [];
(function() {
  var hm = document.createElement("script");
  hm.src = "https://hm.baidu.com/hm.js?6e3dd49b5f14d985cc4c6bdb9248f52b";
  var s = document.getElementsByTagName("script")[0]; 
  s.parentNode.insertBefore(hm, s);
})();
</script>
</footer>
		
<script src="/skin/bootstrap.bundle.js"></script>

</body>
</html>