util.py 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. import asyncio
  2. import signal
  3. import subprocess
  4. import sys
  5. import threading
  6. from functools import partial
  7. from urllib.parse import urlparse
  8. from selenium import webdriver
  9. from pywebio import STATIC_PATH
  10. from pywebio.utils import wait_host_port
  11. default_chrome_options = webdriver.ChromeOptions()
  12. default_chrome_options.add_argument('--no-sandbox')
  13. default_chrome_options.add_argument('--disable-extensions')
  14. default_chrome_options.add_argument('--disable-dev-shm-usage')
  15. default_chrome_options.add_argument('--disable-setuid-sandbox')
  16. USAGE = """
  17. python {name}
  18. 启动PyWebIO服务器
  19. python {name} auto
  20. 使用无头浏览器进行自动化测试,并使用coverage检测代码覆盖率
  21. python {name} debug
  22. 使用带界面的浏览器自动化测试
  23. """
  24. def run_test(server_func, test_func, address='http://localhost:8080?_pywebio_debug=1', chrome_options=None):
  25. """
  26. :param server_func: 启动PyWebIO服务器的函数
  27. :param test_func: 测试的函数。人工测试时不会被运行 (server_proc, browser)
  28. :param port: 启动的PyWebIO服务器的端口
  29. """
  30. if len(sys.argv) not in (1, 2) or (len(sys.argv) == 2 and sys.argv[-1] not in ('server', 'auto', 'debug')):
  31. print(USAGE.format(name=sys.argv[0]))
  32. return
  33. if len(sys.argv) != 2: # when execute test script with no argument, only start server
  34. try:
  35. server_func()
  36. except KeyboardInterrupt:
  37. pass
  38. sys.exit()
  39. if chrome_options is None:
  40. chrome_options = default_chrome_options
  41. if sys.argv[-1] == 'auto':
  42. default_chrome_options.add_argument('--headless')
  43. proc = subprocess.Popen(['coverage', 'run', '--source', 'pywebio', '--append',
  44. sys.argv[0]], stdout=sys.stdout, stderr=subprocess.STDOUT, text=True)
  45. elif sys.argv[-1] == 'debug':
  46. # start server as sub process
  47. proc = subprocess.Popen(['python3', sys.argv[0]], stdout=sys.stdout, stderr=subprocess.STDOUT, text=True)
  48. browser = None
  49. try:
  50. browser = webdriver.Chrome(chrome_options=chrome_options)
  51. browser.set_window_size(1000, 900)
  52. port_str = urlparse(address).netloc.split(':', 1)[-1] or '80'
  53. asyncio.run(wait_host_port('localhost', int(port_str)))
  54. browser.get(address)
  55. browser.implicitly_wait(10)
  56. test_func(proc, browser)
  57. finally:
  58. if browser:
  59. if sys.argv[-1] == 'debug':
  60. input('press ENTER to exit')
  61. browser.quit()
  62. # 不要使用 proc.terminate() ,因为coverage会无法保存分析数据
  63. proc.send_signal(signal.SIGINT)
  64. print("Closed browser and PyWebIO server")