testing.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. # -*- coding: utf-8 -*-
  2. # SPDX-License-Identifier: AGPL-3.0-or-later
  3. # lint: pylint
  4. """Shared testing code."""
  5. # pylint: disable=missing-function-docstring
  6. import os
  7. import subprocess
  8. import traceback
  9. from os.path import dirname, join, abspath, realpath
  10. from splinter import Browser
  11. import aiounittest
  12. class SearxTestLayer:
  13. """Base layer for non-robot tests."""
  14. __name__ = 'SearxTestLayer'
  15. @classmethod
  16. def setUp(cls):
  17. pass
  18. @classmethod
  19. def tearDown(cls):
  20. pass
  21. @classmethod
  22. def testSetUp(cls):
  23. pass
  24. @classmethod
  25. def testTearDown(cls):
  26. pass
  27. class SearxRobotLayer():
  28. """Searx Robot Test Layer"""
  29. def setUp(self):
  30. os.setpgrp() # create new process group, become its leader
  31. # get program paths
  32. webapp = join(abspath(dirname(realpath(__file__))), 'webapp.py')
  33. exe = 'python'
  34. # The Flask app is started by Flask.run(...), don't enable Flask's debug
  35. # mode, the debugger from Flask will cause wired process model, where
  36. # the server never dies. Further read:
  37. #
  38. # - debug mode: https://flask.palletsprojects.com/quickstart/#debug-mode
  39. # - Flask.run(..): https://flask.palletsprojects.com/api/#flask.Flask.run
  40. os.environ['SEARX_DEBUG'] = '0'
  41. # set robot settings path
  42. os.environ['SEARX_SETTINGS_PATH'] = abspath(
  43. dirname(__file__) + '/settings_robot.yml')
  44. # run the server
  45. self.server = subprocess.Popen( # pylint: disable=consider-using-with
  46. [exe, webapp],
  47. stdout=subprocess.PIPE,
  48. stderr=subprocess.STDOUT
  49. )
  50. if hasattr(self.server.stdout, 'read1'):
  51. print(self.server.stdout.read1(1024).decode())
  52. def tearDown(self):
  53. os.kill(self.server.pid, 9)
  54. # remove previously set environment variable
  55. del os.environ['SEARX_SETTINGS_PATH']
  56. # SEARXROBOTLAYER = SearxRobotLayer()
  57. def run_robot_tests(tests):
  58. print('Running {0} tests'.format(len(tests)))
  59. for test in tests:
  60. with Browser('firefox', headless=True, profile_preferences={'intl.accept_languages': 'en'}) as browser:
  61. test(browser)
  62. class SearxTestCase(aiounittest.AsyncTestCase):
  63. """Base test case for non-robot tests."""
  64. layer = SearxTestLayer
  65. def setattr4test(self, obj, attr, value):
  66. """
  67. setattr(obj, attr, value)
  68. but reset to the previous value in the cleanup.
  69. """
  70. previous_value = getattr(obj, attr)
  71. def cleanup_patch():
  72. setattr(obj, attr, previous_value)
  73. self.addCleanup(cleanup_patch)
  74. setattr(obj, attr, value)
  75. if __name__ == '__main__':
  76. import sys
  77. # test cases
  78. from tests import robot
  79. base_dir = abspath(join(dirname(__file__), '../tests'))
  80. if sys.argv[1] == 'robot':
  81. test_layer = SearxRobotLayer()
  82. errors = False
  83. try:
  84. test_layer.setUp()
  85. run_robot_tests([getattr(robot, x) for x in dir(robot) if x.startswith('test_')])
  86. except Exception: # pylint: disable=broad-except
  87. errors = True
  88. print('Error occured: {0}'.format(traceback.format_exc()))
  89. test_layer.tearDown()
  90. sys.exit(1 if errors else 0)