예제 #1
0
        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)
예제 #2
0
        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)
예제 #3
0
        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)
예제 #4
0
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)))
예제 #5
0
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
예제 #6
0
        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)
예제 #7
0
        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)
예제 #8
0
        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)
예제 #9
0
        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)
예제 #10
0
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"))
예제 #11
0
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