Когда-то давно сваяла я питоний файлик для конвертации удобной csv'ки в xml'ку, понятную TestLink'у (ибо набирать тесткейсы в ТестЛинке - это долгий и очень мучительный процесс). Найденное на просторах тырнета индусское решение в виде Экселевского макроса у меня так и не заработало, а человек я ленивый, ВижуалВацека не знающий... В общем, что сваялось, то сваялось, не судите строго.
Да, чтобы всё заработало, надо, чтобы у вас хоть где-нибудь стоял Питон.
Инструкции и файлик см. ниже.
How to convert a csv file to a TestLink xml file.
Пример "входного" файла можно найти вот тут.
Да, чтобы всё заработало, надо, чтобы у вас хоть где-нибудь стоял Питон.
Инструкции и файлик см. ниже.
How to convert a csv file to a TestLink xml file.
A csv file with ";" delimiter should be created based on the
following rules:
1.1. The file should contain the following sequence of fields (The first row containing the column headers is ignored):
Column No Column Name Description
0 TC-extID TestCase External ID
1 Name TestCase Name
2 Summary TestCase summary
3 Preconditions TestCase preconditions
4 Ex. TypeTC TestCase execution type.
1 - Manual, 2 - Automated
5 Importance TestCase Importance
1 - High, 2 - Medium, 3 - Low
6 Keywords TestCase Keywords
7 Notes TestCase Notes
8 Requirements spec title (req_spec_title) Requirements Specificateion folder title
9 Requirements doc ID (req_id) Requirements document ID
10 Requirements doc Title (req_title) Requirements document Title
11 StepNo Individual Step Number
12 Step Description of the step (action taken)
13 Exp. Result Step expected result
14 Ex_TypeStep Step execution type.
1 - Manual, 2 - Automated
1.2. In order to display the special symbols (such as quotes, greater than and less than symbols etc.), they should be entered in html notation.
1.3. The content of the columns 0-7 should be repeated in every row for a single testcase.
1.4. You may separate the testcases with empty rows for better visibility and readablility of the csv file.
1.5. The Name field should not be empty for any testcase step, as it is used as the unique key for defining testcases both in TestLink and in the parser.
1.6. The parser creates testcases for a single 'node' in the test suites tree. So, you should run import for Test Cases, not for Test Suites.
2. Copy the csv2xml.py file to the directory on your local machine where you can execute files.
3. Run the following command (python v. 2.7.x should be installed in the system):
python csv2xml.py param1 param2
(e.g. csv2xml.py source.csv result.xml)
3.1. Param1 should contain full path to the .csv file with testcases, created on the Step 1.
3.2. Param2 should contain fill path and the name of the .xml file which will be imported into TestLink.
4. You should see a message like:
-------------
Done.
An xml file result.xml created
The source file is source.csv
-------------
As a result an xml file is created.
5. Login to TestLink.
6. Go to the node in the test suites tree for which you created the testcases.
7. Click the [Import Test Cases] button in the Test Case Operations section.
8. Specify the path to the .xml file with testcases in the 'File' field
9. Select the 'Consider Test Case as duplicate if' value as 'has same name' (usually the default one).
10. Select the 'Action for duplicates' value as 'Create a new version' or 'Create a new testcase with different title' depending on the desired result.
11. Click the [Upload file] button.
You should see a message like that:
Import TestCase data : <TestCase name> : Already exists, a NEW version has been created.
1.1. The file should contain the following sequence of fields (The first row containing the column headers is ignored):
Column No Column Name Description
0 TC-extID TestCase External ID
1 Name TestCase Name
2 Summary TestCase summary
3 Preconditions TestCase preconditions
4 Ex. TypeTC TestCase execution type.
1 - Manual, 2 - Automated
5 Importance TestCase Importance
1 - High, 2 - Medium, 3 - Low
6 Keywords TestCase Keywords
7 Notes TestCase Notes
8 Requirements spec title (req_spec_title) Requirements Specificateion folder title
9 Requirements doc ID (req_id) Requirements document ID
10 Requirements doc Title (req_title) Requirements document Title
11 StepNo Individual Step Number
12 Step Description of the step (action taken)
13 Exp. Result Step expected result
14 Ex_TypeStep Step execution type.
1 - Manual, 2 - Automated
1.2. In order to display the special symbols (such as quotes, greater than and less than symbols etc.), they should be entered in html notation.
1.3. The content of the columns 0-7 should be repeated in every row for a single testcase.
1.4. You may separate the testcases with empty rows for better visibility and readablility of the csv file.
1.5. The Name field should not be empty for any testcase step, as it is used as the unique key for defining testcases both in TestLink and in the parser.
1.6. The parser creates testcases for a single 'node' in the test suites tree. So, you should run import for Test Cases, not for Test Suites.
2. Copy the csv2xml.py file to the directory on your local machine where you can execute files.
3. Run the following command (python v. 2.7.x should be installed in the system):
python csv2xml.py param1 param2
(e.g. csv2xml.py source.csv result.xml)
3.1. Param1 should contain full path to the .csv file with testcases, created on the Step 1.
3.2. Param2 should contain fill path and the name of the .xml file which will be imported into TestLink.
4. You should see a message like:
-------------
Done.
An xml file result.xml created
The source file is source.csv
-------------
As a result an xml file is created.
5. Login to TestLink.
6. Go to the node in the test suites tree for which you created the testcases.
7. Click the [Import Test Cases] button in the Test Case Operations section.
8. Specify the path to the .xml file with testcases in the 'File' field
9. Select the 'Consider Test Case as duplicate if' value as 'has same name' (usually the default one).
10. Select the 'Action for duplicates' value as 'Create a new version' or 'Create a new testcase with different title' depending on the desired result.
11. Click the [Upload file] button.
You should see a message like that:
Import TestCase data : <TestCase name> : Already exists, a NEW version has been created.
#!/usr/bin/env python import csv, sys import array,unittest class CreateXML(): def MainFunction(self): #csv file structure: #Col[0] - TC-extID #Col[1] - Name #Col[2] - Summary #Col[3] - Preconditions #Col[4] - Ex. TypeTC #Col[5] - Importance #Col[6] - Keywords #Col[7] - Notes #Col[8] - Requirements spec title (req_spec_title) #Col[9] - Requirements doc ID (req_id) #Col[10] - Requirements doc Title (req_title) #Col[11] - StepNo #Col[12] - Step (Action) #Col[13] - Exp. Result #Col[14] - Ex_TypeStep def writeTCHeader(headlist): test = headlist[1] f = open(outputfile, 'a') f.write('<testcase internalid="" name="') #writing TC name tag f.write(headlist[1]) f.write('">') f.write('\n') f.write('<node_order><![CDATA[1]]></node_order>') #Writng <node_order> tag f.write('\n') f.write('<externalid><![CDATA[') #Writng <externalid> tag f.write(headlist[0]) f.write(']]></externalid>') f.write('\n') f.write('<version><![CDATA[1]]></version>') #Writng <version> tag f.write('\n') f.write('<summary><![CDATA[<p>') #Writng <summary> tag f.write(headlist[2]) f.write('</p>]]></summary>') f.write('\n') f.write('<preconditions><![CDATA[<p>') #Writng <preconditions> tag f.write(headlist[3]) f.write('</p>]]></preconditions>') f.write('\n') f.write('<execution_type><![CDATA[') #Writng <execution_type> tag f.write(headlist[4]) f.write(']]></execution_type>') f.write('\n') f.write('<importance><![CDATA[') #Writng <importance> tag f.write(headlist[5]) f.write(']]></importance>') f.write('\n') f.write('\n') f.write('<steps>') f.close() def writeTCBody(headlist): f = open(outputfile, 'a') f.write('\n') f.write('<step>') f.write('\n') f.write('<step_number><![CDATA[') #Writing step_number f.write(headlist[11]) f.write(']]></step_number>') f.write('\n') f.write('<actions><![CDATA[<p>') #Writing actions f.write(headlist[12]) f.write('</p>]]></actions>') f.write('\n') f.write('<expectedresults><![CDATA[<p>') #Writing expected results f.write(headlist[13]) f.write('</p>]]></expectedresults>') f.write('\n') f.write('<execution_type><![CDATA[') f.write(headlist[14]) f.write(']]></execution_type>') f.write('\n') f.write('</step>') f.write('\n') f.close() def writeTCFooter(headlist): f = open(outputfile, 'a') f.write('</steps>') f.write('\n') f.write('\n') f.write('<keywords>') #Writing keywords and notes f.write('\n') f.write('<keyword name="') f.write(headlist[6]) f.write('">') f.write('\n') f.write('<notes><![CDATA[<p>') f.write(headlist[7]) f.write('</p>]]></notes>') f.write('\n') f.write('</keyword>') f.write('\n') f.write('</keywords>') f.write('\n') f.write('<requirements>') #Writing requirements spec f.write('\n') f.write('<requirement>') f.write('\n') f.write('<req_spec_title><![CDATA[') f.write(headlist[8]) f.write(']]></req_spec_title>') f.write('\n') f.write('<doc_id><![CDATA[') f.write(headlist[9]) f.write(']]></doc_id>') f.write('\n') f.write('<title><![CDATA[') f.write(headlist[10]) f.write(']]></title>') f.write('\n') f.write('</requirement>') f.write('\n') f.write('</requirements>') f.write('\n') f.write('</testcase>') f.write('\n') f.write('\n') f.close() csvfile = sys.argv[1] outputfile = sys.argv[2] L = [] headlist = [] prevtc = [] f = open(outputfile, 'w') f.write('<?xml version="1.0" encoding="UTF-8"?>') f.write('\n') f.write('<testcases>') f.write('\n') f.close() reader = csv.reader(open(csvfile, "rb"), delimiter=';', ) for row in reader: if ("Name" != row[1]) and ('' != row[1]): headlist = row L.append(headlist) #Putting the parsed string to the list CurrList = L[0] CurrName = CurrList[1] prevtc = L[0] writeTCHeader(CurrList) for headlist in L: if headlist[1] == CurrName: writeTCBody(headlist) else: writeTCFooter(prevtc) # writing the footer CurrName = headlist[1] prevtc = headlist writeTCHeader(headlist) # starting new test case writeTCBody(headlist) # writing its first step writeTCFooter(headlist) #Writing the last footer f = open(outputfile, 'a') f.write('</testcases>') f.close() print 'Done' print 'An xml file ', outputfile, ' created' print 'The source file is ',csvfile if __name__ == "__main__": a = CreateXML() a.MainFunction()
Пример "входного" файла можно найти вот тут.
Тесты написанные на русском языке сохраняются в файле xml в неверной кодировке. Приходится пересохранять через блокнот в utf-8.
ReplyDeleteРешил проблемы с кодировкой с помощью бесплатной утилиты.
ReplyDeletehttps://code.google.com/p/win-iconv/
Автоматизировал процесс батником:
cd C:\Python27\Python csv2xml.py C:\Python27\Python\Testlink1.csv C:\Python27\Python\Testlink1.xml
win_iconv.exe -t UTF-8 -f WINDOWS-1251 Testlink1.xml > Testlink1_utf.xml
del Testlink1.xml
Огромное спасибо. )
ReplyDeleteНа основе Вашего кода, сделал прожку для создания XML-ки требований, а то у меня в TestLink 1.9.6 никак не получалось из CSV их загнать: все время выдавало Import done, but with syntax errors.
Забрать файл можно тут (req2xml.py)
Пример сsv для требований:
ReplyDeleteRQ-ID;Name;Description
ENV-531;Combobox for Exchange;Main panel contains combobox with options to choose desired exchange
ENV-231;Field for Exchange;Main panel contains field with options to choose desired exchange
Андрей а вы не смогли победить неправильную кодировку в xml если использовать русские буквы при написании тестов?
DeleteНу чтобы скрипт принудительно в utf-8 сохранял?
Было бы здорово если бы скрипт умел это сам, без дополнительной утилиты win-iconv
Есть решение-макрос на основе екзел. После моих переделок она стало с поддержкой UTF-8 и русского языка. В тестлинк затягивает на ура.
DeleteВ одну таблицу вводятся сразу и требования, и тесты. Макрос создает сразу два файла - один для требований, второй для тестов и автоматом устанавливает зависимости.
На практике намного быстрее и удобнее, чем сначала создавать СSV, потом на основе него - XML.
Единственный недостаток: можно прописывать только один шаг для тестов :) т.е. приходится в одну ячейку забивать все шаги. Если это не критично, могу скинуть куда скажете.
Хотя вдруг кому сразу понадобится :) Выкладываю: https://docs.google.com/file/d/0B4nt80DosU8YaUpWcWZjaWQxOW8/edit?usp=sharing
DeleteЕсть еще также макрос, который умеет различать шаги, создавать отдельно только требования или тесты и еще какие-то там усовершенствования, но также без поддержки русского языка. Если есть охота порыться в кодах VBA, могу скинуть, а то у меня и так все тест-доки на английском.
DeleteThis comment has been removed by the author.
ReplyDeleteКстати, насчёт русского языка. При сохранении самой csv'ки можно при сохранении выставлять UTF-8, тогда конфликтов возникать не должно.
ReplyDeleteМожно, в принципе, допилить и питоновский скрипт с encode/decode.
Андрей, спасибо за ссылку, никак у меня макросы победить не получалось :) Может, в этот раз выйдет что.
На здоровье ) Еще раз говорю, если надо, чтоб различало шаги - пишите в личку, будем сообща допиливать другой скрипт )
ReplyDeleteПоявилась версия, которая различает шаги и поддерживает UTF-8. https://docs.google.com/file/d/0B4nt80DosU8YMXFXM1ZPcDI0a1k/edit?usp=sharing
ReplyDeleteАвтор: Alpay Ersoy
Ссылка на блог: http://testlink-import.blogspot.com/2009/11/test-link-import.html
This comment has been removed by the author.
ReplyDelete