TNR campaigns via API

alexandreR
Messages : 14
Inscription : lun. avr. 08, 2024 4:30 pm

TNR campaigns via API

Message par alexandreR »

Bonjour,

J'essaye de lancer en différer une itération d'une campagne TNR.

Mais je bloque sur l'éxécutions de la suite de tests.

Code : Tout sélectionner

# ---------------------------------------------------
# RÉCUPÉRATION DU TEST PLAN D’UNE CAMPAGNE
# ---------------------------------------------------

def get_campaign_test_plan(client: SquashClient, campaign_id: int) -> list[dict]:
    data, status = client.get_json(f"/campaigns/{campaign_id}/test-plan")
    if status != 200 or not data:
        logger.warning(f"Impossible de récupérer le test plan de la campagne {campaign_id} (status {status})")
        return []
    return data.get("_embedded", {}).get("campaign-test-plan-items", [])


# ---------------------------------------------------
# AJOUT DES TESTS À UNE ITÉRATION
# ---------------------------------------------------

def add_test_to_iteration(client: SquashClient, iteration_id: int, tc_id: int, dataset_id=None):
    payload = {
        "_type": "test-plan-item",
        "test_case": {"_type": "test-case", "id": tc_id}
    }
    if dataset_id:
        payload["dataset"] = {"_type": "dataset", "id": dataset_id}

    return client.post(f"/iterations/{iteration_id}/test-plan", json=payload)


def add_tests_to_iteration(client: SquashClient, iteration_id: int, test_plan: list[dict]) -> list[str]:
    iteration_item_ids = []
    for item in test_plan:
        tc = item.get("referenced_test_case", {})
        tc_id = tc.get("id")
        dataset = item.get("referenced_dataset")
        dataset_id = dataset.get("id") if dataset else None

        resp = add_test_to_iteration(client, iteration_id, tc_id, dataset_id)
        status_code = getattr(resp, "status_code", 0)
        if status_code in (200, 201):
            iteration_item_id = resp.json().get("id")
            iteration_item_ids.append(str(iteration_item_id))
            logger.info(f"Test ajouté à l'itération : test_case_id={tc_id}, iteration_item_id={iteration_item_id}")
        else:
            logger.error(f"Erreur ajout test {tc_id} : {status_code}, content={getattr(resp, 'content', None)}")
    return iteration_item_ids


# ---------------------------------------------------
# CRÉATION AUTOMATED SUITE
# ---------------------------------------------------

def create_automated_suite(client: SquashClient, iteration_id: int) -> Optional[str]:
    resp = client.post(f"/automated-suite-utils/from-iteration?iterationId={iteration_id}")
    status_code = getattr(resp, "status_code", 0)
    if status_code != 201:
        logger.error(f"Automated suite non créée ({status_code}), content={getattr(resp, 'content', None)}")
        return None
    suite_id = resp.json().get("id")
    logger.info(f"Automated suite créée : {suite_id}")
    return suite_id


# ---------------------------------------------------
# EXÉCUTION AUTOMATED SUITE
# ---------------------------------------------------

def execute_automated_suite(client: SquashClient, suite_id: str, tech_id: int = 13, tag: str = "Playwright") -> Optional[dict]:
    """
    Exécute une automated suite en précisant la technologie et les tags.

    :param client: SquashClient
    :param suite_id: ID de l'automated suite
    :param tech_id: ID de la technologie automatisée (Playwright par défaut)
    :param tag: Tag à utiliser pour filtrer les agents
    :return: dictionnaire d'exécution réelle ou None si échec
    """

    payload = {
        "technology": {"_type": "automated-test-technology", "id": tech_id},
        "tags": [tag]
    }

    resp = client.post(f"/automated-suite-utils/{suite_id}/executor", json=payload)
    status_code = getattr(resp, "status_code", "unknown")
    content = getattr(resp, "content", None)
    logger.info(f"Réponse brute exécution : status_code={status_code}, content={content}")

    if status_code != 200:
        logger.error(f"Échec de l'exécution de la suite {suite_id} ({status_code})")
        return None

    suite_execution = resp.json()
    # Vérification : Squash peut renvoyer la suite ou directement l'exécution
    exec_id = suite_execution.get("id")  # l'ID réel de l'exécution devrait être ici
    logger.info(f"Exécution lancée pour la suite {suite_id}, execution_id={exec_id}")

    return suite_execution

# ---------------------------------------------------
# RUN COMPLETE D'UNE CAMPAGNE (TNR)
# ---------------------------------------------------

def run_campaign(client: SquashClient, campaign_id: int, tag: str = "Playwright") -> dict:
    result = {
        "campaign_id": campaign_id,
        "iteration_id": None,
        "tests_added": 0,
        "iteration_item_ids": [],
        "automated_suite_id": None,
        "execution": None,
        "error": None,
    }

    # 1) Création de l’itération
    now_str = datetime.now().strftime("%Y-%m-%dT%H:%M:%S")
    iteration_payload = {
        "_type": "iteration",
        "name": f"TNR {now_str}",
        "description": f"Itération automatique pour {tag} le {now_str}",
        "parent": {"_type": "campaign", "id": campaign_id},
        "actual_start_auto": True,
        "actual_end_auto": True
    }
    iter_resp = client.post(f"/campaigns/{campaign_id}/iterations", json=iteration_payload)
    if getattr(iter_resp, "status_code", 0) != 201:
        result["error"] = f"Impossible de créer l'itération ({getattr(iter_resp, 'status_code', 0)})"
        logger.error(result["error"])
        return result

    iteration_id = iter_resp.json().get("id")
    result["iteration_id"] = iteration_id
    logger.info(f"Itération créée : {iteration_id}")

    # 2) Ajout des tests
    test_plan = get_campaign_test_plan(client, campaign_id)
    iteration_item_ids = add_tests_to_iteration(client, iteration_id, test_plan)
    if not iteration_item_ids:
        result["error"] = "Aucun test n'a été ajouté à l'itération."
        return result
    result["tests_added"] = len(iteration_item_ids)
    result["iteration_item_ids"] = iteration_item_ids

    # 3) Création automated suite
    suite_id = create_automated_suite(client, iteration_id)
    if not suite_id:
        result["error"] = "Automated suite non créée"
        return result
    result["automated_suite_id"] = suite_id

    # 4) Exécution
    execution_data = execute_automated_suite(client, suite_id, tag)
    if execution_data is None:
        result["error"] = "Échec de l'exécution"
        return result
    result["execution"] = execution_data

    return result
