Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integration tests #31

Merged
merged 23 commits into from
Nov 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
39d5ba0
:umbrella: Add integration tests.
vanyle Nov 14, 2021
111b251
:umbrella: Changed the CI to ubuntu in an attempt to be able to use t…
vanyle Nov 14, 2021
9cf2b68
:umbrella: Added DISPLAY to the environment variables
vanyle Nov 14, 2021
57d41f6
:umbrella: Change location where integration tests are performed
vanyle Nov 14, 2021
5c46430
:umbrella: Attempt to make x11 work on CI
vanyle Nov 14, 2021
d1aac7d
:umbrella: Update dependencies for CI and make the test linux friendly.
vanyle Nov 14, 2021
5fba40c
:umbrella: Attempt to fix CI errors
vanyle Nov 14, 2021
3b567c6
:umbrella: Next attempt
vanyle Nov 14, 2021
fbdc5a1
:umbrella: Made stuff root
vanyle Nov 14, 2021
4244304
:umbrella: Use `sudo` instead of `su`, because the commands are not r…
vanyle Nov 15, 2021
d7f330a
:beetle: Add sudo at the correct places
vanyle Nov 15, 2021
225b986
:umbrella: Attempt to fix CI. Fixed a bug in the tests where the posi…
vanyle Nov 15, 2021
74e969e
:umbrella: Proper integration with qtbot. qtbot manages the app part.
vanyle Nov 15, 2021
17eb81c
:umbrella: Added -s option to pytest to display prints inside tests
vanyle Nov 15, 2021
90f32b3
:umbrella: rewrite the CI
vanyle Nov 15, 2021
6794f26
:umbrella: Created file with touch to resolve FileNotFound
vanyle Nov 15, 2021
190c706
:umbrella: Add integration test for opening files
vanyle Nov 15, 2021
35ca8e6
:umbrella: Made CI output less noisy
vanyle Nov 15, 2021
6dd3ed6
:umbrella: Fix an issue where the test would crash on windows
vanyle Nov 15, 2021
d756df4
:umbrella: Add integration test support for the `tests` CI. Comment k…
vanyle Nov 16, 2021
64373ee
:umbrella: A linter has no place in a testing CI. This is the job of …
vanyle Nov 16, 2021
44c1121
:umbrella: Set the DISPLAY of the test to xvfb
vanyle Nov 16, 2021
52dd36a
:umbrella: Add end-of-line at the end of the file
vanyle Nov 16, 2021
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
17 changes: 14 additions & 3 deletions .github/workflows/python-coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,18 @@ jobs:
python-version: 3.9
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install python3-tk python3-dev
sudo apt-get install xvfb
sudo apt install libxkbcommon-x11-0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-xfixes0

python -m pip install --upgrade pip
pip install -r requirements.txt
pip install -r requirements-dev.txt
touch /home/runner/.Xauthority

- name: Build unit coverage using pytest-cov
run: |
pip install -r requirements-dev.txt
pytest --cov=opencodeblocks --cov-report=xml tests/unit
score=$(python coverage_score.py --score)
color=$(python coverage_score.py --color)
Expand All @@ -40,14 +47,18 @@ jobs:
style: plastic
- name: Build integration coverage using pytest-cov
run: |
pip install -r requirements-dev.txt
pytest --cov=opencodeblocks --cov-report=xml tests/integration
/sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -screen 0 1920x1080x24 -ac +extension GLX

pytest -s --cov=opencodeblocks --cov-report=xml tests/integration
score=$(python coverage_score.py --score)
color=$(python coverage_score.py --color)
echo "COVERAGE_INTEGRATION_SCORE=$score"
echo "COVERAGE_INTEGRATION_COLOR=$color"
echo "COVERAGE_INTEGRATION_SCORE=$score" >> $GITHUB_ENV
echo "COVERAGE_INTEGRATION_COLOR=$color" >> $GITHUB_ENV
env:
DISPLAY: :99
# QT_DEBUG_PLUGINS: 1 # Uncomment to debug Qt library issues.
- name: Create integration coverage badge
uses: schneegans/[email protected]
with:
Expand Down
20 changes: 11 additions & 9 deletions .github/workflows/python-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ on: ["push"]
jobs:
build:

runs-on: windows-latest
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.7, 3.8, 3.9]
Expand All @@ -21,16 +21,18 @@ jobs:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install python3-tk python3-dev
sudo apt-get install xvfb
sudo apt install libxkbcommon-x11-0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-xfixes0

python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Lint with flake8
run: |
pip install flake8
# 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
pip install -r requirements-dev.txt
touch /home/runner/.Xauthority
- name: Test with pytest
run: |
pip install -r requirements-dev.txt
/sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -screen 0 1920x1080x24 -ac +extension GLX
pytest tests
env:
DISPLAY: :99
1 change: 1 addition & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
filterwarnings =
ignore::DeprecationWarning
addopts = --pspec
qt_api=pyqt5
2 changes: 2 additions & 0 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,7 @@ pytest-cov
pytest-mock
pytest-check
pytest-pspec
pytest-qt
pyautogui
pylint
pylint-pytest
171 changes: 171 additions & 0 deletions tests/integration/test_blocks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
"""
Integration tests for OCB.

We use xvfb to perform the tests without opening any windows.
We use pyautogui to move the mouse and interact with the application.

To pass the tests on windows, you need to not move the mouse.
Use this if you need to understand why a test fails.

To pass the tests on linux, you just need to install xvfb and it's dependencies.
On linux, no windows are opened to the user during the test.
To understand why a test fails, pass the flag "--no-xvfb" and use your own X server
to see the test running live.
"""

