Пример #1
0
def find_testcase_by_reference(ref):
    """Find a testcase by using the data in the testcase reference

    This method uses an iterative approach to the information in the reference.
    Meaning that it looks at each piece of data, in a particular order, and tries
    to find the testcase by that information.

    The order the properties are searched in are:
        1. testcaseId
        2. automationId
        3. automationKey
        4. name

    The automationTool property is not considered unique, so it is not used for
    finding the testcase.

    :param ref: The TestcaseReference object that will be used to try to find the Testcase
    :return: A slickqaweb.model.testcase.Testcase instance on success, None on failure
    """
    assert isinstance(ref, TestcaseReference)
    testcase = None
    if hasattr(ref, 'testcaseId') and ref.testcaseId is not None:
        testcase = Testcase.objects(id=ref.testcaseId).first()
    if testcase is None and hasattr(ref, 'automationId') and ref.automationId is not None and ref.automationId != '':
        testcase = Testcase.objects(automationId=ref.automationId).first()
    if testcase is None and hasattr(ref, 'automationKey') and ref.automationKey is not None and ref.automationKey != '':
        testcase = Testcase.objects(automationKey=ref.automationKey).first()
    if testcase is None and hasattr(ref, 'name') and ref.name is not None and ref.name != '':
        testcase = Testcase.objects(name=ref.name).first()

    return testcase
Пример #2
0
def get_testcase_by_id(testcase_id):
    """Retrieve a testcase by it's id."""
    return JsonResponse(Testcase.objects(id=testcase_id).first())
Пример #3
0
def update_testcase(testcase_id):
    """Update the properties of a testcase."""
    orig = Testcase.objects(id=testcase_id).first()
    deserialize_that(read_request(), orig)
    orig.save()
    return JsonResponse(orig)
