Commit 71557c7a authored by Nicolas Gelot's avatar Nicolas Gelot
Browse files

Rework tests

The infra to run selenium these tests was too complex, and the test are
not updated since 2016. This patch removes the dependencies of
these tests and it adds `pytest` as runner for the unit tests.
parent 54760155
FROM fedora
COPY requirements.txt requirements-dev.txt /
RUN dnf install -y\
wget\
python2-pip\
npm\
&& dnf groupinstall -y "Development Tools" \
&& pip3 install pytest ipdb ipython
&& pip3 install ipdb ipython \
&& pip3 install -r /requirements.txt \
&& pip3 install -r /requirements-dev.txt \
&& rm -f /requirements.txt /requirements-dev.txt
......@@ -26,46 +26,6 @@ update_dev_packages() {
pip3 install -r "$BASE_DIR/requirements-dev.txt"
}
install_geckodriver() {
echo '[!] Checking geckodriver'
# TODO : check the current geckodriver version
set -e
geckodriver -V > /dev/null 2>&1 || NOTFOUND=1
set +e
if [ -z "$NOTFOUND" ]; then
return
fi
GECKODRIVER_VERSION="v0.19.1"
PLATFORM="`python3 -c "import platform; print(platform.system().lower(), platform.architecture()[0])"`"
case "$PLATFORM" in
"linux 32bit" | "linux2 32bit") ARCH="linux32";;
"linux 64bit" | "linux2 64bit") ARCH="linux64";;
"windows 32 bit") ARCH="win32";;
"windows 64 bit") ARCH="win64";;
"mac 64bit") ARCH="macos";;
esac
GECKODRIVER_URL="https://github.com/mozilla/geckodriver/releases/download/$GECKODRIVER_VERSION/geckodriver-$GECKODRIVER_VERSION-$ARCH.tar.gz";
if [ -z "$1" ]; then
if [ -z "$VIRTUAL_ENV" ]; then
printf "geckodriver can't be installed because VIRTUAL_ENV is not set, you should download it from\n %s" "$GECKODRIVER_URL"
exit
else
GECKODRIVER_DIR="$VIRTUAL_ENV/bin"
fi
else
GECKODRIVER_DIR="$1"
mkdir -p -- "$GECKODRIVER_DIR"
fi
printf "Installing %s/geckodriver from\n %s" "$GECKODRIVER_DIR" "$GECKODRIVER_URL"
FILE="`mktemp`"
wget -qO "$FILE" -- "$GECKODRIVER_URL" && tar xz -C "$GECKODRIVER_DIR" -f "$FILE" geckodriver
rm -- "$FILE"
chmod 777 -- "$GECKODRIVER_DIR/geckodriver"
}
locales() {
pybabel compile -d "$SEARX_DIR/translations"
}
......@@ -80,7 +40,7 @@ pep8_check() {
unit_tests() {
echo '[!] Running unit tests'
python3 -m nose2 -s "$BASE_DIR/tests/unit"
PYTHONPATH="$BASE_DIR" pytest --disable-pytest-warnings "$BASE_DIR/tests/unit"
}
py_test_coverage() {
......@@ -90,17 +50,10 @@ py_test_coverage() {
&& coverage html
}
robot_tests() {
echo '[!] Running robot tests'
PYTHONPATH="`pwd`" python3 "$SEARX_DIR/testing.py" robot
}
tests() {
set -e
pep8_check
unit_tests
install_geckodriver
robot_tests
set +e
}
......
babel==2.3.4
mock==2.0.0
nose2[coverage-plugin]
cov-core==1.15.0
pep8==1.7.0
plone.testing==5.0.0
splinter==0.7.5
transifex-client==0.12.2
unittest2==1.1.0
zope.testrunner==4.5.1
selenium==3.5.0
mockredispy==2.9.3
pytest==4.1.0
general:
debug : False
instance_name : "searx_test"
search:
safe_search : 0
autocomplete : ""
language: "en-US"
server:
port : 11111
bind_address : 127.0.0.1
secret_key : "ultrasecretkey" # change this!
base_url : False
image_proxy : False
http_protocol_version : "1.0"
ui:
static_path : ""
templates_path : ""
default_theme : oscar
default_locale : ""
outgoing:
request_timeout : 1.0 # seconds
useragent_suffix : ""
engines:
- name : general dummy
engine : dummy
categories : general
shortcut : gd
- name : dummy dummy
engine : dummy
categories : dummy
shortcut : dd
locales:
en : English
hu : Magyar
# -*- coding: utf-8 -*-
"""Shared testing code."""
import os
import subprocess
import traceback
from os.path import dirname, join, abspath
from splinter import Browser
from unittest2 import TestCase
class SearxTestLayer:
"""Base layer for non-robot tests."""
__name__ = 'SearxTestLayer'
def setUp(cls):
pass
setUp = classmethod(setUp)
def tearDown(cls):
pass
tearDown = classmethod(tearDown)
def testSetUp(cls):
pass
testSetUp = classmethod(testSetUp)
def testTearDown(cls):
pass
testTearDown = classmethod(testTearDown)
class SearxRobotLayer():
"""Searx Robot Test Layer"""
def setUp(self):
os.setpgrp() # create new process group, become its leader
# get program paths
webapp = os.path.join(
os.path.abspath(os.path.dirname(os.path.realpath(__file__))),
'webapp.py'
)
exe = 'python'
# set robot settings path
os.environ['SEARX_SETTINGS_PATH'] = abspath(
dirname(__file__) + '/settings_robot.yml')
# run the server
self.server = subprocess.Popen(
[exe, webapp],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT
)
def tearDown(self):
os.kill(self.server.pid, 9)
# remove previously set environment variable
del os.environ['SEARX_SETTINGS_PATH']
# SEARXROBOTLAYER = SearxRobotLayer()
def run_robot_tests(tests):
print('Running {0} tests'.format(len(tests)))
for test in tests:
with Browser() as browser:
test(browser)
class SearxTestCase(TestCase):
"""Base test case for non-robot tests."""
layer = SearxTestLayer
if __name__ == '__main__':
import sys
# test cases
from tests import robot
base_dir = abspath(join(dirname(__file__), '../tests'))
if sys.argv[1] == 'robot':
test_layer = SearxRobotLayer()
errors = False
try:
test_layer.setUp()
run_robot_tests([getattr(robot, x) for x in dir(robot) if x.startswith('test_')])
except Exception:
errors = True
print('Error occured: {0}'.format(traceback.format_exc()))
test_layer.tearDown()
sys.exit(1 if errors else 0)
# -*- coding: utf-8 -*-
from time import sleep
url = "http://localhost:11111/"
def test_index(browser):
# Visit URL
browser.visit(url)
assert browser.is_text_present('about')
def test_404(browser):
# Visit URL
browser.visit(url + 'missing_link')
assert browser.is_text_present('Page not found')
def test_about(browser):
browser.visit(url)
browser.click_link_by_text('about')
assert browser.is_text_present('Why use searx?')
def test_preferences(browser):
browser.visit(url)
browser.click_link_by_text('preferences')
assert browser.is_text_present('Preferences')
assert browser.is_text_present('Cookies')
assert browser.is_element_present_by_xpath('//label[@for="checkbox_dummy"]')
def test_preferences_engine_select(browser):
browser.visit(url)
browser.click_link_by_text('preferences')
assert browser.is_element_present_by_xpath('//a[@href="#tab_engine"]')
browser.find_by_xpath('//a[@href="#tab_engine"]').first.click()
assert not browser.find_by_xpath('//input[@id="engine_general_dummy__general"]').first.checked
browser.find_by_xpath('//label[@for="engine_general_dummy__general"]').first.check()
browser.find_by_xpath('//input[@value="save"]').first.click()
# waiting for the redirect - without this the test is flaky..
sleep(1)
browser.visit(url)
browser.click_link_by_text('preferences')
browser.find_by_xpath('//a[@href="#tab_engine"]').first.click()
assert browser.find_by_xpath('//input[@id="engine_general_dummy__general"]').first.checked
def test_preferences_locale(browser):
browser.visit(url)
browser.click_link_by_text('preferences')
browser.select('locale', 'hu')
browser.find_by_xpath('//input[@value="save"]').first.click()
# waiting for the redirect - without this the test is flaky..
sleep(1)
browser.visit(url)
browser.click_link_by_text('beállítások')
browser.is_text_present('Beállítások')
def test_search(browser):
browser.visit(url)
browser.fill('q', 'test search query')
browser.find_by_xpath('//button[@type="submit"]').first.click()
assert browser.is_text_present('didn\'t find any results')
# -*- coding: utf-8 -*-
import os
import unittest2 as unittest
from plone.testing import layered
from robotsuite import RobotTestSuite
from searx.testing import SEARXROBOTLAYER
def test_suite():
suite = unittest.TestSuite()
current_dir = os.path.abspath(os.path.dirname(__file__))
robot_dir = os.path.join(current_dir, 'robot')
tests = [
os.path.join('robot', f) for f in
os.listdir(robot_dir) if f.endswith('.robot') and
f.startswith('test_')
]
for test in tests:
suite.addTests([
layered(RobotTestSuite(test), layer=SEARXROBOTLAYER),
])
return suite
......@@ -2,10 +2,10 @@
from collections import defaultdict
import mock
from searx.engines import pubmed
from searx.testing import SearxTestCase
from unittest import TestCase
class TestPubmedEngine(SearxTestCase):
class TestPubmedEngine(TestCase):
def test_request(self):
query = 'test_query'
......
......@@ -2,10 +2,10 @@
from collections import defaultdict
import mock
from searx.engines import acgsou
from searx.testing import SearxTestCase
from unittest import TestCase
class TestAcgsouEngine(SearxTestCase):
class TestAcgsouEngine(TestCase):
def test_request(self):
query = 'test_query'
......
from collections import defaultdict
import mock
from searx.engines import archlinux
from searx.testing import SearxTestCase
from unittest import TestCase
domains = {
'en': 'https://wiki.archlinux.org',
......@@ -13,7 +13,7 @@ domains = {
}
class TestArchLinuxEngine(SearxTestCase):
class TestArchLinuxEngine(TestCase):
def test_request(self):
query = 'test_query'
......
......@@ -2,10 +2,10 @@
from collections import defaultdict
import mock
from searx.engines import arxiv
from searx.testing import SearxTestCase
from unittest import TestCase
class TestBaseEngine(SearxTestCase):
class TestBaseEngine(TestCase):
def test_request(self):
query = 'test_query'
......
......@@ -2,10 +2,10 @@
from collections import defaultdict
import mock
from searx.engines import base
from searx.testing import SearxTestCase
from unittest import TestCase
class TestBaseEngine(SearxTestCase):
class TestBaseEngine(TestCase):
def test_request(self):
query = 'test_query'
......
from collections import defaultdict
import mock
from searx.engines import bing
from searx.testing import SearxTestCase
from unittest import TestCase
class TestBingEngine(SearxTestCase):
class TestBingEngine(TestCase):
def test_request(self):
bing.supported_languages = ['en', 'fr', 'zh-CHS', 'zh-CHT', 'pt-PT', 'pt-BR']
......
......@@ -2,10 +2,10 @@
from collections import defaultdict
import mock
from searx.engines import bing_images
from searx.testing import SearxTestCase
from unittest import TestCase
class TestBingImagesEngine(SearxTestCase):
class TestBingImagesEngine(TestCase):
def test_request(self):
bing_images.supported_languages = ['fr-FR', 'en-US']
......
from collections import defaultdict
import mock
from searx.engines import bing_news
from searx.testing import SearxTestCase
from unittest import TestCase
import lxml
class TestBingNewsEngine(SearxTestCase):
class TestBingNewsEngine(TestCase):
def test_request(self):
bing_news.supported_languages = ['en', 'fr']
......
......@@ -2,10 +2,10 @@
from collections import defaultdict
import mock
from searx.engines import bing_videos
from searx.testing import SearxTestCase
from unittest import TestCase
class TestBingVideosEngine(SearxTestCase):
class TestBingVideosEngine(TestCase):
def test_request(self):
bing_videos.supported_languages = ['fr-FR', 'en-US']
......
......@@ -2,10 +2,10 @@
from collections import defaultdict
import mock
from searx.engines import btdigg
from searx.testing import SearxTestCase
from unittest import TestCase
class TestBtdiggEngine(SearxTestCase):
class TestBtdiggEngine(TestCase):
def test_request(self):
query = 'test_query'
......
......@@ -2,10 +2,10 @@ from collections import defaultdict
from datetime import datetime
import mock
from searx.engines import currency_convert
from searx.testing import SearxTestCase
from unittest import TestCase
class TestCurrencyConvertEngine(SearxTestCase):
class TestCurrencyConvertEngine(TestCase):
def test_request(self):
query = 'test_query'
......
......@@ -2,10 +2,10 @@
from collections import defaultdict
import mock
from searx.engines import dailymotion
from searx.testing import SearxTestCase
from unittest import TestCase
class TestDailymotionEngine(SearxTestCase):
class TestDailymotionEngine(TestCase):
def test_request(self):
dailymotion.supported_languages = ['en', 'fr']
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment