def setUpClass(cls): tc1 = TestCase.create(DEFAULT_PROJ, "regression", "regression", caseimportance="high", caselevel="component", caseautomation="notautomated", caseposneg="positive", testtype="functional", subtype1="-") cls.NEW_TEST_CASE = tc1.work_item_id tc2 = TestCase.create(DEFAULT_PROJ, "regression", "regression", caseimportance="high", caselevel="component", caseautomation="notautomated", caseposneg="positive", testtype="functional", subtype1="-") cls.NEW_TEST_CASE2 = tc2.work_item_id Plan.create(plan_id=PLAN_ID, plan_name="regression", project_id=DEFAULT_PROJ, parent_id=None, template_id="release") cls.NEW_PLAN = PLAN_ID
def test_009_dynamic_records(self): """This test does the following: * creates a TestCase * creates a TestRun based on the Example template (Dynamic query) * verifies that it is a dynamic query * updates an test record. * reloads * verifies that the record has been added """ TestCase.create(DEFAULT_PROJ, TIME_STAMP, "regression", caseimportance="high", caselevel="component", caseautomation="notautomated", caseposneg="positive", testtype="functional", subtype1="-") tr = TestRun.create("proj1", "querytest-%s" % TIME_STAMP, "Example", "querytest-%s" % TIME_STAMP, query=TIME_STAMP) self.assertEquals(tr.select_test_cases_by, "dynamicQueryResult") num_recs = len(tr.records) test_case_id = tr.records[0].test_case_id tr.update_test_record_by_fields(test_case_id, "blocked", "comment", tr.logged_in_user_id, datetime.datetime.now(), 0) tr.reload() self.assertEquals(num_recs, len(tr.records)) self.assertEquals(test_case_id, tr.records[0].test_case_id) self.assertEquals(tr.records[0].result, "blocked")
def test_009_create_comment(self): tc = TestCase(project_id=DEFAULT_PROJ, work_item_id=self.work_item_id) tc.create_comment("This is a comment") tc2 = TestCase(project_id=DEFAULT_PROJ, work_item_id=self.work_item_id) self.assertTrue(len(tc2.comments) == 1) comment = tc2.comments[0] self.assertEqual(comment.text, "This is a comment")
def test_008_create_attachment(self): tc = TestCase(project_id=DEFAULT_PROJ, work_item_id=self.work_item_id) tc.create_attachment(ATTACH_PATH, "Attached File") tc2 = TestCase(project_id=DEFAULT_PROJ, work_item_id=self.work_item_id) self.assertTrue(len(tc2.attachments) == 1) attach = tc2.attachments[0] self.assertEqual(attach.author, tc2.logged_in_user_id) self.assertEqual(attach.title, "Attached File")
def mark_for_deletion(tc, tag): if tag in tc.title: wi = TestCase(uri=tc.uri) wi.title = "stoner-DeleteMe" try: wi.update() print "Changed {} title from {} to {}".format(wi.work_item_id, tc.title, wi.title) except: print "Failed to change {}".format(wi.work_item_id)
def test_013_multiple_types(self): req = Requirement() tc = TestCase() with self.assertRaises(AttributeError): tc.reqtype with self.assertRaises(AttributeError): req.caseimportance req.title = "req1" tc.title = "tc1" self.assertNotEqual(req.title, tc.title)
def add_colon_tc(tc): parts = tc.title.split() if ":" not in tc.title: newtitle = parts[0] + " : " + parts[1] wi = TestCase(uri=tc.uri) wi.title = newtitle try: wi.update() print "Changed title to {}".format(newtitle) except: print "Failed to update {}".format(wi.title)
def print_steps_for_testcase(self, case_id): tc = TestCase(TestCase.default_project, case_id) steps = tc.get_test_steps() for step in steps.steps: stp = step.values[0].content exp = step.values[1].content print('TestStep = %s' % stp) print('ExpectedResult = %s\n' % exp) if steps.steps is None: print('No step for this tesecase!')
def print_steps_for_testcase(self, case_id): tc = TestCase(TestCase.default_project, case_id) steps = tc.get_test_steps() for step in steps.steps: stp = step.values[0].content exp = step.values[1].content print 'TestStep = %s' % stp print 'ExpectedResult = %s\n' % exp if steps.steps is None: print 'No step for this tesecase!'
def test_custom_workitem(self): tc2 = TestCase(project_id=DEFAULT_PROJ, work_item_id=self.TEST_CASE_ID) self.assertIsNotNone(tc2.caseautomation) with self.assertRaises(PylarionLibException): tc2.caseautomation = "bad" tc2.caseautomation = "automated" # check for shared memory issue self.assertNotEqual(self.tc.caseautomation, tc2.caseautomation) req = Requirement() with self.assertRaises(PylarionLibException): req.reqtype = "bad" req.reqtype = 'functional'
def test_bad_character(self): """this test validates that non UTF-8 characters will cause an error """ test_case = TestCase() steps = TestSteps() with self.assertRaises(PylarionLibException): # check _obj_setter test_case.status = u"é".encode('latin') with self.assertRaises(PylarionLibException): # check _custom_setter test_case.tcmscaseid = u"é".encode('latin') with self.assertRaises(PylarionLibException): # check _regular_setter test_case.title = u"é".encode('latin') with self.assertRaises(PylarionLibException): # check _arr_obj_setter steps.keys = [u"é".encode('latin')]
def test_007_add_linked_work_item(self): tc = TestCase(project_id=DEFAULT_PROJ, work_item_id=self.work_item_id) self.assertTrue(tc.add_linked_item(self.work_item_id_2, "verifies")) tc2 = TestCase(project_id=DEFAULT_PROJ, work_item_id=self.work_item_id) self.assertTrue(len(tc2.linked_work_items) == 1) link = tc2.linked_work_items[0] self.assertEqual(link.work_item_id, self.work_item_id_2) self.assertEqual(link.role, "verifies") req3 = Requirement(project_id=DEFAULT_PROJ, work_item_id=self.work_item_id_2) self.assertTrue(len(req3.linked_work_items_derived) == 1) link = req3.linked_work_items_derived[0] self.assertEqual(link.work_item_id, self.work_item_id) self.assertEqual(link.role, "verifies")
def list_workitems_by_query(self, query, wi_type): fields = ['work_item_id', 'title', 'author', 'created'] if wi_type in ["testcase", "TestCase"]: workitem_list = TestCase.query(query, fields) elif wi_type in ["requirement", "Requirement"]: workitem_list = Requirement.query(query, fields) elif wi_type == '': workitem_list = TestCase.query(query, fields) + \ Requirement.query(query, fields) else: print("'%s' is invalid. Use testcase or requirement" % wi_type) exit(0) return workitem_list
def test_001_query(self): results = TestCase.query("project.id:%s AND title:regression" % (DEFAULT_PROJ)) tc = results[0] self.assertIsNone(tc.title) results2 = TestCase.query("project.id:%s AND title:regression" % (DEFAULT_PROJ), fields=["work_item_id", "title"]) tc = results2[0] self.assertIsNotNone(tc.title) results3 = TestCase.query("project.id:%s AND title:regression" % (DEFAULT_PROJ), fields=["work_item_id", "caseautomation"]) tc = results3[0] self.assertEquals(tc.caseautomation, "notautomated")
def test_011_edit_approval(self): tc = TestCase(project_id=DEFAULT_PROJ, work_item_id=self.work_item_id) with self.assertRaises(PylarionLibException): tc.edit_approval("invalid user", "approved") with self.assertRaises(PylarionLibException): tc.edit_approval(tc.logged_in_user_id, "invalid status") tc.edit_approval(tc.logged_in_user_id, "approved") tc2 = TestCase(project_id=DEFAULT_PROJ, work_item_id=self.work_item_id) self.assertTrue(len(tc2.approvals) == 1) approval = tc2.approvals[0] self.assertEqual(approval.status, "approved") self.assertEqual(approval.user_id, tc.logged_in_user_id)
def query_test_case(self, query=None): """ """ from pylarion.work_item import TestCase as PylTestCase if query is None: query = "title:{}".format(self.title) return PylTestCase.query(query)
def test_run(path, test_run_id, test_template_id, user, project): """Execute a test run based on jUnit XML file.""" results = parse_junit(path) try: test_run = TestRun(test_run_id, project_id=project) click.echo('Test run {0} found.'.format(test_run_id)) except PylarionLibException as err: click.echo(err, err=True) click.echo('Creating test run {0}.'.format(test_run_id)) test_run = TestRun.create(project, test_run_id, test_template_id) for result in results: test_case_id = '{0}.{1}'.format(result['classname'], result['name']) test_case = TestCase.query(test_case_id) if len(test_case) == 0: click.echo( 'Was not able to find test case with id {0}, skipping...'. format(test_case_id)) continue status = POLARION_STATUS[result['status']] work_item_id = test_case[0].work_item_id click.echo( 'Adding test record for test case {0} with status {1}.'.format( work_item_id, status)) try: test_run.add_test_record_by_fields( test_case_id=work_item_id, test_result=status, test_comment=result.get('message'), executed_by=user, executed=datetime.datetime.now(), duration=float(result.get('time', '0'))) except PylarionLibException as err: click.echo('Skipping test case {0}.'.format(work_item_id)) click.echo(err, err=True)
def setUpClass(cls): global TEST_RUN_ID cls.doc = Document.create(DEFAULT_PROJ, "Testing", DOC_NAME, "Attribute_Test", ["testcase"], "testspecification") cls.testrun = TestRun.create(DEFAULT_PROJ, TEST_RUN_ID, "example", TEST_RUN_TITLE) TEST_RUN_ID = cls.testrun.test_run_id # arch is a custom field defined by global admins for test runs. # It is set here for a test on custom fields that requires at least two # valid values. If in the future, this custom field is removed, or the # number of valid values is lowered to 1, a different custom field will # have to be used. valid_values = cls.testrun.get_valid_field_values("arch") cls.testrun.arch = valid_values[1] cls.testrun.update() cls.tc = TestCase.create(DEFAULT_PROJ, "regression", "regression", caseimportance="high", caselevel="component", caseautomation="notautomated", caseposneg="positive", testtype="functional", subtype1="-") cls.TEST_CASE_ID = cls.tc.work_item_id
def print_links_for_testcase(self, case_id): tc = TestCase(TestCase.default_project, case_id) print('ID%-12sRole' % ('')) print('-------%7s------' % ('')) for linked in tc.linked_work_items: print('%-13s %-13s' % (linked.work_item_id, linked.role))
def __init__(self, project_name=None, *args, **kwargs): if project_name == None: self.polarion = TestCase() self.project_name = self.polarion.default_project else: self.project_name = project_name # Open a persistent shelf for the default or specified project self.shelf = shelve.open(self.project_name)
def add_test_record(result): """Task that adds a test result to a test run. This task relies on ``OBJ_CACHE`` to get the test run and user objects. The object cache is needed since suds objects are not able to be pickled and it is not possible to pass them to processes. """ test_run = OBJ_CACHE['test_run'] user = OBJ_CACHE['user'] testcases = OBJ_CACHE['testcases'] junit_test_case_id = '{0}.{1}'.format(result['classname'], result['name']) test_case_id = testcases.get(junit_test_case_id) if not test_case_id: click.echo( 'Missing ID information for test {0}, using junit test case id...'. format(junit_test_case_id)) test_case_id = junit_test_case_id test_case = TestCase.query(test_case_id) if len(test_case) == 0: click.echo( 'Was not able to find test case {0} with id {1}, skipping...'. format(junit_test_case_id, test_case_id)) return status = POLARION_STATUS[result['status']] work_item_id = test_case[0].work_item_id click.echo('Adding test record for test case {0} with status {1}.'.format( work_item_id, status)) message = result.get('message', '') if message and type(message) == unicode: message = message.encode('ascii', 'xmlcharrefreplace') try: test_run.add_test_record_by_fields(test_case_id=work_item_id, test_result=status, test_comment=message, executed_by=user, executed=datetime.datetime.now(), duration=float( result.get('time', '0'))) except PylarionLibException as err: click.echo('Skipping test case {0}.'.format(work_item_id)) click.echo(err, err=True) except Exception as err: click.echo( 'Error when adding test record for "{test_case_id}" with the ' 'following information:\n' 'duration="{duration}"' 'executed="{executed}"\n' 'executed_by="{executed_by}"\n' 'test_result="{test_result}"\n' 'test_comment="{test_comment}"\n'.format( test_case_id=work_item_id, test_result=status, test_comment=message, executed_by=user, executed=datetime.datetime.now(), duration=float(result.get('time', '0')))) click.echo(traceback.format_exc(), err=True) raise
def test_014_steps(self): test1 = ["Test 1", "Result 1"] test2 = ["Test 2", "Result 2"] test3 = ["Test 3", "Result 3"] ts1 = TestStep() ts1.values = test1 ts2 = TestStep() ts2.values = test2 ts3 = TestStep() ts3.values = test3 set_steps = [ts1, ts2, ts3] tc = TestCase(project_id=DEFAULT_PROJ, work_item_id=self.work_item_id) tc.set_test_steps(set_steps) tc2 = TestCase(project_id=DEFAULT_PROJ, work_item_id=self.work_item_id) get_steps = tc2.get_test_steps() self.assertEqual(get_steps.steps[0].values[0].content, ts1.values[0].content) self.assertEqual(get_steps.steps[0].values[1].content, ts1.values[1].content) self.assertEqual(get_steps.steps[1].values[0].content, ts2.values[0].content) self.assertEqual(get_steps.steps[1].values[1].content, ts2.values[1].content) self.assertEqual(get_steps.steps[2].values[0].content, ts3.values[0].content) self.assertEqual(get_steps.steps[2].values[1].content, ts3.values[1].content)
def test_013_incident_report_test(self): """This test does the following: * gets a TestRun * gets a TestCase * adds test_steps * creates a TestRecord * populates the TestRecord * Fail the testRecord * reloads the TestCase * Verifies that an Incident Report was Created """ tr = TestRun(project_id=DEFAULT_PROJ, test_run_id=TEST_RUN_ID) tests = [["Test 1", "Result 1"], ["Test 2", "Result 2"], ["Test 3", "Result 3"]] set_steps = [] for test in tests: ts = TestStep() ts.values = test set_steps.append(ts) tc = TestCase(work_item_id=self.NEW_TEST_CASE) tc.set_test_steps(set_steps) tc.update() tc.reload() steps = tc.test_steps.steps results = [] for step in steps: res = TestStepResult() res.result = "failed" res.comment = "This is the result" results.append(res) rec = TestRecord() rec.test_step_results = results rec.test_case_id = self.NEW_TEST_CASE rec.comment = "Incident Report was Created" rec.duration = "50.5" rec.result = "failed" rec.executed_by = tr.logged_in_user_id rec.executed = datetime.datetime.now() tr.update_test_record_by_object(self.NEW_TEST_CASE, rec) tc.reload() linked_work_items = tc.linked_work_items_derived idx = len(linked_work_items) - 1 incident = Incident(project_id="proj1", work_item_id=linked_work_items[idx].work_item_id) self.assertIsNotNone(incident)
def add_test_record(result): """Task that adds a test result to a test run. This task relies on ``OBJ_CACHE`` to get the test run and user objects. The object cache is needed since suds objects are not able to be pickled and it is not possible to pass them to processes. """ test_run = OBJ_CACHE['test_run'] user = OBJ_CACHE['user'] test_case_id = '{0}.{1}'.format(result['classname'], result['name']) test_case = TestCase.query(test_case_id) if len(test_case) == 0: click.echo( 'Was not able to find test case with id {0}, skipping...' .format(test_case_id) ) return status = POLARION_STATUS[result['status']] work_item_id = test_case[0].work_item_id click.echo( 'Adding test record for test case {0} with status {1}.' .format(work_item_id, status) ) message = result.get('message', '') if message and type(message) == unicode: message = message.encode('ascii', 'xmlcharrefreplace') try: test_run.add_test_record_by_fields( test_case_id=work_item_id, test_result=status, test_comment=message, executed_by=user, executed=datetime.datetime.now(), duration=float(result.get('time', '0')) ) except PylarionLibException as err: click.echo('Skipping test case {0}.'.format(work_item_id)) click.echo(err, err=True) except: click.echo( 'Error when adding test record for "{test_case_id}" with the ' 'following information:\n' 'duration="{duration}"' 'executed="{executed}"\n' 'executed_by="{executed_by}"\n' 'test_result="{test_result}"\n' 'test_comment="{test_comment}"\n' .format( test_case_id=work_item_id, test_result=status, test_comment=message, executed_by=user, executed=datetime.datetime.now(), duration=float(result.get('time', '0')) ) ) raise
def get_automation_statuses_from_polarion(): polarion_items = TestCase.query('project.id:{}'.format( conf().polarion.project)) LUT = {stat: set() for stat in POLARION_CASE_AUTOMATION_STATUSES} for item in polarion_items: test_case = TestCase(uri=item.uri) # TODO: Check whether we have the ID as property of test_case item_id = extract_polarion_case_ids(item.uri).pop() caseautomation = test_case.caseautomation print '{} - {}'.format(item_id, caseautomation) if caseautomation not in LUT: LUT[caseautomation] = set() LUT[caseautomation].add(item_id) return LUT
def fix_tc_title(tc): """ Need to add RHSM-TC : prefix to the existing testcases :param tc: :return: """ if tc.title.startswith("RHSM-TC : "): print "TestCase already starts with RHSM-TC : " return newtitle = "RHSM-TC : " + tc.title wi = TestCase(uri=tc.uri) wi.title = newtitle try: wi.update() print "Changed {} title to {}".format(wi.work_item_id, newtitle) except: print "Failed to update {}".format(wi.title)
def test_004_add_approvee(self): tc = TestCase(project_id=DEFAULT_PROJ, work_item_id=self.work_item_id) with self.assertRaises(PylarionLibException): tc.add_approvee("invalid user") tc.add_approvee(tc.logged_in_user_id) tc2 = TestCase(project_id=DEFAULT_PROJ, work_item_id=self.work_item_id) self.assertTrue(len(tc2.approvals) == 1) approval = tc2.approvals[0] self.assertEqual(approval.status, "waiting") self.assertEqual(approval.user_id, tc.logged_in_user_id)
def query_test_case(query, fields=None, **kwargs): """ Returns a list of pylarion TestCase objects :param query: :param fields: an optional list of fields to populate in the returned TestCase objects (by default only work_item_id and title will be populated) :return: """ if fields is None: fields = ["work_item_id", "title"] from pylarion.work_item import TestCase as PylTestCase return PylTestCase.query(query, fields=fields, **kwargs)
def test_003_add_assignee(self): tc = TestCase(project_id=DEFAULT_PROJ, work_item_id=self.work_item_id) with self.assertRaises(PylarionLibException): tc.add_assignee("invalid user") self.assertTrue(tc.add_assignee(tc.logged_in_user_id)) tc2 = TestCase(project_id=DEFAULT_PROJ, work_item_id=self.work_item_id) self.assertTrue(tc2.assignee) self.assertEqual(tc2.assignee[0].user_id, tc2.logged_in_user_id)
def test_005_add_category(self): tc = TestCase(project_id=DEFAULT_PROJ, work_item_id=self.work_item_id) with self.assertRaises(PylarionLibException): tc.add_category("invalid category") self.assertTrue(tc.add_category("filesystems")) tc2 = TestCase(project_id=DEFAULT_PROJ, work_item_id=self.work_item_id) self.assertTrue(len(tc2.categories) == 1) cat = tc2.categories[0] self.assertEqual(cat.category_id, "filesystems")
def test_006_add_hyperlink(self): # TODO: check if an invalid hyperlink can be passed in. tc = TestCase(project_id=DEFAULT_PROJ, work_item_id=self.work_item_id) with self.assertRaises(PylarionLibException): tc.add_hyperlink(HYPERLINK, "invalid") self.assertTrue(tc.add_hyperlink(HYPERLINK, "ref_ext")) tc2 = TestCase(project_id=DEFAULT_PROJ, work_item_id=self.work_item_id) self.assertTrue(len(tc2.hyperlinks) == 1) link = tc2.hyperlinks[0] self.assertEqual(link.uri, HYPERLINK) self.assertEqual(link.role, "ref_ext")
def setUpClass(cls): tc = TestCase.create(DEFAULT_PROJ, "regression", "regression", caseimportance="high", caselevel="component", caseautomation="notautomated", caseposneg="positive", testtype="functional", subtype1="-") req = Requirement.create(DEFAULT_PROJ, "regression _link", "regression link", reqtype="functional", severity="should_have") cls.work_item_id = tc.work_item_id cls.work_item_uri = tc.uri cls.work_item_id_2 = req.work_item_id cls.work_item_uri_2 = req.uri
def create_new_case(prefix, case_name, topo, document, project): """create new case through the name and topo of case""" print(green("Create New Testcase NAME:%s, TOPO:%s" % (case_name, topo))) if topo == "": case_title = "{}: {}".format(prefix, case_name) else: case_title = "{}: {} FUNC={}".format(prefix, case_name, topo) try: case_item = TestCase.create(project, title=case_title, desc="", caseimportance="high", caseautomation="automated", caseposneg="positive", caselevel="component", testtype="functional", subtype1="-") document.move_work_item_here(case_item.work_item_id, None) except: return create_new_case(prefix, case_name, topo, document, project) return case_item.work_item_id
def remove_linked_requirements_from_tests(test_cases): """ Removes all linked Items from TestCase objects in test_Cases :param test_cases: :return: """ with open("/tmp/tc_delete.txt", "w") as tcd: for tc in test_cases: tc = TestCase(uri=tc.uri) linked_items = tc.linked_work_items for li in linked_items: tc.remove_linked_item(li.work_item_id, "verifies") tc.title = "DeleteMe" if tc.author == "ci-user": tc.author = "stoner" tcd.write(tc.work_item_id + "\n") tcd.flush() tc.update()
def test_run(path, test_run_id, test_template_id, user, project): """Execute a test run based on jUnit XML file.""" results = parse_junit(path) try: test_run = TestRun(test_run_id, project_id=project) click.echo('Test run {0} found.'.format(test_run_id)) except PylarionLibException as err: click.echo(err, err=True) click.echo('Creating test run {0}.'.format(test_run_id)) test_run = TestRun.create(project, test_run_id, test_template_id) for result in results: test_case_id = '{0}.{1}'.format(result['classname'], result['name']) test_case = TestCase.query(test_case_id) if len(test_case) == 0: click.echo( 'Was not able to find test case with id {0}, skipping...' .format(test_case_id) ) continue status = POLARION_STATUS[result['status']] work_item_id = test_case[0].work_item_id click.echo( 'Adding test record for test case {0} with status {1}.' .format(work_item_id, status) ) try: test_run.add_test_record_by_fields( test_case_id=work_item_id, test_result=status, test_comment=result.get('message'), executed_by=user, executed=datetime.datetime.now(), duration=float(result.get('time', '0')) ) except PylarionLibException as err: click.echo('Skipping test case {0}.'.format(work_item_id)) click.echo(err, err=True)
def add_test_case(args): """Task that creates or updates Test Cases and manages their Requirement. This task relies on ``OBJ_CACHE`` to get the collect_only and project objects. :param args: A tuple where the first element is a path and the second is a list of ``TestFunction`` objects mapping the tests from that path. """ path, tests = args collect_only = OBJ_CACHE['collect_only'] project = OBJ_CACHE['project'] for test in tests: # Fetch the test case id if the @Id tag is present otherwise generate a # test_case_id based on the test Python import path test_case_id = test.unexpected_tags.get('id') if not test_case_id: # Generate the test_case_id. It could be either path.test_name or # path.ClassName.test_name if the test methods is defined within a # class. test_case_id_parts = [ path.replace('/', '.').replace('.py', ''), test.name ] if test.parent_class is not None: test_case_id_parts.insert(-1, test.parent_class) test_case_id = '.'.join(test_case_id_parts) if test.docstring: if not type(test.docstring) == unicode: test.docstring = test.docstring.decode('utf8') test.docstring = RST_PARSER.parse(test.docstring) # Is the test automated? Acceptable values are: # automated, manualonly, and notautomated auto_status = test.unexpected_tags.get( 'caseautomation', 'automated' if test.automated else 'notautomated' ).lower() caseposneg = test.unexpected_tags.get( 'caseposneg', 'negative' if 'negative' in test.name else 'positive' ).lower() subtype1 = test.unexpected_tags.get( 'subtype1', '-' ).lower() casecomponent = test.unexpected_tags.get('casecomponent', '-').lower() caseimportance = test.unexpected_tags.get( 'caseimportance', 'medium').lower() caselevel = test.unexpected_tags.get('caselevel', 'component').lower() setup = test.setup if test.setup else None status = test.unexpected_tags.get('status', 'approved').lower() testtype = test.unexpected_tags.get( 'testtype', 'functional' ).lower() upstream = test.unexpected_tags.get('upstream', 'no').lower() results = [] if not collect_only: results = TestCase.query( test_case_id, fields=[ 'caseautomation', 'caseposneg', 'description', 'work_item_id' ] ) requirement_name = test.unexpected_tags.get( 'requirement', parse_requirement_name(path)) if len(results) == 0: click.echo( 'Creating test case {0} for requirement {1}.' .format(test.name, requirement_name) ) if not collect_only: test_case = TestCase.create( project, test.name, test.docstring if test.docstring else '', caseautomation=auto_status, casecomponent=casecomponent, caseimportance=caseimportance, caselevel=caselevel, caseposneg=caseposneg, subtype1=subtype1, test_case_id=test_case_id, testtype=testtype, setup=setup, upstream=upstream, ) test_case.status = status test_case.update() click.echo( 'Linking test case {0} to verify requirement {1}.' .format(test.name, requirement_name) ) if not collect_only: requirement = fetch_requirement( requirement_name, project, collect_only) test_case.add_linked_item( requirement.work_item_id, 'verifies') else: click.echo( 'Updating test case {0} for requirement {1}.' .format(test.name, requirement_name) ) # Ensure that a single match for the Test Case is # returned. assert len(results) == 1 test_case = results[0] if not collect_only and any(( test_case.caseautomation != auto_status, test_case.casecomponent != casecomponent, test_case.caseimportance != caseimportance, test_case.caselevel != caselevel, test_case.caseposneg != caseposneg, test_case.description != test.docstring, test_case.setup != setup, test_case.subtype1 != subtype1, test_case.testtype != testtype, test_case.upstream != upstream, test_case.status != status, )): test_case.description = ( test.docstring if test.docstring else '') test_case.caseautomation = auto_status test_case.casecomponent = casecomponent test_case.caseimportance = caseimportance test_case.caselevel = caselevel test_case.caseposneg = caseposneg test_case.setup = setup test_case.status = status test_case.subtype1 = subtype1 test_case.testtype = testtype test_case.upstream = upstream test_case.update()
def test_case(path, collect_only, project): """Sync test cases with Polarion.""" testcases = testimony.get_testcases([path]) for path, tests in testcases.items(): requirement = None for test in tests: # Expect test_case_id to be path.test_name or # path.ClassName.test_name. test_case_id_parts = [ path.replace('/', '.').replace('.py', ''), test.name ] if test.parent_class is not None: test_case_id_parts.insert(-1, test.parent_class) test_case_id = '.'.join(test_case_id_parts) if requirement is None: requirement_name = parse_requirement_name(test_case_id) results = Requirement.query('{0}'.format(requirement_name), fields=['title', 'work_item_id']) if len(results) > 0: # As currently is not possible to get a single # match for the title, make sure to not use a # not intended Requirement. for result in results: if result.title == requirement_name: requirement = result if requirement is None: click.echo( 'Creating requirement {0}.'.format(requirement_name)) if not collect_only: requirement = Requirement.create(project, requirement_name, '', reqtype='functional') results = TestCase.query(test_case_id, fields=['description', 'work_item_id']) if len(results) == 0: click.echo( 'Creating test case {0} for requirement {1}.'.format( test.name, requirement_name)) if not collect_only: test_case = TestCase.create( project, test.name, test.docstring if test.docstring else '', caseautomation='automated', casecomponent='-', caseimportance='medium', caselevel='component', caseposneg='positive', subtype1='-', test_case_id=test_case_id, testtype='functional', ) click.echo( 'Liking test case {0} to verify requirement {1}.'.format( test.name, requirement_name)) if not collect_only: test_case.add_linked_item(requirement.work_item_id, 'verifies') else: click.echo( 'Updating test case {0} for requirement {1}.'.format( test.name, requirement_name)) # Ensure that a single match for the Test Case is # returned. assert len(results) == 1 test_case = results[0] if (not collect_only and test_case.description != test.docstring): test_case = TestCase(project, test_case.work_item_id) test_case.description = (test.docstring if test.docstring else '') test_case.update()
def edit_tc_title(tc_, prefix): tc = TestCase(uri=tc_.uri) tc.title += prefix tc.update()
def test_case(path, collect_only, project): """Sync test cases with Polarion.""" testcases = testimony.get_testcases([path]) for path, tests in testcases.items(): requirement = None for test in tests: # Expect test_case_id to be path.test_name or # path.ClassName.test_name. test_case_id_parts = [ path.replace('/', '.').replace('.py', ''), test.name ] if test.parent_class is not None: test_case_id_parts.insert(-1, test.parent_class) test_case_id = '.'.join(test_case_id_parts) if requirement is None: requirement_name = parse_requirement_name(test_case_id) results = Requirement.query( '{0}'.format(requirement_name), fields=['title', 'work_item_id'] ) if len(results) > 0: # As currently is not possible to get a single # match for the title, make sure to not use a # not intended Requirement. for result in results: if result.title == requirement_name: requirement = result if requirement is None: click.echo( 'Creating requirement {0}.'.format(requirement_name)) if not collect_only: requirement = Requirement.create( project, requirement_name, '', reqtype='functional' ) results = TestCase.query( test_case_id, fields=['description', 'work_item_id']) if len(results) == 0: click.echo( 'Creating test case {0} for requirement {1}.' .format(test.name, requirement_name) ) if not collect_only: test_case = TestCase.create( project, test.name, test.docstring if test.docstring else '', caseautomation='automated', casecomponent='-', caseimportance='medium', caselevel='component', caseposneg='positive', subtype1='-', test_case_id=test_case_id, testtype='functional', ) click.echo( 'Liking test case {0} to verify requirement {1}.' .format(test.name, requirement_name) ) if not collect_only: test_case.add_linked_item( requirement.work_item_id, 'verifies') else: click.echo( 'Updating test case {0} for requirement {1}.' .format(test.name, requirement_name) ) # Ensure that a single match for the Test Case is # returned. assert len(results) == 1 test_case = results[0] if (not collect_only and test_case.description != test.docstring): test_case = TestCase(project, test_case.work_item_id) test_case.description = ( test.docstring if test.docstring else '') test_case.update()
def test_002_get_item(self): tc = TestCase(project_id=DEFAULT_PROJ, work_item_id=self.work_item_id) self.assertIsNotNone(tc.uri)
def main(): isUpdateAutomationValue = False # access excel file and update results credentials = get_credentials() http = credentials.authorize(httplib2.Http()) discoveryUrl = ('https://sheets.googleapis.com/$discovery/rest?version=v4') service = discovery.build('sheets', 'v4', http=http, discoveryServiceUrl=discoveryUrl) # https://docs.google.com/spreadsheets/d/1y4eBJhcZ0HsB5JUH5MPcFXWtc2zbP9XbgdCIF0S4iHs/edit#gid=1503195790 spreadsheetId = '1y4eBJhcZ0HsB5JUH5MPcFXWtc2zbP9XbgdCIF0S4iHs' # Get all test runs by Polarion query, extract test run id and test run results (pass, fail, pending block, total...) test_runs_uris = TestRun.search( 'NOT status:invalid AND plannedin.KEY:RHOS16' ) #updated:[20190627 TO 20190630]') # # test_runs_uris = TestRun.search('20180625-0836') print("Number of items %s" % len(test_runs_uris)) loop_counter = 1 missing_test_run_in_excel = '' non_test_cases_item = 0 for test_run_uri in test_runs_uris: # for i in range(106,130): # test_run_uri = test_runs_uris[i] #get excel values rangeName = 'RHOS 16!A2:X' result = service.spreadsheets().values().get( spreadsheetId=spreadsheetId, range=rangeName).execute() values = result.get('values', []) value_input_option = 'RAW' print('Updating test run number: ' + str(loop_counter)) loop_counter += 1 print(test_run_uri.uri) test_run = TestRun(uri=test_run_uri.uri) test_run_id = test_run.test_run_id print('Test run title: ' + test_run.title) print('Test run ID: ' + test_run.test_run_id) records = test_run.records pass_counter = 0 fail_counter = 0 pending_counter = 0 automation_counter = 0.0 critical_counter = 0 critical_auto_counter = 0 #automation_percentage = 0 blocked_counter = 0 total_counter = 0 #Collect inforamtion about test runs, how many test pass if test_run.TestRunType == 'Acceptance': for record in records: if record.result == 'passed': pass_counter += 1 elif record.result == 'failed': fail_counter += 1 elif record.result == 'blocked': blocked_counter += 1 else: pending_counter += 1 else: for record in records: # print record.result #check if test is automated test = TestCase.query(record.test_case_id) # print('Test case ID: ' + record.test_case_id) # Check if the object type is a testcase and not a header for example! if test and not Requirement.query(record.test_case_id): #calculate critical automated and rest automated if isUpdateAutomationValue: if test[0].caseautomation.lower() == 'automated': automation_counter += 1 if test[0].caseimportance.lower() == 'critical': critical_auto_counter += 1 #count number of critical cases if test[0].caseimportance.lower() == 'critical': critical_counter += 1 if record.result == 'passed': pass_counter += 1 elif record.result == 'failed': fail_counter += 1 elif record.result == 'blocked': blocked_counter += 1 else: pending_counter += 1 else: non_test_cases_item += 1 total_counter = pass_counter + fail_counter + blocked_counter + pending_counter # if total_counter > 0: # automation_percentage = int(float(automation_counter)/float(total_counter)) #*100 print('Total pass:'******'Total fail:', fail_counter) print('Total blocked:', blocked_counter) print('Total pending:', pending_counter) print('Total automated:', automation_counter) print('Number of critical:', critical_counter) print('Number of critical auto:', critical_auto_counter) #print ('Automation percentage:', automation_percentage) print('Total number of test cases:', total_counter) #column number in excel file and thier representation as hard coded value row_counter = 1 # offset due to headers title_column_number = 2 total_column_number = 8 pass_column_number = 9 fail_column_number = 10 blocked_column_number = 11 test_run_id_column_number = 20 automation_percentage_column_number = 18 critical_test_number = 22 is_test_run_exist_in_excel = None if not values: print('No data found.') else: for row in values: is_test_run_exist_in_excel = False row_counter += 1 # print(row_counter) # if(row_counter==134): # print('stop') # Check that row contains test run id in cell R AND check that test_run_id is match if row.__len__() >= test_run_id_column_number and row[ test_run_id_column_number] == test_run_id: print('Row number is: ' + str(row_counter)) is_test_run_exist_in_excel = True # print('%s, %s, %s, %s, %s, %s, %s :' % (row[title_column_number], row[total_column_number], row[pass_column_number], row[fail_column_number], row[blocked_column_number],row[automation_percentage_column_number], row[critical_test_number])) values = [[ total_counter, total_counter, pass_counter, fail_counter, blocked_counter ]] body = {'values': values} rangeName = 'RHOS 15!H' + str(row_counter) + ':L' + str( row_counter) result = service.spreadsheets().values().update( spreadsheetId=spreadsheetId, range=rangeName, valueInputOption=value_input_option, body=body).execute() # # update automation percentage field # values = [ # [automation_percentage] # ] # body = { # 'values': values # } # rangeName = 'RHOS 13!S' + str(row_counter) # result = service.spreadsheets().values().update(spreadsheetId=spreadsheetId, range=rangeName, valueInputOption='USER_ENTERED',body=body).execute() # update PQI values... if isUpdateAutomationValue and test_run.TestRunType != 'Acceptance': values = [[ automation_counter, critical_counter, critical_auto_counter ]] body = {'values': values} rangeName = 'RHOS 15!V' + str( row_counter) + ':X' + str(row_counter) result = service.spreadsheets().values().update( spreadsheetId=spreadsheetId, range=rangeName, valueInputOption=value_input_option, body=body).execute() # done with update, move to next test run break #Check if test run exist in excel file and was updated if not is_test_run_exist_in_excel: missing_test_run_in_excel += test_run_id + ", " print("Missing Test Runs in Excel: " + missing_test_run_in_excel) print("Number of headers or requirements in test runs: ", non_test_cases_item)
def add_test_case(args): """Task that creates or updates Test Cases and manages their Requirement. This task relies on ``OBJ_CACHE`` to get the collect_only and project objects. :param args: A tuple where the first element is a path and the second is a list of ``TestFunction`` objects mapping the tests from that path. """ path, tests = args collect_only = OBJ_CACHE['collect_only'] project = OBJ_CACHE['project'] # Fetch or create a Requirement requirement = None requirement_name = parse_requirement_name(path) click.echo( 'Fetching requirement {0}.'.format(requirement_name)) if not collect_only: results = Requirement.query( '{0}'.format(requirement_name), fields=['title', 'work_item_id'] ) if len(results) > 0: # As currently is not possible to get a single # match for the title, make sure to not use a # not intended Requirement. for result in results: if result.title == requirement_name: requirement = result if requirement is None: click.echo( 'Creating requirement {0}.'.format(requirement_name)) if not collect_only: requirement = Requirement.create( project, requirement_name, '', reqtype='functional' ) for test in tests: # Generate the test_case_id. It could be either path.test_name or # path.ClassName.test_name if the test methods is defined within a # class. test_case_id_parts = [ path.replace('/', '.').replace('.py', ''), test.name ] if test.parent_class is not None: test_case_id_parts.insert(-1, test.parent_class) test_case_id = '.'.join(test_case_id_parts) if test.docstring: if not type(test.docstring) == unicode: test.docstring = test.docstring.decode('utf8') test.docstring = RST_PARSER.parse(test.docstring) # Is the test automated? Acceptable values are: # automated, manualonly, and notautomated auto_status = 'automated' if test.automated else 'notautomated' caseposneg = 'negative' if 'negative' in test.name else 'positive' setup = test.setup if test.setup else None results = [] if not collect_only: results = TestCase.query( test_case_id, fields=[ 'caseautomation', 'caseposneg', 'description', 'work_item_id' ] ) if len(results) == 0: click.echo( 'Creating test case {0} for requirement {1}.' .format(test.name, requirement_name) ) if not collect_only: test_case = TestCase.create( project, test.name, test.docstring if test.docstring else '', caseautomation=auto_status, casecomponent='-', caseimportance='medium', caselevel='component', caseposneg=caseposneg, subtype1='-', test_case_id=test_case_id, testtype='functional', setup=setup, ) click.echo( 'Linking test case {0} to verify requirement {1}.' .format(test.name, requirement_name) ) if not collect_only: test_case.add_linked_item( requirement.work_item_id, 'verifies') else: click.echo( 'Updating test case {0} for requirement {1}.' .format(test.name, requirement_name) ) # Ensure that a single match for the Test Case is # returned. assert len(results) == 1 test_case = results[0] if (not collect_only and (test_case.description != test.docstring or test_case.caseautomation != auto_status or test_case.caseposneg != caseposneg or test_case.setup != setup)): test_case.description = ( test.docstring if test.docstring else '') test_case.caseautomation = auto_status test_case.caseposneg = caseposneg test_case.setup = setup test_case.update()
def create_polarion_tc(self): """ Given the pong.TestCase, convert it to the equivalent pylarion.work_item.TestCase """ t = lambda x: unicode.encode(x, encoding="utf-8", errors="ignore") if isinstance(x, unicode) else x desc, title = [t(x) for x in [self.description, self.title]] # Check to see if we already have an existing test case tc = None if self.polarion_tc: log.info("Getting TestCase for {}: {}".format(title, desc)) tc = self.polarion_tc self.validate_test(tc) if not self.polarion_tc.title.startswith(self.prefix): self.polarion_tc.title = self.prefix + self.polarion_tc.title # See if the Polarion Test Case has steps. The TestCase will contain a TestSteps array of size 1 # The step will have 2 columns (or key-value pairs) # | step | expectedResult # +======+=============== # | args | PASS test_steps = tc.get_test_steps() steps = test_steps.steps # If this TestCase has more than 1 TestStep, it's the older workaround where a TestStep was a row # of data in the 2d array. Moving to the SR2 2015 release with parameterized testing instead if len(steps) > 1: tc.set_test_steps() # Empty the TestSteps if len(steps) == 0: step = self.make_polarion_test_step() tc.set_test_steps([step]) else: log.info("Generating new TestCase for {} : {}".format(title, desc)) WORKAROUND_949 = False try: self.description.decode(encoding="utf-8") except UnicodeError: raw = self.description.encode("utf-8") self.description = unicode(raw, encoding="utf-8", errors="replace") try: self.description.decode(encoding="utf-8") except UnicodeError: WORKAROUND_949 = True if WORKAROUND_949: self.description = unicode("", encoding="utf-8") from pylarion.work_item import TestCase as PylTestCase tc = PylTestCase.create(self.project, self.title, self.description, **TC_KEYS) # Create PylTestSteps if needed and add it if self.step_results: step = self.make_polarion_test_step() tc.set_test_steps([step]) if not tc: raise Exception("Could not create TestCase for {}".format(self.title)) else: self.polarion_tc = tc self.link_requirements(tc) self.polarion_tc.update() return tc
def add_test_case(args): """Task that creates or updates Test Cases and manages their Requirement. This task relies on ``OBJ_CACHE`` to get the collect_only and project objects. :param args: A tuple where the first element is a path and the second is a list of ``TestFunction`` objects mapping the tests from that path. """ path, tests = args collect_only = OBJ_CACHE['collect_only'] project = OBJ_CACHE['project'] for test in tests: # Fetch the test case id if the @Id tag is present otherwise generate a # test_case_id based on the test Python import path test_case_id = test.tokens.get('id', generate_test_id(test)) if test.docstring: if not type(test.docstring) == unicode: test.docstring = test.docstring.decode('utf8') # Is the test automated? Acceptable values are: # automated, manualonly, and notautomated auto_status = test.tokens.get( 'caseautomation', 'notautomated' if test.tokens.get('status') else 'automated' ).lower() caseposneg = test.tokens.get( 'caseposneg', 'negative' if 'negative' in test.name else 'positive' ).lower() subtype1 = test.tokens.get( 'subtype1', '-' ).lower() casecomponent = test.tokens.get('casecomponent', '-').lower() caseimportance = test.tokens.get( 'caseimportance', 'medium').lower() caselevel = test.tokens.get('caselevel', 'component').lower() description = test.tokens.get( 'description', test.docstring if test.docstring else '') description = RST_PARSER.parse(description) setup = test.tokens.get('setup') status = test.tokens.get('status', 'approved').lower() testtype = test.tokens.get( 'testtype', 'functional' ).lower() title = test.tokens.get('title', test.name) upstream = test.tokens.get('upstream', 'no').lower() steps = test.tokens.get('steps') expectedresults = test.tokens.get('expectedresults') if steps and expectedresults: test_steps = generate_test_steps( map_steps(steps, expectedresults)) else: test_steps = None results = [] if not collect_only: results = TestCase.query( test_case_id, fields=[ 'caseautomation', 'caseposneg', 'description', 'work_item_id' ] ) requirement_name = test.tokens.get( 'requirement', parse_requirement_name(path)) if len(results) == 0: click.echo( 'Creating test case {0} for requirement: {1}.' .format(title, requirement_name) ) if not collect_only: test_case = TestCase.create( project, title, description, caseautomation=auto_status, casecomponent=casecomponent, caseimportance=caseimportance, caselevel=caselevel, caseposneg=caseposneg, setup=setup, subtype1=subtype1, test_case_id=test_case_id, testtype=testtype, upstream=upstream, ) test_case.status = status if test_steps: test_case.test_steps = test_steps test_case.update() click.echo( 'Linking test case {0} to requirement: {1}.' .format(title, requirement_name) ) if not collect_only: requirement = fetch_requirement( requirement_name, project, collect_only) test_case.add_linked_item( requirement.work_item_id, 'verifies') else: click.echo( 'Updating test case {0} for requirement {1}.' .format(title, requirement_name) ) # Ensure that a single match for the Test Case is # returned. assert len(results) == 1 test_case = results[0] if not collect_only and any(( test_case.caseautomation != auto_status, test_case.casecomponent != casecomponent, test_case.caseimportance != caseimportance, test_case.caselevel != caselevel, test_case.caseposneg != caseposneg, test_case.description != description, test_case.setup != setup, test_case.status != status, test_case.subtype1 != subtype1, test_case.test_steps != test_steps, test_case.testtype != testtype, test_case.title != title, test_case.upstream != upstream, )): test_case.caseautomation = auto_status test_case.casecomponent = casecomponent test_case.caseimportance = caseimportance test_case.caselevel = caselevel test_case.caseposneg = caseposneg test_case.description = description test_case.setup = setup test_case.status = status test_case.subtype1 = subtype1 test_case.testtype = testtype test_case.title = title test_case.upstream = upstream if test_steps: test_case.test_steps = test_steps test_case.update()
class PolarionMapping(collections.MutableMapping): lucene_special_chars = ['+', '-', '&&', '||', '!', '(', ')', '{', '}', '[', ']', '^', '\"', '~', '*', '?', ':', '\\'] def __init__(self, project_name=None, *args, **kwargs): if project_name == None: self.polarion = TestCase() self.project_name = self.polarion.default_project else: self.project_name = project_name # Open a persistent shelf for the default or specified project self.shelf = shelve.open(self.project_name) def __del__(self): # Closing the shelf flushes and saves it self.shelf.close() def __getitem__(self, key): if self.shelf.has_key(key): return self.shelf.__getitem__(key) else: # Query Polarion for the test case if it isn't in the shelf tests = self.polarion.query("testCaseID:%s OR title:%s" % (self.escape_query(key), self.escape_query(key)), fields=["work_item_id", "title"], project_id=self.project_name) if len(tests) == 0: print "Test case '%s' does not exist in Polarion" % key return None elif len(tests) == 1: self.shelf[str(key)] = str(tests[0].work_item_id) self.shelf.sync() return self.shelf.__getitem__(key) else: err_str = "Found multiple test cases with testCaseID '%s' in Polarion\n" % key for tc in tests: if tc.test_case_id is not None: err_str += "testCaseID: '%s'; workItemID: '%s'\n" % (tc.test_case_id, tc.work_item_id) elif tc.title is not None: err_str += "title: '%s'; workItemID: '%s'\n" % (tc.title, tc.work_item_id) raise RuntimeError(err_str) def __setitem__(self, key, val): self.shelf[str(key)] = str(val) self.shelf.sync() def __delitem__(self, key): self.shelf.pop(key, None) def __iter__(self): return self.shelf.__iter__() def __len__(self): return len(self.shelf) def __repr__(self): return self.shelf.__repr__() def escape_query(self, query_str): '''Escape Lucene Query Syntax Special Characters''' for char in self.lucene_special_chars: escape_str = query_str.replace(char, '\%s' % char) return escape_str def sync(self, full=False): '''Sync the mapping with Polarion. If full is True, then do a complete re-sync.''' tests = self.polarion.query("", fields=["work_item_id", "title"], project_id=self.project_name) if full: self.shelf.clear() for test in tests: if test.test_case_id is not None and not self.shelf.has_key(str(test.test_case_id)): print "Adding '%s' with ID '%s'" % (test.test_case_id, test.work_item_id) self.shelf[str(test.test_case_id)] = str(test.work_item_id) elif test.title is not None and not self.shelf.has_key(str(test.title)): print "Adding '%s' with ID '%s'" % (test.title, test.work_item_id) self.shelf[str(test.title)] = str(test.work_item_id) self.shelf.sync()