自動化測試平臺設計與實現(三、自動化用例物件成為可執行檔案,用例執行機的設計與實現、用例除錯)

jpx發表於2024-08-08

1、將資料庫內自動化用例相關資訊讀取出來,生成可執行(測試)檔案

透過之前的設計,我們實現了在平臺上,增刪改查用例、關鍵字、斷言等操作。但最終資料庫中用例的資料,要組合成可執行檔案,來進行測試活動。

我們需要設計一個方法,輸入project name, testcase title,定位唯一的testcase,然後透過testcase、TestCaseKeyword、assertion,這些是組成一個http請求測試的充分必要元素。然後把這個寫到當前目錄的新py檔案,檔名就是project_name和title的拼接。構建一個可執行的python檔案,執行python檔案內的函式,我們就得到本次測試的結果。

回顧通常的python測試指令碼,它一般有:

import requests
import json

def projectA_testcase1():

    # step1: 有幾步keyword,就有幾個step註釋
    url = "example.com"
    headers = {'Content-Type': 'application/json'}
    data = {
        "name": "abc",
        "email": "abc@example.com"
    }
    response = requests.post(url, data=json.dumps(data), headers=headers)

    assert response.status_code == 200
    assert response.message == "success"

而這個測試指令碼需要的元素,剛好儲存在我們的資料庫內。我們讀取資料庫,傳遞project和testcase title,拿到需要的資訊,然後生成測試檔案。

import os
import json
import django
from django.core.exceptions import ValidationError

# 設定 Django 環境
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'TestBench.settings')  # 修改為您的 settings 模組路徑
django.setup()

from testplatform.models import Project, Testcase, TestCaseKeyword, Assertion

def create_test_script(project_name, testcase_title):
    try:
        project = Project.objects.get(name=project_name)
    except Project.DoesNotExist:
        raise ValidationError(f"Project '{project_name}' not found")

    try:
        testcase = Testcase.objects.get(project=project, title=testcase_title)
    except Testcase.DoesNotExist:
        raise ValidationError(f"Testcase with title '{testcase_title}' not found in project '{project_name}'")

    testcase_keywords = TestCaseKeyword.objects.filter(test_case=testcase)
    steps = []
    for tk in testcase_keywords:
        assertions = Assertion.objects.filter(testcase_keyword=tk).values('target_value', 'operator', 'compared_value')
        steps.append({
            'url': tk.url,
            'method': tk.method,
            'params': tk.params,
            'headers': tk.headers,
            'body_type': tk.body_type,
            'body': tk.body,
            'assertions': list(assertions)
        })

    # 生成檔案內容
    script_content = f"""
import requests
import json

def {project_name}_{testcase_title}():

"""
    for i, step in enumerate(steps, start=1):
        script_content += f"""
    # step{i}: 執行請求並驗證斷言
    url = "{step['url']}"
    method = "{step['method']}"
    params = {step['params']}
    headers = {step['headers']}
    body = {step['body']}

"""
        if step['body_type'] == "application/x-www-form-urlencoded":
            script_content += f"""
    response = requests.request(method, url, params=params, headers=headers, data=body)
"""
        else:
            script_content += f"""
    response = requests.request(method, url, params=params, headers=headers, json=json.dumps(body))
"""
        for assertion in step['assertions']:
            target_value = assertion['target_value']
            operator = assertion['operator']
            compared_value = assertion['compared_value']
            if operator == 'greater_than':
                script_content += f"    assert {target_value} > {compared_value}\n"
            elif operator == 'less_than':
                script_content += f"    assert {target_value} < {compared_value}\n"
            elif operator == 'equal':
                script_content += f"    assert {target_value} == {compared_value}\n"
            elif operator == 'greater_than_or_equal':
                script_content += f"    assert {target_value} >= {compared_value}\n"
            elif operator == 'less_than_or_equal':
                script_content += f"    assert {target_value} <= {compared_value}\n"
            elif operator == 'equal_to':
                script_content += f"    assert '{compared_value}' in {target_value}\n"
            elif operator == 'contains':
                script_content += f"    assert '{compared_value}' in {target_value}\n"
            elif operator == 'in':
                script_content += f"    assert {target_value} in '{compared_value}'\n"

    script_content += f"""
if __name__ == "__main__":
    {project_name}_{testcase_title}()
"""

    # 檔名
    file_name = f"{project_name}_{testcase_title}.py"
    # 上一級目錄的casefile資料夾路徑
    casefile_dir = os.path.join(os.path.dirname(os.getcwd()), 'casefile')
    # 確保casefile資料夾存在
    os.makedirs(casefile_dir, exist_ok=True)
    # 完整的檔案路徑
    file_path = os.path.join(casefile_dir, file_name)

    # 寫入檔案
    with open(file_path, 'w', encoding='utf-8') as file:
        file.write(script_content)

    print(f"Test script written to {file_path}")


if __name__ == '__main__':
    create_test_script(project_name="Project B", testcase_title="autocase0807_001")

相關文章