Пример #4
0
def add_result(testrun_id=None):
    """Create a new result."""
    raw = read_request()
    new_result = deserialize_that(raw, Result())
    assert isinstance(new_result, Result)

    # validate --------------------------------------------------------------
    # you must have a testcase reference (some info about the testcase) and a
    # status for the result.  Otherwise it's not really a result.
    errors = []
    if is_not_provided(new_result, 'status'):
        errors.append("status must be set")
    if is_not_provided(new_result, 'testcase') or (is_not_provided(new_result.testcase, 'name') and
                                               is_not_provided(new_result.testcase, 'testcaseId') and
                                               is_not_provided(new_result.testcase, 'automationId') and
                                               is_not_provided(new_result.testcase, 'automationKey')):
        errors.append("testcase must be provided with at least one identifying piece of data")
    if len(errors) > 0:
        return Response('\r\n'.join(errors), status=400, mimetype="text/plain")

    # fill in defaults -------------------------------------------------------
    # a few fields can easily be inferred or set to a default

    if is_not_provided(new_result, 'runstatus'):
        if new_result.status == "NO_RESULT":
            new_result.runstatus = "TO_BE_RUN"
        else:
            new_result.runstatus = "FINISHED"
    if is_not_provided(new_result, 'recorded'):
        new_result.recorded = datetime.datetime.utcnow()

    # resolve references -----------------------------------------------------
    testrun = None
    project = None
    testcase = None
    release = None
    build = None
    component = None
    configuration = None

    if testrun_id is not None:
        testrun = Testrun.objects(id=testrun_id).first()
        if testrun is not None:
            new_result.testrun = create_testrun_reference(testrun)

    # the order in this section is important.  We try to find information any way we can,
    # so if it's not provided in the result, we look at the testrun, if it's not in the testrun,
    # but it is in the testcase we get it from there.

    # first lookup the testrun and resolve it if we can
    if is_provided(new_result, 'testrun') and testrun is None:
        testrun = find_testrun_by_reference(new_result.testrun)
        # don't create a new testrun if it's null, we'll do that later after we resolve the other
        # pieces of information

    # try to resolve the testcase, we won't try to create it if it's none yet.
    # for that we need to resolve as much of the other information we can.
    testcase = find_testcase_by_reference(new_result.testcase)

    # try to find the project from the data provided in the result.  If that doesn't work,
    # and we do have a testrun, see if we can get it from there.  If we do have a name of a
    # project and we still haven't found the project, create it!
    if is_provided(new_result, 'project'):
        project = find_project_by_reference(new_result.project)
        if project is None and testrun is not None and is_provided(testrun, 'project'):
            project = find_project_by_reference(testrun.project)
        if project is None and is_provided(new_result.project, 'name'):
            project = Project()
            project.name = new_result.project.name
            project.save()

    # if they didn't provide any project data, but did provide testrun data, try
    # to resolve the project from the testrun
    if project is None and testrun is not None and is_provided(testrun, 'project'):
        project = find_project_by_reference(testrun.project)

    # if we couldn't resolve the project previously, but we can resolve the testcase
    # see if we can get the project from the testcase
    if project is None and testcase is not None and is_provided(testcase, 'project'):
        project = find_project_by_reference(testcase.project)


    # finally, make sure that the reference we have in the result has all the info in it
    if project is not None:
        new_result.project = create_project_reference(project)

    # resolve the component
    if is_provided(new_result, 'component'):
        if project is not None:
            component = find_component_by_reference(project, new_result.component)
            if component is None:
                component = Component()
                component.id = ObjectId()
                component.name = new_result.component.name
                if is_provided(new_result.component, 'code'):
                    component.code = new_result.component.code
                else:
                    component.code = component.name.lower().replace(' ', '-')
                project.components.append(component)
                project.save()
    if component is not None:
        new_result.component = create_component_reference(component)

    # create a testcase if needed
    if testcase is None and is_not_provided(new_result.testcase, 'name'):
        return Response('Existing testcase not found, please provide a testcase name if you want one to be created.\n', status=400, mimetype="text/plain")
    elif testcase is None:
        testcase = Testcase()
        testcase.created = datetime.datetime.utcnow()
        testcase.name = new_result.testcase.name
        if is_provided(new_result.testcase, 'automationId'):
            testcase.automationId = new_result.testcase.automationId
        if is_provided(new_result.testcase, 'automationKey'):
            testcase.automationKey = new_result.testcase.automationKey
        if project is not None:
            testcase.project = create_project_reference(project)
        if component is not None:
            testcase.component = create_component_reference(component)
        testcase.save()
    testcase_changed = False
    if 'steps' in raw['testcase']:
        testcase.steps = []
        for raw_step in raw['testcase']['steps']:
            step = deserialize_that(raw_step, Step())
            testcase.steps.append(step)
        testcase_changed = True
    if 'purpose' in raw['testcase']:
        testcase.purpose = raw['testcase']['purpose']
        testcase_changed = True
    if 'requirements' in raw['testcase']:
        testcase.requirements = raw['testcase']['requirements']
        testcase_changed = True
    if 'author' in raw['testcase']:
        testcase.author = raw['testcase']['author']
        testcase_changed = True
    # TODO: feature and automationTool

    if testcase_changed:
        testcase.save()

    # no matter what testcase should not be None at this point, but just in case I made a mistake
    if testcase is None:
        return Response('Somehow I was unable to find or create a testcase for this result.\n', status=400, mimetype="text/plain")
    new_result.testcase = create_testcase_reference(testcase)

    # dereference release and build if possible
    if is_provided(new_result, 'release') and project is not None:
        release = find_release_by_reference(project, new_result.release)
    if release is None and testrun is not None and project is not None and is_provided(testrun, 'release'):
        release = find_release_by_reference(project, testrun.release)
    if release is None and project is not None and is_provided(new_result, 'release') and is_provided(new_result.release, 'name'):
        release = Release()
        release.id = ObjectId()
        release.name = new_result.release.name
        project.releases.append(release)
        project.save()
    if release is not None:
        new_result.release = create_release_reference(release)
        if is_provided(new_result, 'build'):
            build = find_build_by_reference(release, new_result.build)
        if build is None and testrun is not None and is_provided(testrun, 'build'):
            build = find_build_by_reference(release, testrun.build)
        if build is None and project is not None and is_provided(new_result, 'build') and is_provided(new_result.build, 'name'):
            build = Build()
            build.id = ObjectId()
            build.name = new_result.build.name
            build.built = datetime.datetime.utcnow()
            release.builds.append(build)
            project.save()
        if build is not None:
            new_result.build = create_build_reference(build)

    # dereference configuration
    if is_provided(new_result, 'config'):
        configuration = find_configuration_by_reference(new_result.config)
    if configuration is None and testrun is not None and is_provided(testrun, 'config'):
        configuration = find_configuration_by_reference(testrun.config)
    if configuration is None and is_provided(new_result, 'config') and is_provided(new_result.config, 'name'):
        configuration = Configuration()
        configuration.name = new_result.config.name
        if is_provided(new_result.config, 'filename'):
            configuration.filename = new_result.config.filename
        configuration.save()
    if configuration is not None:
        new_result.config = create_configuration_reference(configuration)

    # if there is no testrun, create one with the information provided
    if testrun is None:
        testrun = Testrun()
        if is_provided(new_result, 'testrun') and is_provided(new_result.testrun, 'name'):
            testrun.name = new_result.testrun.name
        else:
            testrun.name = 'Testrun starting %s' % str(datetime.datetime.utcnow())
        if project is not None:
            testrun.project = create_project_reference(project)
        if configuration is not None:
            testrun.config = create_configuration_reference(configuration)
        if release is not None:
            testrun.release = create_release_reference(release)
        if build is not None:
            testrun.build = create_build_reference(build)
        testrun.dateCreated = datetime.datetime.utcnow()
        testrun.runStarted = datetime.datetime.utcnow()
        testrun.state = 'RUNNING'
        testrun.save()

    if testrun is not None:
        new_result.testrun = create_testrun_reference(testrun)

        status_name = "inc__summary__resultsByStatus__" + new_result.status
        Testrun.objects(id=testrun.id).update_one(**{status_name: 1})

    apply_triage_notes(new_result, testcase)
    new_result.history, estimatedRuntime = find_history(new_result)
    if new_result.attributes is None:
        new_result.attributes = {}
    new_result.attributes['estimatedRuntime'] = str(estimatedRuntime)
    new_result.save()

    events.CreateEvent(new_result)
    return JsonResponse(new_result)