Pour mes retours ils m'envoie que tout est bon :

Code : Tout sélectionner

INFO:squash_api.campaigns:Itération créée : 91
INFO:squash_api.campaigns:Test ajouté à l'itération : test_case_id=649, iteration_item_id=241
INFO:squash_api.campaigns:Test ajouté à l'itération : test_case_id=649, iteration_item_id=242
INFO:squash_api.campaigns:Test ajouté à l'itération : test_case_id=649, iteration_item_id=243
INFO:squash_api.campaigns:Test ajouté à l'itération : test_case_id=649, iteration_item_id=244
INFO:squash_api.campaigns:Automated suite créée : fdc0049a-0974-4a8e-933f-33ce6ec141c5
INFO:squash_api.campaigns:Réponse brute exécution : status_code=200, content=b'{\n  "id" : "fdc0049a-0974-4a8e-933f-33ce6ec141c5",\n  "_type" : "automated-suite",\n  "_links" : {\n    "self" : {\n      "href" : "http://***/squash/api/rest/latest/automated-suites/fdc0049a-0974-4a8e-933f-33ce6ec141c5"\n    },\n    "executions" : {\n      "href" : "http://***/squash/api/rest/latest/automated-suites/fdc0049a-0974-4a8e-933f-33ce6ec141c5/executions"\n    }\n  }\n}'
INFO:squash_api.campaigns:Exécution lancée pour la suite fdc0049a-0974-4a8e-933f-33ce6ec141c5, execution_id=fdc0049a-0974-4a8e-933f-33ce6ec141c5
https://ibb.co/h1V88G8Y

On voit qu'il est pas éxécuter malgrès les logs, je vois pas ou je peux dire que j'utilise l'environnement playwright. Ni ou vérifier si il y a une erreur que je ne voit pas. Ou comment faire autrement pour lancer des suites de tests en différer.

Cordialement Alexandre
alexandreR
Messages : 14
Inscription : lun. avr. 08, 2024 4:30 pm

Re: TNR campaigns via API

Message par alexandreR »

J'ai essayer par une autre méthode est c'est encore pire :

Code : Tout sélectionner

def create_automated_suite2(client: SquashClient, iteration_item_ids: list[str]) -> Optional[str]:
    item_ids_param = ",".join(iteration_item_ids)
    resp = client.post(f"/automated-suite-utils/from-iteration-test-plan-items?itemIds={item_ids_param}")
    status_code = getattr(resp, "status_code", 0)
    if status_code != 201:
        logger.error(f"Automated suite non créée ({status_code}), content={getattr(resp, 'content', None)}")
        return None
    suite_id = resp.json().get("id")
    logger.info(f"Automated suite créée : {suite_id}")
    return suite_id
Avec pour résultat une erreur 500.

Code : Tout sélectionner

[25-11-26 09:40:23.843] SquashTM - 13 ERROR [http-nio-8080-exec-6] [] --- org.squashtest.tm.plugin.rest.core.web.exceptionhandler.RestApiGenericExceptionHandler: resolving exception 'java.lang.IndexOutOfBoundsException' with the catch-all handler
java.lang.IndexOutOfBoundsException: Index 0 out of bounds for length 0
Dans l'execution ou la creation je ne vois pas de paramètre pour précisser l'environemment, ici playwright.
alexandreR
Messages : 14
Inscription : lun. avr. 08, 2024 4:30 pm

Re: TNR campaigns via API

Message par alexandreR »

J'ai essayer "****/squash/api/rest/latest/automated-suite-utils/dfa05a5a-d68c-4f1f-9c72-2954bf1d467e/executor"
Cela me renvoit 200, mais aucun logs dans squash-tm ou orchestrator.

Code : Tout sélectionner

      
{
  "id": "dfa05a5a-d68c-4f1f-9c72-2954bf1d467e",
  "_type": "automated-suite",
  "_links": {
    "self": {
      "href": "***/api/rest/latest/automated-suites/dfa05a5a-d68c-4f1f-9c72-2954bf1d467e"
    },
    "executions": {
      "href": "***/api/rest/latest/automated-suites/dfa05a5a-d68c-4f1f-9c72-2954bf1d467e/executions"
    }
  }
}
Je ne comprend vraiment pas comment du coup faire pour lancer des suites automatisé via l'API. Personne n'a déjà fait ? Pourquoi ce status code a 200, alors qu'il y a clairement une erreur vu rien se passe ?
Personne ne sait ?

Cordialement Alexandre
Répondre

Revenir à « API Rest Test Management »