testing.py 3.1 KB

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