# Imports needed for testing
import time, threading, queue, os, sys
import pytest
from pytest_mock import MockerFixture
import pytest_check as check
import pyautogui

# Packages tested
from opencodeblocks.graphics.blocks.codeblock import OCBCodeBlock
from opencodeblocks.graphics.socket import OCBSocket
from opencodeblocks.graphics.window import OCBWindow
from opencodeblocks.graphics.widget import OCBWidget

from qtpy.QtWidgets import QApplication
from PyQt5.QtWidgets import QWidget
from PyQt5.QtGui import QFocusEvent, QMouseEvent
from PyQt5.QtCore import QCoreApplication, QEvent, Qt, QPointF, QPoint
from PyQt5 import QtTest

def test_window_opening(qtbot):
""" The OCBWindow should open and close correctly """
wnd = OCBWindow()
wnd.close()

"""
def test_running_python(qtbot):
# The blocks should run arbitrary python when unfocused
wnd = OCBWindow()

EXPRESSION = "3 + 5 * 2"
SOURCE_TEST = \
'''
print(%s)
''' % EXPRESSION
expected_result = str(eval(EXPRESSION))

# Let's add a block with the source to the window !
ocb_widget = OCBWidget()
test_block = OCBCodeBlock(title="Testing block", source=SOURCE_TEST)
ocb_widget.scene.addItem(test_block)
wnd.mdiArea.addSubWindow(ocb_widget)

# Let's run the block !
pyeditor = test_block.source_editor.widget()
# pyeditor.setModified(True)
# test_block._source = ""
QApplication.processEvents()
QtTest.QTest.mouseClick(pyeditor,Qt.MouseButton.LeftButton)
QApplication.processEvents()
QtTest.QTest.keyPress(pyeditor," ")
QApplication.processEvents()

# Click outside the block to lose focus of the previous block.
# This will need to be changed by the click to the run button.
QtTest.QTest.mouseClick(ocb_widget,Qt.MouseButton.LeftButton)
QApplication.processEvents()

# When the execution becomes non-blocking for the UI, a refactor will be needed here.
result = test_block.stdout.strip()

check.equal(expected_result,result)
wnd.close()
"""

def test_move_blocks(qtbot):
"""
Newly created blocks are displayed in the center.
They can be dragged around with the mouse.
"""
wnd = OCBWindow()

ocb_widget = OCBWidget()
subwnd = wnd.mdiArea.addSubWindow(ocb_widget)

test_block1 = OCBCodeBlock(title="Testing block 1", source="print(1)")
ocb_widget.scene.addItem(test_block1)

test_block2 = OCBCodeBlock(title="Testing block 2", source="print(2)")
ocb_widget.scene.addItem(test_block2)

subwnd.show()

QApplication.processEvents()

expected_move_amount = [70,-30]
STOP_MSG = "stop"
CHECK_MSG = "check"

msgQueue = queue.Queue()

def testing_drag(msgQueue):
time.sleep(.4) # Wait for proper setup of app

# test_block1 == (0,0) but it's not crucial for this test.
pos_block_1 = QPoint(int(test_block1.pos().x()),int(test_block1.pos().y()))

pos_block_1.setX(pos_block_1.x() + test_block1.title_height//2)
pos_block_1.setY(pos_block_1.y() + test_block1.title_height//2)

pos_block_1 = ocb_widget.view.mapFromScene(pos_block_1)
pos_block_1 = ocb_widget.view.mapToGlobal(pos_block_1)

pyautogui.moveTo(pos_block_1.x(),pos_block_1.y())
pyautogui.mouseDown(button="left")

iterations = 5
for i in range(iterations+1):
time.sleep(0.05)
pyautogui.moveTo(
pos_block_1.x() + expected_move_amount[0] * i // iterations,
pos_block_1.y() + expected_move_amount[1] * i // iterations
)

pyautogui.mouseUp(button="left")
time.sleep(.2)

move_amount = [test_block2.pos().x(),test_block2.pos().y()]
# rectify because the scene can be zoomed :
move_amount[0] = int(move_amount[0] * ocb_widget.view.zoom)
move_amount[1] = int(move_amount[1] * ocb_widget.view.zoom)

msgQueue.put([
CHECK_MSG,
move_amount,
expected_move_amount,
"Block moved by the correct amound"
])

msgQueue.put([STOP_MSG])


t = threading.Thread(target=testing_drag, args=(msgQueue,))
t.start()

while True:
QApplication.processEvents()
time.sleep(0.02)
if not msgQueue.empty():
msg = msgQueue.get()
if msg[0] == STOP_MSG:
break
elif msg[0] == CHECK_MSG:
check.equal(msg[1],msg[2],msg[3])
t.join()
wnd.close()

def test_open_file():
"""
The application loads files properly.
"""

wnd = OCBWindow()
file_example_path = "./tests/testing_assets/example_graph1.ipyg"
subwnd = wnd.createNewMdiChild(os.path.abspath(file_example_path))
subwnd.show()
wnd.close()
Loading