lczub / TestLink-API-Python-client

A Python client to use the TestLink API
105 stars 63 forks source link

How to import test cases with external names longer than 100 chars #136

Closed abhay2703 closed 4 years ago

abhay2703 commented 4 years ago

By default test case title limit is 100 characters, and we can increase it by editing _inputdimensions.conf. But that works only when adding test cases manually.

That does not work while creating test cases using the API.

Traceback (most recent call last):
  File "E:/Abhay/Work/Python/TestlinkConnect/TestlinkTest.py", line 134, in <module>
    tc_import.addTCs()
  File "E:/Abhay/Work/Python/TestlinkConnect/TestlinkTest.py", line 63, in addTCs
    newTestCase = self.myTestLink.createTestCase(TCData['TCSummary'][1], TSId, self.TPid, self.TLUser, TCData['TCSummary'][1], steps=StepsList, preconditions=TCData['TCPreCondition'][1])
  File "C:\Python38\lib\site-packages\testlink\testlinkapi.py", line 155, in createTestCase
    return super(TestlinkAPIClient, self).createTestCase(*argsPositional, 
  File "C:\Python38\lib\site-packages\testlink\testlinkdecorators.py", line 112, in wrapperAddDevKey
    return methodAPI(self, *argsPositional, **argsOptional)
  File "C:\Python38\lib\site-packages\testlink\testlinkdecorators.py", line 99, in wrapperWithArgs
    return self.callServerWithPosArgs(methodAPI.__name__, 
  File "C:\Python38\lib\site-packages\testlink\testlinkapigeneric.py", line 1582, in callServerWithPosArgs
    response = self._callServer(methodNameAPI, argsOptional)
  File "C:\Python38\lib\site-packages\testlink\testlinkapigeneric.py", line 2057, in _callServer
    response = getattr(self.server.tl, methodNameAPI)(argsAPI)
  File "C:\Python38\lib\xmlrpc\client.py", line 1109, in __call__
    return self.__send(self.__name, args)
  File "C:\Python38\lib\xmlrpc\client.py", line 1450, in __request
    response = self.__transport.request(
  File "C:\Python38\lib\xmlrpc\client.py", line 1153, in request
    return self.single_request(host, handler, request_body, verbose)
  File "C:\Python38\lib\xmlrpc\client.py", line 1169, in single_request
    return self.parse_response(resp)
  File "C:\Python38\lib\xmlrpc\client.py", line 1335, in parse_response
    p.feed(data)
  File "C:\Python38\lib\xmlrpc\client.py", line 438, in feed
    self._parser.Parse(data, 0)
xml.parsers.expat.ExpatError: junk after document element: line 1, column 91

Process finished with exit code 1
lczub commented 4 years ago

Hello abhay2703 ,

thanks for this interesting issue. Your traceback xml.parsers.expat.ExpatError: junk after document element: line 1, column 91 is a classic symptom, that the Testlink Server itself was running in an internal error.

I guess, you extended in _testlink-code\gui\templates\conf\ inputdimensions.conf the setting for TESTCASE_NAME_MAXLEN, correct?

...
TESTPROJECT_TRUNCATE_SIZE=150
TESTCASE_NAME_SIZE=50
TESTCASE_NAME_MAXLEN=100
TESTPLAN_TRUNCATE_SIZE=45
...

The TestLink Server does not allow, that clients can influence such settings via the api. The issue reason must exist somewhere inside the TestLink Server code itself.

Please check, if your TestLink Server Logs reports some more detailed error messages or try to run the api request with activated debugging mode as described in How to check original exchanged XML data.

Regards Luiko

abhay2703 commented 4 years ago

Dear Luiko,

Your analysis is correct regarding the changes I made to the settings in _inputdimensions.conf Also as per your suggestion I looked in testlink server logs and found the error:

........
[<<][5edc9ddf0ec5b791175367][DEFAULT][/testlink/lib/api/xmlrpc/v1/xmlrpc.php][20/Jun/7 07:57:19][20/Jun/7 07:57:19][took 0.001199 secs]
[>>][5edc9ddf1122a916266638][DEFAULT][/testlink/lib/api/xmlrpc/v1/xmlrpc.php][20/Jun/7 07:57:19]
[<<][5edc9ddf1122a916266638][DEFAULT][/testlink/lib/api/xmlrpc/v1/xmlrpc.php][20/Jun/7 07:57:19][20/Jun/7 07:57:19][took 0.010994 secs]
[>>][5edc9ddf15f55380179937][DEFAULT][/testlink/lib/api/xmlrpc/v1/xmlrpc.php][20/Jun/7 07:57:19]
    [20/Jun/7 07:57:19][ERROR][<nosession>][DATABASE]
        ERROR ON exec_query() - database.class.php <br />1406 - Data too long for column 'name' at row 1 - INSERT INTO nodes_hierarchy (name,node_type_id,node_order,parent_id)  VALUES('Verify the behavior when user provides just the tool name without providing any commands, sub-commands, parameters or options.', 3,0,8929)<br />THE MESSAGE : INSERT INTO nodes_hierarchy (name,node_type_id,node_order,parent_id)  VALUES('Verify the behavior when user provides just the tool name without providing any commands, sub-commands, parameters or options.', 3,0,8929)
Query failed: errorcode[1406]
    errormsg:Data too long for column 'name' at row 1 
[<<][5edc9ddf15f55380179937][DEFAULT][/testlink/lib/api/xmlrpc/v1/xmlrpc.php][20/Jun/7 07:57:19][20/Jun/7 07:57:19][took 0.03322 secs]

Now is there a way that I can fix this length error? Thanks for the help.

Regards, Abhay

lczub commented 4 years ago

Hello Abhay, I run today some test against a new TL Server installation, build with the latest _testlink_1_9_20_fixed branch.

I have NOT adjusted the configuration file input_dimensions.conf and created two test cases using the api createTable a) 105 chars long name TESTCASE_LONGNAME 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 b) 107 chars long name TESTCASE_LONGNAME 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 b

Both test cases are inserted without an error. TL presents both test cases with the same shortened name TESTCASE_LONGNAME 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 01234 - this is the value of the related DB table field nodes_hierarchy.name, which only can store a 100 long var char.

If you really want to store test case names longer as 100 chars, for my understanding, you have to customize your DB and not only the php code.

The SQL error you report says, that you try to store more than 100 chars in nodes_hierarchy.name. I guess, your change of TESTCASE_NAME_MAXLEN in input_dimensions.conf has the effect, that the function to shorten long test case names before storing them creates too long names for the database. It sounds not for a good idea that you have extend this constant. It should match nodes_hierarchy.name max number of chars.

Regards Luiko

abhay2703 commented 4 years ago

Hi Luiko,

I tried the same thing before changing the _inputdimensions.conf (2 tests with short and long test name) on TL 1.9.19 and the behavior was same i.e. both tests were added added successfully without any error. And the test name for long string was truncated.

Now the problem for me is, I have 1000+ testcases that I want to import to TL, and it is very difficult for me to change length for all test cases. So easier way for me was to change the configuration of TL. But now that also seems problematic.

Can you please suggest a solution to the issue? And if 1 of the solution is to customize the DB, then how can I do that?

Thanks in advance.

PS: I am using 1.9.19 because updateTestCaseCustomFieldDesignValue API was not working in latest 1.9.20. (So I downgraded my TL version)

Regards, Abhay

lczub commented 4 years ago

Hello Abhay,

my suggestion is, that you revert your changes on and import your all your test cases without customizing the db schema. This will shorten your external test case names, but they should be all get different internal IDs. To not lose the long name, store them as part of the test case description.

Code will look something like this

myTestLinkGen = TestlinkAPIGeneric(TEST_URL_1920_DOCKER, TEST_DEVKEY_DOCKER, verbose=False)
description_format = "<h3>old TC name</h3> <p>{old_tc_name}</p> <h3>old description</h3> <p>{old_descr}</p>"
...
# Creates test case TC_LONG_B with to long name, will be shorten by server
# description will include the old long name
steps_tc_long_b = [
        {'step_number' : 1, 'actions' : "Step action 1 - long_B" , 
         'expected_results' : "Step result 1 - long_B", 'execution_type' : MANUAL},
        {'step_number' : 2, 'actions' : "Step action 2 - long_B" , 
         'expected_results' : "Step result 2 - long_B", 'execution_type' : MANUAL}
               ] 

tc_import_data_long_b = {'old_tc_name' : 'TESTCASE_LONGNAME 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 b',
                  'old_descr' : 'old TC description to import'}

newTestCase = myTestLinkGen.createTestCase(tc_import_data_long_b['old_tc_name'], 
          newTestSuiteID_A, newProjectID, myTestUserName, 
          description_format.format(**tc_import_data_long_b), 
          steps_tc_long_b, preconditions='these are the preconditions',
          importance=LOW, state=READFORREVIEW, estimatedexecduration=10.1)                 
print("createTestCase", newTestCase)
abhay2703 commented 4 years ago

This will be acceptable, i guess.

Thanks Luiko.