util.py 2.6 KB

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