def given(self): from corejet.core.model import RequirementsCatalogue, Epic, Story self.catalogue = RequirementsCatalogue(project="Test project", extractTime=datetime.datetime(2011, 1, 2, 12, 1, 0)) epic1 = Epic("E1", "First epic") self.catalogue.epics.append(epic1) epic2 = Epic("E2", "Second epic") self.catalogue.epics.append(epic2) story1 = Story("S1", "First story", points=3, status="open", priority="high", epic=epic1) epic1.stories.append(story1) story2 = Story("S2", "Second story", points=3, status="closed", resolution="fixed", priority="high", epic=epic1) epic1.stories.append(story2) text = """\ Scenario Outline: Count some apples Given I have <Start amount> apples When I get <Red> red and <Green> green apples more Then I have a total of <Sum> apples Examples: | Start amount | Red | Green | Sum | | 2 | 3 | 4 | 9 | | 3 | 4 | 5 | 12 | """ appendScenarios(story1, text)
def given(self): from corejet.core.model import RequirementsCatalogue, Epic, Story self.catalogue = RequirementsCatalogue(project="Test project", extractTime=datetime.datetime(2011, 1, 2, 12, 1, 0)) epic1 = Epic("E1", "First epic") self.catalogue.epics.append(epic1) epic2 = Epic("E2", "Second epic") self.catalogue.epics.append(epic2) story1 = Story("S1", "First story", points=3, status="open", priority="high", epic=epic1) epic1.stories.append(story1) story2 = Story("S2", "Second story", points=3, status="closed", resolution="fixed", priority="high", epic=epic1) epic1.stories.append(story2) text = """\ Scenario: First scenario Given something When something happens Then do something And something else Scenario: Second scenario Given something When something happens Then do something And something else """ appendScenarios(story1, text)
def given(self): from corejet.core.model import RequirementsCatalogue, Epic, Story self.catalogue = RequirementsCatalogue(project="Test project", extractTime=datetime.datetime(2011, 1, 2, 12, 1, 0)) epic1 = Epic("E1", "First epic") self.catalogue.epics.append(epic1) story1 = Story("S1", "First story", points=3, status="open", priority="high", epic=epic1) epic1.stories.append(story1) text = u"""\ # language: fi Tapausaihio: Montako yötä on jouluun Oletetaan, että tänään on <päivä>. joulukuuta. Kun avaan vielä <avaukset> luukkua joulukalenterista, niin jouluun on enää <jäljellä> yötä. Tapaukset: | päivä | avaukset | jäljellä | | 1 | 2 | 21 | | 21 | 3 | 0 | """ appendScenarios(story1, text)
def appendScenariosFromPivotalStory(story, node, options): """Appends scenarios from Pivotal node or prints error""" try: appendScenarios(story, node.findtext("description") or u"", default_language=options.get("language", "en")) for task in node.findall("tasks/task"): appendScenarios(story, task.findtext("description") or u"", default_language=options.get("language", "en")) except ValueError, e: print("Could not parse story %s\n%s" % (node.findtext("url"), str(e)))
def adaptRobotTestCaseToStory(context): """Creates a CoreJet story out of RobotTestCase by concatenating steps and parsing the result with appendScenarios.""" def find_suite(child_suite, default=None): """Returns the first test suite, which contains tests.""" if child_suite.testcase_table.tests: return child_suite for grandchild in getattr(child_suite, 'children', []): first_suite_with_test_cases = find_suite(grandchild) if first_suite_with_test_cases: return first_suite_with_test_cases return default suite = find_suite(context._robot_suite, context._robot_suite) name, title = (u"", u"") for metadata in suite.setting_table.metadata: if metadata.name == u"Id": name = metadata.value elif metadata.name == u"Title": title = metadata.value story = RobotStory(name, title) setattr(story, context._testMethodName, story.runTest) source = u"" for keyword in suite.keyword_table.keywords: # here we expect that possible story level steps are described # as Background-keyword if keyword.name == u"Background": for step in keyword.steps: source += u"\n".join(step.as_list()) + u"\n" source += u"\n" for scenario in suite.testcase_table.tests: source += u"Scenario: %s\n" % scenario.name for step in scenario.steps: source += u"\n".join(step.as_list()) + "\n" source += "\n" appendScenarios(story, source) for scenario in story.scenarios: # we must prepend scenarios level givens, whens and thens with # story level ones to support the behavior of corejet.testrunner scenario.givens = story.givens + scenario.givens scenario.whens = story.whens + scenario.whens scenario.thens = story.thens + scenario.thens return story.scenarios and story or None
def given(self): from corejet.core.model import RequirementsCatalogue, Epic, Story self.catalogue = RequirementsCatalogue( project="Test project", extractTime=datetime.datetime(2011, 1, 2, 12, 1, 0)) epic1 = Epic("E1", "First epic") self.catalogue.epics.append(epic1) epic2 = Epic("E2", "Second epic") self.catalogue.epics.append(epic2) story1 = Story("S1", "First story", points=3, status="open", priority="high", epic=epic1) epic1.stories.append(story1) story2 = Story("S2", "Second story", points=3, status="closed", resolution="fixed", priority="high", epic=epic1) epic1.stories.append(story2) text = """\ Scenario Outline: Count some apples Given I have <Start amount> apples When I get <Red> red and <Green> green apples more Then I have a total of <Sum> apples Examples: | Start amount | Red | Green | Sum | | 2 | 3 | 4 | 9 | | 3 | 4 | 5 | 12 | """ appendScenarios(story1, text)
def given(self): from corejet.core.model import RequirementsCatalogue, Epic, Story self.catalogue = RequirementsCatalogue(project="Test project", extractTime=datetime.datetime(2011, 1, 2, 12, 1, 0)) epic1 = Epic("E1", "First epic") self.catalogue.epics.append(epic1) story1 = Story("S1", "First story", points=3, status="open", priority="high", epic=epic1) epic1.stories.append(story1) text = u"""\ # language: fi Tapaus: RTFM suomeksi Oletetaan, että olen pulassa. Kun klikkaan "Ohjeet"-linkkiä, niin löydän apua. """ appendScenarios(story1, text)
def given(self): from corejet.core.model import RequirementsCatalogue, Epic, Story self.catalogue = RequirementsCatalogue(project="Test project", extractTime=datetime.datetime(2011, 1, 2, 12, 1, 0)) epic1 = Epic("E1", "First epic") self.catalogue.epics.append(epic1) story1 = Story("S1", "First story", points=3, status="open", priority="high", epic=epic1) epic1.stories.append(story1) text = u"""\ # language: fi Tapaus: Toinen tapaus Oletetaan, että olen 1. ja 2. korttelin välissä. Kun katson suoraan oikealle niin näen uuden kirjakaupan ja kauniin näyteikkunan. """ appendScenarios(story1, text)
def given(self): from corejet.core.model import RequirementsCatalogue, Epic, Story self.catalogue = RequirementsCatalogue(project="Test project", extractTime=datetime.datetime(2011, 1, 2, 12, 1, 0)) epic1 = Epic("E1", "First epic") self.catalogue.epics.append(epic1) story1 = Story("S1", "First story", points=3, status="open", priority="high", epic=epic1) epic1.stories.append(story1) text = u"""\ # language: fi Tapaus: Ensimmäinen tapaus Oletetaan, että ajan polkupyörällä, mutta minulla ei ole pyöräilykypärää. Kun törmään liikenteessä autoon, niin minulle käy tosi huonosti, mutta auton kuljettaja voi selvitä vammoitta. """ appendScenarios(story1, text)
def doPivotal(options, corejet_etree): try: pv = pivotal.Pivotal(options["token"], use_https=True) except TypeError: # Support HTTPS on pivotal_py == 0.1.3 pivotal.BASE_URL = "https://www.pivotaltracker.com/services/v3/" pv = pivotal.Pivotal(options["token"]) pivotal_project = pv.projects(options["project"]) pivotal_story_etrees = {} def get_pivotal_story_etree(story_id): if story_id in pivotal_story_etrees: story_etree = pivotal_story_etrees[story_id] else: story_etree = pivotal_project.stories(story_id).get_etree() pivotal_story_etrees[story_id] = story_etree return pivotal_story_etrees[story_id] incomplete_tasks_xpath = "tasks/task[contains(complete/text(), 'false')]" for scenario in corejet_etree.findall( "story/scenario[@testStatus='pass']"): story_id = scenario.getparent().get("id") task = None # A fake story is needed to parse exact scenario names tmp = Story("id", "name") story_etree = get_pivotal_story_etree(story_id) for node in story_etree.xpath(incomplete_tasks_xpath): appendScenarios(tmp, node.findtext("description")) # Expect only one scenario per task if tmp.scenarios\ and tmp.scenarios[-1].name == scenario.get("name"): task = node if task is not None: print (u"Completed task #%s for " u"https://www.pivotaltracker.com/story/show/%s") %\ (task.findtext("position"), story_id) task.find("complete").text = "true" url = pivotal_project.stories(story_id)\ .tasks(task.findtext("id")).url h = httplib2.Http(timeout=15) h.force_exception_to_status_code = True headers = { "X-TrackerToken": options["token"], "Content-Type": "application/xml" } h.request(url, "PUT", etree.tostring(task), headers=headers) if not story_etree.xpath(incomplete_tasks_xpath): print u"All tasks completed for #%s" % story_id for story in corejet_etree.findall("story"): # total_scenarios = len(story.findall("scenario")) passing_scenarios = story.findall("scenario[@testStatus='pass']") failing_scenarios = story.findall("scenario[@testStatus='fail']") pending_scenarios = story.findall("scenario[@testStatus='pending']") mismatch_scenarios = story.findall("scenario[@testStatus='mismatch']") if passing_scenarios and not (failing_scenarios or pending_scenarios or mismatch_scenarios): if story.get("requirementStatus") not in ["finished", "accepted", "rejected", "delivered"]: status = u"COMMIT" else: status = u"OK" elif (mismatch_scenarios or pending_scenarios) and story.get( "requirementStatus") in\ ["finished", "accepted", "rejected", "delivered"]: status = "REGRESSION" elif mismatch_scenarios or pending_scenarios: status = "UNSYNC" else: status = "FAIL" print ((u"#%s: passing %02d failing %02d outdated %02d " u"missing %02d status %s") % (story.get("id"), len(passing_scenarios), len(failing_scenarios), len(mismatch_scenarios), len(pending_scenarios), status) ).replace("00", "--") for scenario in pending_scenarios: print u"#%s: MISSING: Scenario: %s" %\ (story.get("id"), scenario.get("name")) for scenario in mismatch_scenarios: story = scenario.getparent() print u"#%s: OUTDATED: \"Scenario: %s\"" %\ (story.get("id"), scenario.get("name")) if mismatch_scenarios or pending_scenarios: print u"#%s: URI: https://www.pivotaltracker.com/story/show/%s" %\ (story.get("id"), story.get("id"))
def jiraSource(details): """Produce a CoreJet XML file from JIRA. The parameter should be a comma-separated string with the following parameters: username=<username> - username to use to connect password=<password> - password to use to connect url=<url> - url of JIRA instance project=<name> - project name filter=<id> - id of filter that returns stories pointsField=<id> - id of field containing story points epicField=<id> - id of field indicating epic for a story acceptanceCriteriaField=<id> - id of field containing acceptance criteria """ parameters = extractParameters(details) username = parameters["username"] password = parameters["password"] url = parameters["url"] projectName = parameters["project"] filterId = parameters["filter"] pointsFieldId = parameters["pointsfield"] epicFieldId = parameters["epicfield"] acFieldId = parameters["acceptancecriteriafield"] catalogue = RequirementsCatalogue(project=projectName, extractTime=datetime.now()) # Open web service connection wsdl = url + "/rpc/soap/jirasoapservice-v2?wsdl" client = Client(wsdl) # Log into JIRA print "Fetching repository from JIRA instance at", url securityToken = client.service.login(username, password) epicCache = {} statuses = {} resolutions = {} try: # Look up statuses and resolutions for status in client.service.getStatuses(securityToken): statuses[status.id] = status.name for resolution in client.service.getResolutions(securityToken): resolutions[resolution.id] = resolution.name # Fetch all issues issues = client.service.getIssuesFromFilter(securityToken, filterId) for issue in issues: story = Story(issue.key, issue.summary) try: story.points = int(singleValueCustomFieldForIssue(issue, pointsFieldId)) except (ValueError, TypeError): pass story.status = statuses.get(issue.status, None) story.resolution = resolutions.get(issue.resolution, None) epicName = singleValueCustomFieldForIssue(issue, epicFieldId) # See if this epic is a reference to an issue epic = epicCache.get(epicName, None) if epic is None: epicTitle = epicName try: epicIssue = client.service.getIssue(securityToken, epicName) epicTitle = epicIssue.summary except WebFault: # Can't find the issue? We use the epic name as its title pass # Create a new epic, cache it, and add it to the catalogue epicCache[epicName] = epic = Epic(epicName, epicTitle) catalogue.epics.append(epic) epic.stories.append(story) story.epic = epic acceptanceCriteria = singleValueCustomFieldForIssue(issue, acFieldId) try: appendScenarios(story, acceptanceCriteria) except ValueError, e: print "Error parsing acceptance criteria for", issue.key, "-", str(e) finally: client.service.logout(securityToken) return catalogue