Skip to content

Implement integration tests for the project Core #50

@hadamrd

Description

@hadamrd

Motivation

We need to integrate test scripts into our project to enable more systematic and organized testing. Setting this up initially will take some time, but it will prove extremely beneficial for our ongoing development process.

The plan is to store the credentials for a bot account in GitHub Secrets. This might involve a JWT that includes the character profile, API key, and a certificate for a standard bot account.

We will then implement specialized test classes derived from pyd2bot. These classes will use the account to perform automated actions such as random movements, map changes, a set number of combats, traversing from Incarnam to Astrub, auto-traveling on long journeys, and saving Zaap locations.

Additionally, we'll configure a GitHub workflow to execute these tests on a runner hosted by OVH, which will run the latest version of Dofus. The smallest VM option available at OVH should suffice, which will incur a minimal cost per month.

Proposed structure for our test code:

# File: tests/test_integration.py
import json
import os
import uuid
from pyd2bot.Pyd2Bot import Pyd2Bot
from pyd2bot.data.models import Session, Character, Credentials, Path
import pydantic

class Secret(pydantic.Basemodel):
    character: Character
    credentials: Credentials

class BotFightTester(Pyd2Bot):
    
    def __init__(self, decoded_git_secret: Secret, test_path, monster_lvl_coef_diff: float, fights_per_minute: float, test_session_timeout: int = 30):
        session = Session({
            "id": uuid.uuid4(),
            "character": decoded_git_secret.character,
            "type": "SOLO_FIGHT",
            "credentials": decoded_git_secret.credentials,
            "unloadType": "BANK",
            "path": test_path,
            "monsterLvlCoefDiff": monster_lvl_coef_diff,
            "fightsPerMinute": fights_per_minute,
            "sessionTimeout": test_session_timeout,
        })
        super().__init__(session)

    def startSessionMainBehavior(self):
        BotFightBehavior(self.session).start(self.onMainBehaviorFinish)

def test_fight():
    bot_creds = os.getenv("BOT_CREDENTIALS")
    fightsPerMinute = os.getenv("FIGHTS_PER_MINUTE")
    monsterLvlCoefDiff = os.getenv("MONSTER_LVL_COEF_DIFF")
    testPath = Path(**json.loads(os.getenv("TEST_PATH")))
    testDuration = os.getenv("TEST_DURATION")
    decoded_git_secret = Secret(**json.loads(bot_creds))
    bot_tester = BotFightTester(decoded_git_secret, testPath, monsterLvlCoefDiff, fightsPerMinute, testDuration)
    test_result = True
    fail_error = None
    def onShutdown(reason, message):
        nonlocal test_result
        nonlocal fail_error
        if reason != "WANTED_SHUTDOWN":
            test_result = False
    bot_tester.addShutDownListener(onShutdown)
    bot_tester.start()
    bot_tester.join()
    assert test_result, fail_error

Example of the github workflow

name: Integration Tests for bots

on:
  push:
    branches: [ main, feature/* ]
  pull_request:
    branches: [ main ]

jobs:
  test:
    runs-on: [self-hosted, ovh, windows, 10, fordofus] # Specifies the runner labels
    steps:
    - uses: actions/checkout@v2
      with:
        repository: 'hadamrd/pyd2bot'
        path: 'botdev/pyd2bot'

    - name: Set up Python environment
      run: |
        python -m venv ./botdev/.venv
        source ./botdev/.venv/Scripts/activate
        pip install --upgrade pip
        pip install -r ./botdev/pyd2bot/requirements.txt

    - name: Run integration tests
      env:
        BOT_CREDENTIALS: ${{ secrets.BOT_CREDENTIALS }}
        FIGHTS_PER_MINUTE: 1
        MONSTER_LVL_COEF_DIFF: 3
        TEST_PATH: '{"id": "test_path", "type": "CustomrRandomPath", "mapIds": [xxxx1, xxxx2, ....]}'
        TEST_DURATION: 30
      run: |
        cd botdev/pyd2bot/test_integration
        python main.py

Important

We need to make sure that the version of pyd2bot we are working on, which originates from the commit triggering the workflow, is > a long-term support (LTS) version. To achieve this, we add the following line to the pyd2bot requirements.txt file:
git+https://github.com/hadamrd/pydofus2.git@develop#egg=pydofus2

One good option for a runner vm

AWS Free Tier: This includes 750 hours per month of a t2.micro instance for free for the first 12 months of a new AWS account. This is suitable for small-scale, low-traffic applications or basic testing./

Metadata

Metadata

Assignees

No one assigned

    Labels

    backendbackend featureenhancementNew feature or requesthelp wantedExtra attention is needed

    Projects

    Status

    Ready

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions