-
Notifications
You must be signed in to change notification settings - Fork 108
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #12 from ch-sa/pytest
Add integration tests
- Loading branch information
Showing
11 changed files
with
261 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
name: Integration Tests | ||
on: [push, pull_request] | ||
|
||
jobs: | ||
|
||
testing: | ||
runs-on: ${{ matrix.os }} | ||
strategy: | ||
matrix: | ||
os: [ubuntu-latest] | ||
python-version: [3.6, 3.7, 3.8] | ||
env: | ||
DISPLAY: ':99.0' | ||
|
||
steps: | ||
- name: Get repository | ||
uses: actions/checkout@v2 | ||
|
||
- name: Set up Python ${{ matrix.python-version }} | ||
uses: actions/setup-python@v2 | ||
with: | ||
python-version: ${{ matrix.python-version }} | ||
|
||
- name: setup ${{ matrix.os }} | ||
run: | | ||
sudo apt install libxkbcommon-x11-0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-xfixes0 | ||
/sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -screen 0 1920x1200x24 -ac +extension GLX | ||
- name: Install freeglut | ||
run: | | ||
sudo apt-get install freeglut3 freeglut3-dev | ||
- name: Install dependencies | ||
run: | | ||
python -m pip install --upgrade pip | ||
pip install flake8 pytest | ||
pip install -r requirements.txt | ||
- name: Test with pytest | ||
run: | | ||
python -m pytest tests/integration/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,40 +1,37 @@ | ||
# This workflow will install Python dependencies, run tests and lint with a single version of Python | ||
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions | ||
|
||
name: Tests | ||
|
||
on: | ||
push: | ||
branches: [ main ] | ||
pull_request: | ||
branches: [ main ] | ||
name: Unit Tests | ||
on: [push, pull_request] | ||
|
||
jobs: | ||
build: | ||
|
||
testing: | ||
runs-on: ${{ matrix.os }} | ||
strategy: | ||
matrix: | ||
os: [ubuntu-latest, macos-latest, windows-latest] | ||
python-version: [3.6, 3.7, 3.8] | ||
|
||
steps: | ||
- uses: actions/checkout@v2 | ||
- name: Get repository | ||
uses: actions/checkout@v2 | ||
|
||
- name: Set up Python 3.8 | ||
uses: actions/setup-python@v2 | ||
with: | ||
python-version: ${{ matrix.python-version }} | ||
|
||
- name: Install dependencies | ||
run: | | ||
python -m pip install --upgrade pip | ||
pip install flake8 pytest | ||
pip install -r requirements.txt | ||
- name: Lint with flake8 | ||
run: | | ||
# stop the build if there are Python syntax errors or undefined names | ||
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics | ||
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide | ||
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics | ||
- name: Test with pytest | ||
run: | | ||
python -m pytest tests/ | ||
python -m pytest tests/unit/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,4 +2,5 @@ numpy~=1.19.4 | |
PyQt5~=5.15.2 | ||
PyOpenGL~=3.1.5 | ||
open3d~=0.11.2 | ||
pytest~=6.2.2 | ||
pytest~=6.2.2 | ||
pytest-qt~=4.0.1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import os | ||
import sys | ||
|
||
import pytest | ||
|
||
|
||
def pytest_configure(config): | ||
os.chdir("../labelCloud") | ||
print(f"Set working directory to {os.getcwd()}.") | ||
|
||
sys.path.insert(0, "labelCloud") | ||
print(f"Added labelCloud to Python path.") | ||
|
||
import app # preventing circular import | ||
|
||
|
||
@pytest.fixture | ||
def startup_pyqt(qtbot, qapp): | ||
from control.controller import Controller | ||
from view.gui import GUI | ||
|
||
# Setup Model-View-Control structure | ||
control = Controller() | ||
view = GUI(control) | ||
qtbot.addWidget(view) | ||
qtbot.addWidget(view.glWidget) | ||
|
||
# Install event filter to catch user interventions | ||
qapp.installEventFilter(view) | ||
|
||
# Start GUI | ||
view.show() | ||
return view, control | ||
|
||
|
||
@pytest.fixture | ||
def bbox(): | ||
from model.bbox import BBox | ||
return BBox(cx=0, cy=0, cz=0, length=3, width=2, height=1) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
import os | ||
from PyQt5 import QtCore | ||
from PyQt5.QtWidgets import QAbstractSlider | ||
|
||
from control.config_manager import config | ||
|
||
|
||
def test_gui(qtbot, startup_pyqt): | ||
view, controller = startup_pyqt | ||
|
||
assert len(controller.pcd_manager.pcds) > 0 | ||
os.remove("labels/exemplary.json") | ||
assert len(os.listdir("labels")) == 0 | ||
qtbot.mouseClick(view.button_next_pcd, QtCore.Qt.LeftButton, delay=0) | ||
assert len(os.listdir("labels")) == 1 | ||
|
||
bbox = controller.bbox_controller.bboxes[0] | ||
bbox.center = (0, 0, 0) | ||
controller.bbox_controller.set_active_bbox(0) | ||
qtbot.mouseClick(view.button_right, QtCore.Qt.LeftButton, delay=0) | ||
qtbot.mouseClick(view.button_up, QtCore.Qt.LeftButton, delay=0) | ||
qtbot.mouseClick(view.button_backward, QtCore.Qt.LeftButton, delay=0) | ||
assert bbox.center == (0.03, 0.03, 0.03) | ||
|
||
view.close() | ||
|
||
|
||
def test_bbox_control_with_buttons(qtbot, startup_pyqt, bbox): | ||
view, controller = startup_pyqt | ||
|
||
# Prepare test bounding box | ||
controller.bbox_controller.bboxes = [bbox] | ||
old_length, old_width, old_height = bbox.get_dimensions() | ||
controller.bbox_controller.set_active_bbox(0) | ||
|
||
# Translation | ||
translation_step = config.getfloat("LABEL", "std_translation") | ||
qtbot.mouseClick(view.button_right, QtCore.Qt.LeftButton, delay=0) | ||
qtbot.mouseClick(view.button_up, QtCore.Qt.LeftButton, delay=0) | ||
qtbot.mouseClick(view.button_backward, QtCore.Qt.LeftButton, delay=0) | ||
assert bbox.center == (translation_step, translation_step, translation_step) | ||
qtbot.mouseClick(view.button_left, QtCore.Qt.LeftButton, delay=0) | ||
qtbot.mouseClick(view.button_down, QtCore.Qt.LeftButton, delay=0) | ||
qtbot.mouseClick(view.button_forward, QtCore.Qt.LeftButton) | ||
print("BBOX: %s" % [str(c) for c in bbox.get_center()]) | ||
assert bbox.center == (0.00, 0.00, 0.00) | ||
|
||
# Scaling | ||
scaling_step = config.getfloat("LABEL", "std_scaling") | ||
qtbot.mouseClick(view.button_incr_dim, QtCore.Qt.LeftButton) | ||
assert bbox.length == old_length + scaling_step | ||
assert bbox.width == old_width / old_length * bbox.length | ||
assert bbox.height == old_height / old_length * bbox.length | ||
|
||
# Rotation | ||
# TODO: Make dial configureable? | ||
view.dial_zrotation.triggerAction(QAbstractSlider.SliderSingleStepAdd) | ||
assert bbox.z_rotation == 1 | ||
view.dial_zrotation.triggerAction(QAbstractSlider.SliderPageStepAdd) | ||
assert bbox.z_rotation == 11 | ||
|
||
view.close() | ||
|
||
|
||
def test_bbox_control_with_keyboard(qtbot, startup_pyqt, qapp, bbox): | ||
view, controller = startup_pyqt | ||
|
||
# Prepare test bounding box | ||
controller.bbox_controller.bboxes = [bbox] | ||
controller.bbox_controller.set_active_bbox(0) | ||
|
||
# Translation | ||
translation_step = config.getfloat("LABEL", "std_translation") | ||
for letter in "dqw": | ||
qtbot.keyClick(view, letter) | ||
assert bbox.center == (translation_step, translation_step, translation_step) | ||
translation_step = config.getfloat("LABEL", "std_translation") | ||
for letter in "aes": | ||
qtbot.keyClick(view, letter) | ||
assert bbox.center == (0, 0, 0) | ||
|
||
for key in [QtCore.Qt.Key_Right, QtCore.Qt.Key_Up, QtCore.Qt.Key_PageUp]: | ||
qtbot.keyClick(view, key) | ||
assert bbox.center == (translation_step, translation_step, translation_step) | ||
for key in [QtCore.Qt.Key_Left, QtCore.Qt.Key_Down, QtCore.Qt.Key_PageDown]: | ||
qtbot.keyClick(view, key) | ||
assert bbox.center == (0, 0, 0) | ||
|
||
# Rotation | ||
rotation_step = config.getfloat("LABEL", "std_rotation") | ||
config.set("USER_INTERFACE", "z_rotation_only", "False") | ||
qtbot.keyClick(view, "y") | ||
assert bbox.z_rotation == rotation_step | ||
qtbot.keyClick(view, "x") | ||
assert bbox.z_rotation == 0 | ||
qtbot.keyClick(view, QtCore.Qt.Key_Comma) | ||
assert bbox.z_rotation == rotation_step | ||
qtbot.keyClick(view, QtCore.Qt.Key_Period) | ||
assert bbox.z_rotation == 0 | ||
qtbot.keyClick(view, "c") | ||
assert bbox.y_rotation == rotation_step | ||
qtbot.keyClick(view, "v") | ||
assert bbox.y_rotation == 0 | ||
qtbot.keyClick(view, "b") | ||
assert bbox.x_rotation == rotation_step | ||
qtbot.keyClick(view, "n") | ||
assert bbox.x_rotation == 0 | ||
|
||
# Shortcuts | ||
qtbot.keyClick(view, QtCore.Qt.Key_Delete) | ||
assert len(controller.bbox_controller.bboxes) == 0 | ||
assert controller.bbox_controller.get_active_bbox() is None | ||
|
||
view.close() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import pytest | ||
from PyQt5 import QtCore | ||
from PyQt5.QtCore import QPoint | ||
|
||
from control.config_manager import config | ||
from model.bbox import BBox | ||
|
||
|
||
def test_picking_mode(qtbot, startup_pyqt): | ||
view, control = startup_pyqt | ||
control.bbox_controller.bboxes = [] | ||
|
||
qtbot.mouseClick(view.button_activate_picking, QtCore.Qt.LeftButton, delay=1000) | ||
qtbot.mouseClick(view.glWidget, QtCore.Qt.LeftButton, pos=QPoint(500, 500), delay=1000) | ||
|
||
assert len(control.bbox_controller.bboxes) == 1 | ||
new_bbox = control.bbox_controller.bboxes[0] | ||
assert new_bbox.center == tuple(pytest.approx(x, 0.01) for x in [-0.2479, -0.2245, 0.0447]) | ||
|
||
assert new_bbox.length == config.getfloat("LABEL", "std_boundingbox_length") | ||
assert new_bbox.width == config.getfloat("LABEL", "std_boundingbox_width") | ||
assert new_bbox.height == config.getfloat("LABEL", "std_boundingbox_height") | ||
assert new_bbox.z_rotation == new_bbox.y_rotation == new_bbox.x_rotation == 0 | ||
|
||
|
||
def test_spanning_mode(qtbot, startup_pyqt): | ||
view, control = startup_pyqt | ||
control.bbox_controller.bboxes = [] | ||
config.set("USER_INTERFACE", "z_rotation_only", "True") | ||
|
||
qtbot.mouseClick(view.button_activate_spanning, QtCore.Qt.LeftButton, delay=10) | ||
qtbot.mouseClick(view.glWidget, QtCore.Qt.LeftButton, pos=QPoint(431, 475), delay=20) | ||
qtbot.mouseClick(view.glWidget, QtCore.Qt.LeftButton, pos=QPoint(506, 367), delay=20) | ||
qtbot.mouseClick(view.glWidget, QtCore.Qt.LeftButton, pos=QPoint(572, 439), delay=20) | ||
qtbot.mouseClick(view.glWidget, QtCore.Qt.LeftButton, pos=QPoint(607, 556), delay=20) | ||
|
||
assert len(control.bbox_controller.bboxes) == 1 | ||
new_bbox: BBox = control.bbox_controller.bboxes[0] | ||
assert new_bbox.center == tuple(pytest.approx(x, 0.01) for x in [-0.2100, -0.2348, 0.0568]) | ||
assert new_bbox.get_dimensions() == tuple(pytest.approx(x, 0.01) for x in [0.7344, 0.5305, 0.1212]) | ||
assert new_bbox.get_rotations() == tuple(pytest.approx(x % 360, 0.5) for x in [0, 0, 55.2205]) |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import os | ||
import sys | ||
|
||
|
||
def pytest_configure(config): | ||
os.chdir("../labelCloud") | ||
print(f"Set working directory to {os.getcwd()}.") | ||
|
||
sys.path.insert(0, "labelCloud") | ||
print(f"Added labelCloud to Python path.") | ||
|
||
import app # preventing circular import |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,6 @@ | ||
import os | ||
|
||
import pytest | ||
import preparation | ||
from control.label_manager import LabelManager | ||
|
||
|
||
|