Beispiel #1
0
 def add_case_suite_name(_case_info):
     _case_suite_id = _case_info.get('caseSuiteId')
     try:
         case_suite_name = CaseSuite.find_one({'_id': _case_suite_id})['name'] \
             if CaseSuite.find_one({'_id': _case_suite_id}) else ''
         _case_info['caseSuiteName'] = case_suite_name if case_suite_name else ''
     except BaseException as e:
         print(e)
     return _case_info
def add_case_suite(project_id):
    request_data = request.get_json()
    request_data["status"] = True
    request_data["projectId"] = ObjectId(project_id)
    request_data["lastUpdateTime"] = datetime.datetime.utcnow()
    request_data["createAt"] = datetime.datetime.utcnow()

    try:
        filtered_data = CaseSuite.filter_field(request.get_json(),
                                               use_set_default=True)
        CaseSuite.insert(filtered_data)
        return jsonify({'status': 'ok', 'data': '添加成功'})
    except BaseException as e:
        return jsonify({'status': 'failed', 'data': '添加失败 %s' % e})
Beispiel #3
0
    def get_cron_test_cases_list(self):
        if not self.is_execute_forbiddened_case:
            for case_suite_id in self.test_case_suite_id_list:
                is_forbiddened_case_suite = len(list(CaseSuite.find({'_id': ObjectId(case_suite_id),
                                                                     'status': {'$ne': True}}))) > 0
                if is_forbiddened_case_suite:
                    self.test_case_suite_id_list.remove(case_suite_id)

        query = {'isDeleted': {'$ne': True}} if self.is_execute_forbiddened_case\
            else {'isDeleted': {'$ne': True}, 'status': True}
        test_cases = [testing_case for testing_case in TestingCase.find(query).sort([('caseSuiteId', pymongo.ASCENDING),
                                                                                     ('createAt', pymongo.ASCENDING)])]

        cron_test_cases_from_case_suite_id = filter(lambda x: str(x.get('caseSuiteId')) in self.test_case_suite_id_list,
                                                    test_cases)
        cron_test_cases_from_case_id = filter(lambda x: str(x.get('_id')) in self.test_case_id_list, test_cases)

        cron_test_cases_list = list(cron_test_cases_from_case_suite_id) + list(cron_test_cases_from_case_id)

        def remove_duplicated_case(case_list):
            id_list = []
            for case in case_list:
                case_id = case["_id"]
                if case_id in id_list:
                    case_list.remove(case)
                else:
                    id_list.append(case_id)
            return case_list

        return remove_duplicated_case(cron_test_cases_list)
def update_case_suite(project_id, case_suite_id):
    try:
        filtered_data = CaseSuite.filter_field(request.get_json())
        for key, value in filtered_data.items():
            CaseSuite.update({"_id": ObjectId(case_suite_id)},
                             {'$set': {
                                 key: value
                             }})
        update_response = CaseSuite.update(
            {"_id": ObjectId(case_suite_id)},
            {'$set': {
                'lastUpdateTime': datetime.datetime.utcnow()
            }},
        )
        if update_response["n"] == 0:
            return jsonify({'status': 'failed', 'data': '未找到相应更新数据!'})
        return jsonify({'status': 'ok', 'data': '更新成功'})
    except BaseException as e:
        return jsonify({'status': 'failed', 'data': '更新失败: %s' % e})
 def get_new_create_at(create_at):
     time_quantity = 1
     while True:
         new_create_at = create_at - datetime.timedelta(
             milliseconds=time_quantity)
         find_result = list(CaseSuite.find({'createAt': new_create_at}))
         has_identical_create_at_case_suite = True if len(
             find_result) > 0 else False
         if not has_identical_create_at_case_suite:
             return new_create_at
         else:
             time_quantity += 1
