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
def get_testcase_by_id(testcase_id): """Retrieve a testcase by it's id.""" return JsonResponse(Testcase.objects(id=testcase_id).first())
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)
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)