Skip to content

Commit

Permalink
reorganize all tests in a single top folder (#3981)
Browse files Browse the repository at this point in the history
* lift node version restraint to allow more recent version if already installed

* add node test for latest version

* change python version

* use purple for debug logs

* update workflow

* add playwright dev dependency

* update workflow

* change test

* oops

* improve test

* update test

* fix tests

* mv units tests to a subfolder

* reorganize tests

* fix install

* update test_state

* revert node changes and only keep new tests organization

* move integration tests in tests/integration

* fix integration workflow

* fix dockerfile workflow

* fix dockerfile workflow 2

* fix shared_state
  • Loading branch information
Lendemor authored Sep 25, 2024
1 parent b07fba7 commit 3f53886
Show file tree
Hide file tree
Showing 121 changed files with 306 additions and 96 deletions.
39 changes: 39 additions & 0 deletions .github/workflows/check_node_latest.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: integration-node-latest

on:
push:
branches:
- main
pull_request:
branches:
- main

env:
TELEMETRY_ENABLED: false

jobs:
check_latest_node:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.12']
node-version: ['node']
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup_build_env
with:
python-version: ${{ matrix.python-version }}
run-poetry-install: true
create-venv-at-path: .venv
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- run: |
poetry run uv pip install pyvirtualdisplay pillow
poetry run playwright install --with-deps
- run: |
# poetry run pytest tests/test_node_version.py
poetry run pytest tests/integration


2 changes: 1 addition & 1 deletion .github/workflows/integration_app_harness.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ jobs:
SCREENSHOT_DIR: /tmp/screenshots
REDIS_URL: ${{ matrix.state_manager == 'redis' && 'redis://localhost:6379' || '' }}
run: |
poetry run pytest integration
poetry run pytest tests/integration
- uses: actions/upload-artifact@v4
name: Upload failed test screenshots
if: always()
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/reflex_init_in_docker_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,5 @@ jobs:
# Run reflex init in a docker container
# cwd is repo root
docker build -f integration/init-test/Dockerfile -t reflex-init-test integration/init-test
docker run --rm -v $(pwd):/reflex-repo/ reflex-init-test /reflex-repo/integration/init-test/in_docker_test_script.sh
docker build -f tests/integration/init-test/Dockerfile -t reflex-init-test tests/integration/init-test
docker run --rm -v $(pwd):/reflex-repo/ reflex-init-test /reflex-repo/tests/integration/init-test/in_docker_test_script.sh
6 changes: 3 additions & 3 deletions .github/workflows/unit_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,17 +65,17 @@ jobs:
- name: Run unit tests
run: |
export PYTHONUNBUFFERED=1
poetry run pytest tests --cov --no-cov-on-fail --cov-report=
poetry run pytest tests/units --cov --no-cov-on-fail --cov-report=
- name: Run unit tests w/ redis
if: ${{ matrix.os == 'ubuntu-latest' }}
run: |
export PYTHONUNBUFFERED=1
export REDIS_URL=redis://localhost:6379
poetry run pytest tests --cov --no-cov-on-fail --cov-report=
poetry run pytest tests/units --cov --no-cov-on-fail --cov-report=
# Change to explicitly install v1 when reflex-hosting-cli is compatible with v2
- name: Run unit tests w/ pydantic v1
run: |
export PYTHONUNBUFFERED=1
poetry run uv pip install "pydantic~=1.10"
poetry run pytest tests --cov --no-cov-on-fail --cov-report=
poetry run pytest tests/units --cov --no-cov-on-fail --cov-report=
- run: poetry run coverage html
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ repos:
rev: v0.4.10
hooks:
- id: ruff-format
args: [integration, reflex, tests]
args: [reflex, tests]
- id: ruff
args: ["--fix", "--exit-non-zero-on-fix"]
exclude: '^integration/benchmarks/'
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ In your `reflex` directory run make sure all the unit tests are still passing us
This will fail if code coverage is below 70%.

``` bash
poetry run pytest tests --cov --no-cov-on-fail --cov-report=
poetry run pytest tests/units --cov --no-cov-on-fail --cov-report=
```

Next make sure all the following tests pass. This ensures that every new change has proper documentation and type checking.
Expand Down
239 changes: 164 additions & 75 deletions poetry.lock

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ asynctest = ">=0.13.0,<1.0"
pre-commit = ">=3.2.1"
selenium = ">=4.11.0,<5.0"
pytest-benchmark = ">=4.0.0,<5.0"
playwright = ">=1.46.0"
pytest-playwright = ">=0.5.1"

[tool.poetry.scripts]
reflex = "reflex.reflex:cli"
Expand Down
2 changes: 1 addition & 1 deletion reflex/utils/console.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def debug(msg: str, **kwargs):
kwargs: Keyword arguments to pass to the print function.
"""
if is_debug():
msg_ = f"[blue]Debug: {msg}[/blue]"
msg_ = f"[purple]Debug: {msg}[/purple]"
if progress := kwargs.pop("progress", None):
progress.console.print(msg_, **kwargs)
else:
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ function do_export () {
reflex init --template "$template"
reflex export
(
cd "$SCRIPTPATH/../.."
cd "$SCRIPTPATH/../../.."
scripts/integration.sh ~/"$template" dev
pkill -9 -f 'next-server|python3' || true
sleep 10
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
def SharedStateApp():
"""Test that shared state works as expected."""
import reflex as rx
from integration.shared.state import SharedState
from tests.integration.shared.state import SharedState

class State(SharedState):
pass
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
73 changes: 73 additions & 0 deletions tests/test_node_version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
"""Test for latest node version being able to run reflex."""

from __future__ import annotations

from typing import Any, Generator

import httpx
import pytest
from playwright.sync_api import Page, expect

from reflex.testing import AppHarness


def TestNodeVersionApp():
"""A test app for node latest version."""
import reflex as rx
from reflex.utils.prerequisites import get_node_version

class TestNodeVersionConfig(rx.Config):
pass

class TestNodeVersionState(rx.State):
@rx.var
def node_version(self) -> str:
return str(get_node_version())

app = rx.App()

@app.add_page
def index():
return rx.heading("Node Version check v", TestNodeVersionState.node_version)


@pytest.fixture()
def node_version_app(tmp_path) -> Generator[AppHarness, Any, None]:
"""Fixture to start TestNodeVersionApp app at tmp_path via AppHarness.
Args:
tmp_path: pytest tmp_path fixture
Yields:
running AppHarness instance
"""
with AppHarness.create(
root=tmp_path,
app_source=TestNodeVersionApp, # type: ignore
) as harness:
yield harness


def test_node_version(node_version_app: AppHarness, page: Page):
"""Test for latest node version being able to run reflex.
Args:
node_version_app: running AppHarness instance
page: playwright page instance
"""

def get_latest_node_version():
response = httpx.get("https://nodejs.org/dist/index.json")
versions = response.json()

# Assuming the first entry in the API response is the most recent version
if versions:
latest_version = versions[0]["version"]
return latest_version
return None

assert node_version_app.frontend_url is not None
page.goto(node_version_app.frontend_url)
expect(page.get_by_role("heading")).to_have_text(
f"Node Version check {get_latest_node_version()}"
)
5 changes: 5 additions & 0 deletions tests/units/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
"""Root directory for tests."""

import os

from reflex import constants
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
20 changes: 11 additions & 9 deletions tests/test_state.py β†’ tests/units/test_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
from reflex.utils import format, prerequisites, types
from reflex.utils.format import json_dumps
from reflex.vars.base import ComputedVar, Var
from tests.states.mutation import MutableSQLAModel, MutableTestState
from tests.units.states.mutation import MutableSQLAModel, MutableTestState

from .states import GenState

Expand Down Expand Up @@ -440,26 +440,28 @@ def test_get_substates():

def test_get_name():
"""Test getting the name of a state."""
assert TestState.get_name() == "tests___test_state____test_state"
assert ChildState.get_name() == "tests___test_state____child_state"
assert ChildState2.get_name() == "tests___test_state____child_state2"
assert GrandchildState.get_name() == "tests___test_state____grandchild_state"
assert TestState.get_name() == "tests___units___test_state____test_state"
assert ChildState.get_name() == "tests___units___test_state____child_state"
assert ChildState2.get_name() == "tests___units___test_state____child_state2"
assert (
GrandchildState.get_name() == "tests___units___test_state____grandchild_state"
)


def test_get_full_name():
"""Test getting the full name."""
assert TestState.get_full_name() == "tests___test_state____test_state"
assert TestState.get_full_name() == "tests___units___test_state____test_state"
assert (
ChildState.get_full_name()
== "tests___test_state____test_state.tests___test_state____child_state"
== "tests___units___test_state____test_state.tests___units___test_state____child_state"
)
assert (
ChildState2.get_full_name()
== "tests___test_state____test_state.tests___test_state____child_state2"
== "tests___units___test_state____test_state.tests___units___test_state____child_state2"
)
assert (
GrandchildState.get_full_name()
== "tests___test_state____test_state.tests___test_state____child_state.tests___test_state____grandchild_state"
== "tests___units___test_state____test_state.tests___units___test_state____child_state.tests___units___test_state____grandchild_state"
)


Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from reflex.utils.serializers import serialize_figure
from reflex.vars.base import LiteralVar, Var
from reflex.vars.object import ObjectVar
from tests.test_state import (
from tests.units.test_state import (
ChildState,
ChildState2,
ChildState3,
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

0 comments on commit 3f53886

Please sign in to comment.