Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: test

on:
pull_request:
push:
branches:
- main

jobs:
tests:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.11", "3.12"]
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt -r requirements-dev.txt
playwright install --with-deps
- name: Run unit and integration tests
run: pytest tests/unit tests/integration
- name: Run e2e tests
run: pytest tests/e2e
- name: Upload coverage
uses: actions/upload-artifact@v4
with:
name: coverage-${{ matrix.python-version }}
path: coverage.xml
26 changes: 26 additions & 0 deletions TESTING_GUIDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Testing Guide

This project uses **pytest** for unit and integration tests and **Playwright** for end-to-end tests.

## Setup

1. Install Python dependencies:
```bash
pip install -r requirements.txt -r requirements-dev.txt
playwright install --with-deps
```

## Running Tests

- **Unit & Integration**:
```bash
pytest
```
Coverage is enforced at 80% by default.

- **End-to-End**:
```bash
pytest tests/e2e
```

Playwright will start the local server automatically during the E2E tests.
9 changes: 9 additions & 0 deletions playwright.config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import os
from playwright.sync_api import Playwright

BASE_URL = os.getenv('BASE_URL', 'http://localhost:5000')

# Default configuration for Playwright tests

def pytest_configure(config):
config.base_url = BASE_URL
4 changes: 4 additions & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[pytest]
addopts = --cov=src --cov-report=term-missing --cov-report=xml --cov-fail-under=80
testpaths = tests

4 changes: 4 additions & 0 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
pytest>=8.0,<9.0
pytest-cov>=4.1,<5.0
pytest-playwright>=0.4,<0.5
playwright>=1.40,<2.0
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
numpy==1.24.3
numpy==1.26.4
plotly==5.14.1
flask==2.3.2
gunicorn==22.0.0
Expand Down
Empty file added tests/__init__.py
Empty file.
Empty file added tests/e2e/__init__.py
Empty file.
21 changes: 21 additions & 0 deletions tests/e2e/test_smoke.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import subprocess
import time
import os

import pytest

SERVER_PORT = os.getenv('PORT', '5000')

@pytest.fixture(scope="session", autouse=True)
def server():
proc = subprocess.Popen(["python", "src/app.py"], env={**os.environ, "FLASK_DEBUG": "false"})
time.sleep(3)
yield
proc.terminate()
proc.wait()


@pytest.mark.asyncio
async def test_homepage(page):
await page.goto(f"http://localhost:{SERVER_PORT}/")
assert await page.text_content("body") is not None
Empty file added tests/integration/__init__.py
Empty file.
27 changes: 27 additions & 0 deletions tests/integration/test_routes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from src.app import app


def test_compute_topological_compatibility_route():
client = app.test_client()
payload = {
'skb1': {
'tx': 0.1,
'ty': 0.1,
'tz': 0.1,
'tt': 0.1,
'orientable': 1,
'genus': 0
},
'skb2': {
'tx': -0.1,
'ty': -0.1,
'tz': -0.1,
'tt': -0.1,
'orientable': 1,
'genus': 0
}
}
response = client.post('/compute_topological_compatibility', json=payload)
assert response.status_code == 200
data = response.get_json()
assert 'compatible' in data
Empty file added tests/unit/__init__.py
Empty file.
34 changes: 34 additions & 0 deletions tests/unit/test_app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import numpy as np
from src import app as app_module


def test_generate_twisted_strip_shape():
twists = [1, 1, 1, 0]
x, y, z, u, v = app_module.generate_twisted_strip(twists, t=0.0, loop_factor=1)
assert x.shape == (50, 50)
assert y.shape == (50, 50)
assert z.shape == (50, 50)
assert u.shape == (50, 50)
assert v.shape == (50, 50)


def test_compute_topological_compatibility_returns_dict():
skb1 = {
'tx': 0.1,
'ty': 0.1,
'tz': 0.1,
'tt': 0.1,
'orientable': 1,
'genus': 0
}
skb2 = {
'tx': -0.1,
'ty': -0.1,
'tz': -0.1,
'tt': -0.1,
'orientable': 1,
'genus': 0
}
result = app_module.compute_topological_compatibility(skb1=skb1, skb2=skb2)
assert isinstance(result, dict)
assert 'compatible' in result
Loading