def import_test_cases():
    file = request.files.get('file')
    request_data = request.form
    case_suite_id = request_data.get('caseSuiteId') if request_data else None
    project_id = request_data.get('projectId') if request_data else None
    current_user_name = request_data.get('userName') if request_data else None

    if file is None or project_id is None or current_user_name is None:
        return jsonify({'status': 'failed', 'data': '参数不合法!值为: None'})

    if case_suite_id == 'undefined' or project_id == 'undefined' or current_user_name == 'undefined':
        return jsonify({'status': 'failed', 'data': '参数不合法!值为: undefined'})

    try:
        file_content = file.read()
        workbook = xlrd.open_workbook(file_contents=file_content)
    except BaseException as e:
        return jsonify({'status': 'failed', 'data': '「Excel」读取失败! %s' % e})

    if '测试用例' not in workbook.sheet_names():
        return jsonify({'status': 'failed', 'data': '「Excel」缺失「测试用例」Sheet'})

    test_case_table = workbook.sheet_by_name('测试用例')
    rows_num = test_case_table.nrows  # 获取该sheet中的有效行数

    if rows_num < 2:
        return jsonify({
            'status': 'failed',
            'data': '「测试用例」Sheet 有效行数小于两行: %s 行' % rows_num
        })

    test_case_attributes = test_case_table.row_values(0)

    non_intersection = list(
        set(test_case_map.values()) ^ set(test_case_attributes))
    if non_intersection:
        missing_attributes = [
            nip for nip in non_intersection if nip in test_case_map.values()
        ]
        return jsonify({'status': 'failed', 'data': '「测试用例」Sheet 表头缺失字段: %s' % missing_attributes}) \
            if missing_attributes else jsonify({'status': 'failed', 'data': '「测试用例」Sheet 表头存在多余字段: %s' %
                                               [nip for nip in non_intersection if nip not in test_case_map.values()]})

    attributes_indexes = [
        test_case_attributes.index(v) for v in test_case_map.values()
    ]

    def get_pre_import_case_info(case_info, test_case_mapping,
                                 table_row_index):
        _is_case_exist, _case_info, _is_case_suite_exist = \
            common.validate_and_pre_process_import_test_case(CaseSuite, TestingCase, case_info,
                                                             test_case_mapping, table_row_index)
        return _is_case_exist, _case_info, _is_case_suite_exist

    results = []
    import_count = 0
    update_count = 0
    test_case_info = copy.deepcopy(test_case_map)
    for i in range(rows_num - 1):
        for j, v in enumerate(test_case_info.keys()):
            test_case_info[v] = test_case_table.row_values(i + 1)[
                attributes_indexes[j]]
        try:
            is_case_exist, pre_import_case_info, is_case_suite_exist\
                = get_pre_import_case_info(test_case_info, test_case_mapping=test_case_map, table_row_index=(i+2))
        except BaseException as b_e:
            return jsonify({'status': 'failed', 'data': '导入数据异常: %s' % b_e})

        try:
            # 在接口用例列表中导入
            if case_suite_id:
                if is_case_exist and str(
                        pre_import_case_info.get('caseSuiteId')) == str(
                            case_suite_id):
                    pre_import_case_info = TestingCase.filter_field(
                        pre_import_case_info, use_set_default=False)
                    result = str(TestingCase.update({"_id": ObjectId(pre_import_case_info.get('_id'))},
                                                    {'$set': pre_import_case_info})) + \
                                                     ' _id: {}'.format(pre_import_case_info.get('_id'))
                    update_count += 1
                else:
                    try:
                        pre_import_case_info.pop('_id')
                    except BaseException:
                        pass
                    pre_import_case_info['status'] = True
                    pre_import_case_info['caseSuiteId'] = ObjectId(
                        case_suite_id)
                    pre_import_case_info['projectId'] = ObjectId(project_id)
                    pre_import_case_info['creatorNickName'] = current_user_name
                    pre_import_case_info[
                        'lastUpdatorNickName'] = current_user_name
                    pre_import_case_info = TestingCase.filter_field(
                        pre_import_case_info, use_set_default=True)
                    result = TestingCase.insert(pre_import_case_info)
                    import_count += 1
            # 在用例列表内导入
            else:
                inserted_case_suite_id = None
                case_suite_name = pre_import_case_info.get('caseSuiteName')\
                    if pre_import_case_info.get('caseSuiteName') else ''
                if is_case_suite_exist:
                    if not case_suite_name == CaseSuite.find_one({
                            "_id":
                            ObjectId(pre_import_case_info.get('caseSuiteId'))
                    })['name']:
                        CaseSuite.update(
                            {
                                "_id":
                                ObjectId(
                                    pre_import_case_info.get('caseSuiteId'))
                            }, {'$set': {
                                'name': case_suite_name
                            }})
                    else:
                        pass
                else:
                    insert_data = dict()
                    insert_data["name"] = case_suite_name
                    insert_data["status"] = True
                    insert_data["projectId"] = ObjectId(project_id)
                    insert_data["lastUpdateTime"] = datetime.datetime.utcnow()
                    insert_data["createAt"] = datetime.datetime.utcnow()
                    insert_data["creatorNickName"] = current_user_name
                    insert_data["lastUpdatorNickName"] = current_user_name
                    inserted_case_suite_id = CaseSuite.insert(insert_data)

                if inserted_case_suite_id:
                    pre_import_case_info.pop('_id') if is_case_exist else None
                    pre_import_case_info["projectId"] = ObjectId(project_id)
                    pre_import_case_info['caseSuiteId'] = ObjectId(
                        inserted_case_suite_id)
                    pre_import_case_info = TestingCase.filter_field(
                        pre_import_case_info, use_set_default=True)
                    result = TestingCase.insert(pre_import_case_info)
                    import_count += 1

                else:
                    if is_case_exist:
                        pre_import_case_info = TestingCase.filter_field(
                            pre_import_case_info, use_set_default=False)
                        result = str(TestingCase.update({"_id": ObjectId(pre_import_case_info.get('_id'))},
                                                        {'$set': pre_import_case_info})) + ' _id: {}'\
                            .format(pre_import_case_info.get('_id'))

                        update_count += 1
                    else:
                        pre_import_case_info["projectId"] = ObjectId(
                            project_id)
                        pre_import_case_info['caseSuiteId'] = ObjectId(
                            pre_import_case_info.get('caseSuiteId'))
                        pre_import_case_info = TestingCase.filter_field(
                            pre_import_case_info, use_set_default=True)
                        result = TestingCase.insert(pre_import_case_info)
                        import_count += 1

            results.append(result)
        except BaseException as e:
            return jsonify({'status': 'failed', 'data': '数据导入异常: %s' % e})

    def get_returned_data(_results, _import_count, _update_count):
        _returned_data = dict()
        _returned_data['status'] = 'ok'
        if import_count > 0 and update_count == 0:
            _returned_data['data'] = '操作成功, 共成功导入 %s 条用例' % _import_count
            # _returned_data['log'] = '导入数据_id: %s' % _results
        elif update_count > 0 and import_count == 0:
            _returned_data['data'] = '操作成功, 共成功覆盖 %s 条用例' % _update_count
            # _returned_data['log'] = '导入数据_id: %s' % _results
        elif import_count > 0 and update_count > 0:
            _returned_data['data'] = '操作成功, 共成功导入 %s 条用例、覆盖 %s 条用例' % (
                import_count, update_count)
            # _returned_data['log'] = '导入数据_id: %s' % _results
        else:
            _returned_data['data'] = '操作成功,但啥都没导入 / 覆盖'
            # _returned_data['log'] = None
        return jsonify(_returned_data)

    returned_data = get_returned_data(results, import_count, update_count)
    return returned_data
def start_test():
    # TODO 性能优化
    from testframe.interfaceTest.tester import tester
    request_data = request.get_json()
    case_suite_id_list = None
    case_id_list = None
    executor_nick_name = None
    execution_mode = None
    is_single_test = None

    if 'domain' not in request_data:
        return jsonify({'status': 'failed', 'data': '缺失domain字段!'})
    else:
        domain = request_data["domain"]

    if 'caseSuiteIdList' in request_data:
        case_suite_id_list = request_data["caseSuiteIdList"]

    if 'caseIdList' in request_data:
        case_id_list = request_data["caseIdList"]

    if 'executorNickName' in request_data:
        executor_nick_name = request_data["executorNickName"]

    if 'executionMode' in request_data:
        execution_mode = request_data["executionMode"]

    testing_case_list = []
    testing_cases = copy.deepcopy(
        TestingCase.find({
            'isDeleted': {
                '$ne': True
            },
            'status': True
        })  # sort吃顺序
        .sort([('caseSuiteId', pymongo.ASCENDING),
               ('createAt', pymongo.ASCENDING)]))

    if case_suite_id_list:
        for case_suite_id in case_suite_id_list:
            is_forbiddened_case_suite = len(
                list(
                    CaseSuite.find({
                        '_id': ObjectId(case_suite_id),
                        'status': {
                            '$ne': True
                        }
                    }))) > 0
            if is_forbiddened_case_suite:
                return jsonify({'status': 'failed', 'data': '请先「启用」测试用例'})

        for testing_case in testing_cases:
            if "caseSuiteId" in testing_case and str(
                    testing_case["caseSuiteId"]) in case_suite_id_list:
                testing_case_list.append(testing_case)

    if not case_id_list and len(testing_case_list) < 1:
        return jsonify({
            'status': 'failed',
            'data': '未在「测试用例」中找到任何「启用的」接口测试用例'
        })

    testing_cases = copy.deepcopy(
        TestingCase.find({
            'isDeleted': {
                '$ne': True
            },
            'status': True
        })  # sort吃顺序
        .sort([('caseSuiteId', pymongo.ASCENDING),
               ('createAt', pymongo.ASCENDING)]))  # 再次初始化 Cursor object
    if case_id_list:
        for testing_case in testing_cases:
            if str(testing_case["_id"]) in case_id_list:
                testing_case_list.append(testing_case)

    if len(testing_case_list) > 0:
        project_id = testing_case_list[0]["projectId"]
        project_name = Project.find_one({'_id': ObjectId(project_id)})['name']
    else:
        return jsonify({'status': 'failed', 'data': '请先「启用」接口测试用例'})

    # 去除相同的测试用例
    def remove_duplicated_case(case_list):
        id_list = []
        for case in case_list:
            case_id = case["_id"]
            if case_id in id_list:
                case_list.remove(case)
            else:
                id_list.append(case_id)
        return case_list

    testing_case_list = remove_duplicated_case(testing_case_list)

    if 'caseSuiteIdList' not in request_data and len(testing_case_list) == 1:
        is_single_test = True

    tester = tester(test_case_list=testing_case_list, domain=domain)

    if not is_single_test:
        try:
            tester.execute_all_test_and_send_report(TestingCase, TestReport,
                                                    project_id,
                                                    executor_nick_name,
                                                    execution_mode,
                                                    project_name)
            return jsonify({'status': 'ok', 'data': '测试已启动,稍后请留意自动化测试报告'})
        except BaseException as e:
            return jsonify({'status': 'failed', 'data': '测试启动失败: %s' % e})
    else:
        # TODO 单个接口测试需要返回测试结果,使用同步方法, 需重构
        test_result_list = tester.execute_all_test_for_cron_and_single_test()
        for index, test_result in enumerate(test_result_list):
            test_case_id = test_result["_id"]
            test_result = common.format_response_in_dic(test_result)
            test_result_list[index] = test_result
            TestingCase.update({"_id": ObjectId(test_case_id)},
                               {'$set': {
                                   'lastManualTestResult': test_result
                               }})
        test_count = len(test_result_list)
        passed_count = len(
            list(
                filter(lambda x: x == 'ok', [
                    test_result["status"] for test_result in test_result_list
                ])))
        failed_count = len(
            list(
                filter(lambda x: x == 'failed', [
                    test_result["status"] for test_result in test_result_list
                ])))
        passed_rate = '%d' % round((passed_count / test_count) * 100, 2) + '%'

        if test_count > 0:
            for test_result in test_result_list:
                if 'testBaseInfo' in test_result and 'lastManualTestResult' in test_result[
                        'testBaseInfo']:
                    test_result['testBaseInfo'].pop('lastManualTestResult')

            raw_data = {
                "projectId":
                ObjectId(project_id),
                "projectName":
                project_name,
                "testCount":
                test_count,
                "passCount":
                passed_count,
                "failedCount":
                failed_count,
                "passRate":
                passed_rate,
                "comeFrom":
                execution_mode,
                "executorNickName":
                executor_nick_name,
                "totalTestSpendingTimeInSec":
                test_result_list[0]['spendingTimeInSec'],
                "testDomain":
                domain,
                "testDetail":
                test_result_list,
                "createAt":
                datetime.datetime.utcnow()
            }
            filtered_data = TestReport.filter_field(raw_data,
                                                    use_set_default=True)
            TestReport.insert(filtered_data)

        return jsonify({'status': 'ok', 'data': test_result_list})
def copy_case_suite(project_id, case_suite_id):
    try:
        test_case_suite = list(CaseSuite.find({'_id':
                                               ObjectId(case_suite_id)}))[0]
        test_case_suite['originCaseSuiteIds'] = [] if 'originCaseSuiteIds' not in test_case_suite \
            else test_case_suite['originCaseSuiteIds']
        origin_case_suite_id_info = dict()
        origin_case_suite_id_info['_id'] = test_case_suite.pop(
            '_id') if test_case_suite.get('_id') else None
        origin_case_suite_id_info['copiedAt'] = datetime.datetime.utcnow()
        test_case_suite['originCaseSuiteIds'].append(origin_case_suite_id_info)

        def get_new_create_at(create_at):
            time_quantity = 1
            while True:
                new_create_at = create_at - datetime.timedelta(
                    milliseconds=time_quantity)
                find_result = list(CaseSuite.find({'createAt': new_create_at}))
                has_identical_create_at_case_suite = True if len(
                    find_result) > 0 else False
                if not has_identical_create_at_case_suite:
                    return new_create_at
                else:
                    time_quantity += 1

        case_suite_create_at = test_case_suite.get('createAt')
        new_case_suite_create_at = get_new_create_at(
            case_suite_create_at)  # 超前插入,精髓
        new_case_suite_suffix = '(复制版)'
        case_suite_name = test_case_suite.pop('name') + new_case_suite_suffix \
            if 'name' in test_case_suite else '未知用例组' + new_case_suite_suffix
        test_case_suite['createAt'] = new_case_suite_create_at
        test_case_suite['name'] = case_suite_name
        new_case_suite_id = CaseSuite.insert(test_case_suite)

        query = {
            'caseSuiteId': ObjectId(case_suite_id),
            'isDeleted': {
                '$ne': True
            }
        }
        test_cases = list(TestingCase.find(query))

        def substitute_info(testing_case):
            testing_case['originTestingCaseIds'] = [] if 'originTestingCaseIds' not in testing_case \
                else testing_case['originTestingCaseIds']
            origin_testing_case_id_info = dict()
            origin_testing_case_id_info['_id'] = testing_case.pop(
                '_id') if testing_case.get('_id') else None
            origin_testing_case_id_info['copiedAt'] = datetime.datetime.utcnow(
            )
            testing_case['originTestingCaseIds'].append(
                origin_testing_case_id_info)
            testing_case['caseSuiteId'] = new_case_suite_id
            return testing_case

        substituted_test_cases = list(map(substitute_info, test_cases))
        for substituted_test_case in substituted_test_cases:
            TestingCase.insert(substituted_test_case)
        return jsonify({'status': 'ok', 'data': '复制成功'})
    except BaseException as e:
        return jsonify({'status': 'failed', 'data': '复制失败 %s' % e})